kubernetes(13):k8s数据持久化-pv和pvc—NFS实现
k8s数据持久化-pv和pvc—NFS实现
https://www.cnblogs.com/zhenyuyaodidiao/p/6500720.html
https://www.cnblogs.com/benjamin77/p/9944268.html#auto_id_2
1 Volume
在Docker的设计实现中,容器中的数据是临时的,即当容器被销毁时,其中的数据将会丢失。如果需要持久化数据,需要使用Docker数据卷挂载宿主机上的文件或者目录到容器中。在Kubernetes中,当Pod重建的时候,数据是会丢失的,Kubernetes也是通过数据卷挂载来提供Pod数据的持久化的。Kubernetes数据卷是对Docker数据卷的扩展,Kubernetes数据卷是Pod级别的,可以用来实现Pod中容器的文件共享。目前,Kubernetes支持的数据卷类型如下:
1) EmptyDir
2) HostPath
3) GCE Persistent Disk
4) AWS Elastic Block Store
5) NFS
6) iSCSI
7) Flocker
8) GlusterFS
9) RBD
10) Git Repo
11) Secret
12) Persistent Volume Claim
13) Downward API
1.1 本地数据卷
EmptyDir、HostPath这两种类型的数据卷,只能最用于本地文件系统。本地数据卷中的数据只会存在于一台机器上,所以当Pod发生迁移的时候,数据便会丢失。该类型Volume的用途是:Pod中容器间的文件共享、共享宿主机的文件系统。
1.1.1 EmptyDir
如果Pod配置了EmpyDir数据卷,在Pod的生命周期内都会存在,当Pod被分配到 Node上的时候,会在Node上创建EmptyDir数据卷,并挂载到Pod的容器中。只要Pod 存在,EmpyDir数据卷都会存在(容器删除不会导致EmpyDir数据卷丟失数据),但是如果Pod的生命周期终结(Pod被删除),EmpyDir数据卷也会被删除,并且永久丢失。
EmpyDir数据卷非常适合实现Pod中容器的文件共享。Pod的设计提供了一个很好的容器组合的模型,容器之间各司其职,通过共享文件目录来完成交互,比如可以通过一个专职日志收集容器,在每个Pod中和业务容器中进行组合,来完成日志的收集和汇总。
1.1.2 HostPath
HostPath数据卷允许将容器宿主机上的文件系统挂载到Pod中。如果Pod需要使用宿主机上的某些文件,可以使用HostPath。
1.2 网络共享数据卷
Kubernetes提供了很多类型的数据卷以集成第三方的存储系统,包括一些非常流行的分布式文件系统,也有在IaaS平台上提供的存储支持,这些存储系统都是分布式的,通过网络共享文件系统,因此我们称这一类数据卷为网络数据卷。
网络数据卷能够满足数据的持久化需求,Pod通过配置使用网络数据卷,每次Pod创建的时候都会将存储系统的远端文件目录挂载到容器中,数据卷中的数据将被水久保存,即使Pod被删除,只是除去挂载数据卷,数据卷中的数据仍然保存在存储系统中,且当新的Pod被创建的时候,仍是挂载同样的数据卷。网络数据卷包含以下几种:NFS、iSCISI、GlusterFS、RBD(Ceph Block Device)、Flocker、AWS Elastic Block Store、GCE Persistent Disk
1.3 PV(Persistent Volume)和PVC(Persistent Volume Claim)
PV—资源池—NFS等
PVC—分享给谁用
理解每个存储系统是一件复杂的事情,特别是对于普通用户来说,有时候并不需要关心各种存储实现,只希望能够安全可靠地存储数据。Kubernetes中提供了Persistent Volume和Persistent Volume Claim机制,这是存储消费模式。Persistent Volume是由系统管理员配置创建的一个数据卷(目前支持HostPath、GCE Persistent Disk、AWS Elastic Block Store、NFS、iSCSI、GlusterFS、RBD),它代表了某一类存储插件实现;而对于普通用户来说,通过Persistent Volume Claim可请求并获得合适的Persistent Volume,而无须感知后端的存储实现。Persistent Volume和Persistent Volume Claim的关系其实类似于Pod和Node,Pod消费Node资源,Persistent Volume Claim则消费Persistent Volume资源。Persistent Volume和Persistent Volume Claim相互关联,有着完整的生命周期管理:
1) 准备:系统管理员规划或创建一批Persistent Volume;
2) 绑定:用户通过创建Persistent Volume Claim来声明存储请求,Kubernetes发现有存储请求的时候,就去查找符合条件的Persistent Volume(最小满足策略)。找到合适的就绑定上,找不到就一直处于等待状态;
3) 使用:创建Pod的时候使用Persistent Volume Claim;
4) 释放:当用户删除绑定在Persistent Volume上的Persistent Volume Claim时,Persistent Volume进入释放状态,此时Persistent Volume中还残留着上一个Persistent Volume Claim的数据,状态还不可用;
5) 回收:是否的Persistent Volume需要回收才能再次使用。回收策略可以是人工的也可以是Kubernetes自动进行清理(仅支持NFS和HostPath)
PersistentVolume (PV) 是外部存储系统中的一块存储空间,由管理员创建和维护。与 Volume 一样,PV 具有持久性,生命周期独立于 Pod。
PersistentVolumeClaim (PVC) 是对 PV 的申请 (Claim)。PVC 通常由普通用户创建和维护。需要为 Pod 分配存储资源时,用户可以创建一个 PVC,指明存储资源的容量大小和访问模式(比如只读)等信息,Kubernetes 会查找并提供满足条件的 PV。
有了 PersistentVolumeClaim,用户只需要告诉 Kubernetes 需要什么样的存储资源,而不必关心真正的空间从哪里分配,如何访问等底层细节信息。这些 Storage Provider 的底层信息交给管理员来处理,只有管理员才应该关心创建 PersistentVolume 的细节信息。
1.4 信息数据卷
Kubernetes中有一些数据卷,主要用来给容器传递配置信息,我们称之为信息数据卷,比如Secret(处理敏感配置信息,密码、Token等)、Downward API(通过环境变量的方式告诉容器Pod的信息)、Git Repo(将Git仓库下载到Pod中),都是将Pod的信息以文件形式保存,然后以数据卷方式挂载到容器中,容器通过读取文件获取相应的信息。
2 通过NFS实现持久化存储
https://www.cnblogs.com/benjamin77/p/9944268.html#auto_id_1
2.1 配置nfs
k8s-master nfs-server
k8s-node1 k8s-node2 nfs-client
2.2 安装nfs-master
yum install -y nfs-utils
2.3 在master节点创建共享目录
mkdir -p /data/tomcat
2.4 编辑/etc/exports配置文件
cat /etc/exports /data 192.168.0.0/24(rw,no_root_squash,no_all_squash,sync)
2.5 启动nfs-server服务
systemctl start rpcbind
systemctl start nfs
2.6 在nodes安装nfs客户端
yum install -y nfs-utils
2.7 创建PV-持久卷
apiVersion: v1 kind: PersistentVolume #资源类型 metadata: name: mysql-tomcat labels: type: mysql-tomcat-nfs spec: capacity: storage: 5Gi accessModes: - ReadWriteMany #访问模式,多个客户端读写 persistentVolumeReclaimPolicy: Recycle #回收策略-可以回收 nfs: path: "/nfsdata" server: 10.6.76.25 #k8s-nfs matser readOnly: false #只读
[root@k8s-master k8s]# kubectl create -f pv_nfs.yaml persistentvolume " mysql-tomcat" created
2.8 查看PV信息
[root@k8s-master k8s]# kubectl get pv NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM REASON AGE mysql-tomcat 5Gi RWX Recycle Bound default/mysql-tomcat-pvc 5m [root@k8s-master k8s]# kubectl describe pv mysql-tomcat Name: mysql-tomcat Labels: type=mysql-tomcat-nfs StorageClass: Status: Bound Claim: default/mysql-tomcat-pvc Reclaim Policy: Recycle Access Modes: RWX Capacity: 5Gi Message: Source: Type: NFS (an NFS mount that lasts the lifetime of a pod) Server: 10.6.76.25 Path: /nfsdata ReadOnly: false No events.
2.9 创建PVC-持久卷消费者
# cat pvc_nfs.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-tomcat-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi
2.10PVC自动绑定PV
没有强制绑定-空闲自动绑定
[root@k8s-master k8s]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESSMODES AGE mysql-tomcat-pvc Bound mysql-tomcat 5Gi RWX 6m [root@k8s-master k8s]# kubectl get pv NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM REASON AGE mysql-tomcat 5Gi RWX Recycle Bound default/mysql-tomcat-pvc 6m [root@k8s-master k8s]#
2.11重新加载MySQL-deployment.yaml
[root@k8s-master k8s]# cat mysql-deploy.yaml apiVersion: extensions/v1beta1 kind: Deployment #副本控制器Deployment metadata: name: mysql #Deployment的名称,全局唯一 spec: replicas: 1 #Pod副本的期待数量 template: #根据此模版创建Pod的副本(实例) metadata: labels: app: mysql #Pod副本拥有的标签,对应Deployment的selector spec: containers: #Pod内,定义容器 - name: mysql #容器名称 image: 192.168.0.136:5000/mysql:5.7 #Docker image ports: - containerPort: 3306 #容器应用监听的端口 volumeMounts: - name: mysql-data-pvc #和下面一致 mountPath: /var/lib/mysql env: #注入容器内的环境变量 - name: MYSQL_ROOT_PASSWORD #这里设置root初始密码 value: "123456" volumes: # - name: mysql-data-pvc #pvc名字 persistentVolumeClaim: claimName: mysql-tomcat-pvc
[root@k8s-master k8s]# kubectl apply -f mysql-deploy.yaml deployment "mysql" configured [root@k8s-master k8s]#
2.12检查持久化同步数据
[root@k8s-master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE mysql-1415028949-3d366 1/1 Running 0 16h 172.16.5.3 k8s-node-1 tomcat-app-3309240903-2bm2r 1/1 Running 0 17h 172.16.5.2 k8s-node-1 tomcat-app-3309240903-5qgw1 1/1 Running 0 17h 172.16.96.2 k8s-node-2
NFS同步数据
[root@k8s-master k8s]# kubectl exec -it mysql-1415028949-wdhzf /bin/bash root@mysql-1415028949-wdhzf:/# root@mysql-1415028949-wdhzf:/# root@mysql-1415028949-wdhzf:/# cd /var/lib/mysql root@mysql-1415028949-wdhzf:/var/lib/mysql# ls auto.cnf ca.pem client-key.pem ib_logfile0 ibdata1 mysql private_key.pem server-cert.pem sys ca-key.pem client-cert.pem ib_buffer_pool ib_logfile1 ibtmp1 performance_schema public_key.pem server-key.pem root@mysql-1415028949-wdhzf:/var/lib/mysql# [root@k8s-master nfsdata]# pwd /nfsdata [root@k8s-master nfsdata]# ls auto.cnf ca.pem client-key.pem ibdata1 ib_logfile1 mysql private_key.pem server-cert.pem sys ca-key.pem client-cert.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-key.pem [root@k8s-master nfsdata]#
新建一个数据库
[root@k8s-master k8s]# mysql -uroot -p123456 -h172.16.5.3 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6 Server version: 5.7.27 MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> mysql> mysql> mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | +--------------------+ 4 rows in set (10.87 sec) mysql> create database www; Query OK, 1 row affected (2.41 sec) mysql>
删除pod,自动新建pod,再次查看数据
[root@k8s-master k8s]# kubectl delete pod mysql-1415028949-3d366 pod "mysql-1415028949-3d366" deleted [root@k8s-master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE mysql-1415028949-0z3tt 0/1 Pending 0 30s <none> k8s-node-2 mysql-1415028949-3d366 1/1 Terminating 0 17h 172.16.5.3 k8s-node-1 tomcat-app-3309240903-2bm2r 1/1 Running 0 17h 172.16.5.2 k8s-node-1 tomcat-app-3309240903-5qgw1 1/1 Running 0 17h 172.16.96.2 k8s-node-2 [root@k8s-master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE mysql-1415028949-0z3tt 1/1 Running 0 2m 172.16.96.3 k8s-node-2 tomcat-app-3309240903-2bm2r 1/1 Running 0 17h 172.16.5.2 k8s-node-1 tomcat-app-3309240903-5qgw1 1/1 Running 0 17h 172.16.96.2 k8s-node-2 [root@k8s-master k8s]# mysql -uroot -p123456 -h172.16.96.3 -P3306 mysql: [Warning] Using a password on the command line interface can be insecure. Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.7.27 MySQL Community Server (GPL) Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sys | | www | +--------------------+ 5 rows in set (0.17 sec) mysql>
2.13web+mysql样例测试
https://www.cnblogs.com/wangxu01/articles/11411113.html
我们把MySQL持久化测试一下
[root@k8s-master k8s]# cat tomcat-app-deployment.yaml apiVersion: extensions/v1beta1 kind: Deployment metadata: name: tomcat-app spec: replicas: 3 template: metadata: labels: app: tomcat-app spec: containers: - name: tomcat-app image: 192.168.0.136:5000/tomcat-app:v1 ports: - containerPort: 8080 env: - name: MYSQL_SERVICE_HOST value: '172.16.96.3' - name: MYSQL_SERVICE_PORT value: '3306' [root@k8s-master k8s]# cat tomcat-app-svc.yaml apiVersion: v1 kind: Service metadata: name: tomcat-app spec: type: NodePort ports: - port: 8080 name: myweb-svc nodePort: 30002 selector: app: tomcat-app [root@k8s-master k8s]# [root@k8s-master k8s]# cat mysql-deploy.yaml apiVersion: extensions/v1beta1 kind: Deployment #副本控制器Deployment metadata: name: mysql #Deployment的名称,全局唯一 spec: replicas: 1 #Pod副本的期待数量 template: #根据此模版创建Pod的副本(实例) metadata: labels: app: mysql #Pod副本拥有的标签,对应Deployment的selector spec: containers: #Pod内,定义容器 - name: mysql #容器名称 image: 192.168.0.136:5000/mysql:5.7 #Docker image ports: - containerPort: 3306 #容器应用监听的端口 volumeMounts: - name: mysql-data-pvc mountPath: /var/lib/mysql env: #注入容器内的环境变量 - name: MYSQL_ROOT_PASSWORD #这里设置root初始密码 value: "123456" volumes: # - name: mysql-data-pvc #pvc名字 persistentVolumeClaim: claimName: mysql-tomcat-pvc [root@k8s-master k8s]# cat mysql-svc.yaml apiVersion: v1 kind: Service metadata: name: mysql spec: type: NodePort ports: - port: 3306 nodePort: 30001 selector: app: mysql [root@k8s-master k8s]# [root@k8s-master k8s]# cat pv_nfs.yaml apiVersion: v1 kind: PersistentVolume #资源类型 metadata: name: mysql-tomcat labels: type: mysql-tomcat-nfs spec: capacity: storage: 5Gi accessModes: - ReadWriteMany #访问模式,多个客户端读写 persistentVolumeReclaimPolicy: Recycle #回收策略-可以回收 nfs: path: "/nfsdata" server: 192.168.0.136 #k8s-nfs matser readOnly: false #只读 [root@k8s-master k8s]# cat pvc_nfs.yaml apiVersion: v1 kind: PersistentVolumeClaim metadata: name: mysql-tomcat-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 1Gi [root@k8s-master k8s]#
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | HPE_APP | | mysql | | performance_schema | | sys | | www | +--------------------+ 6 rows in set (0.01 sec) mysql> use HPE_APP Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> show tables; +-------------------+ | Tables_in_HPE_APP | +-------------------+ | T_USERS | +-------------------+ 1 row in set (0.05 sec) mysql> select * from T_USERS; +----+-----------+-------+ | ID | USER_NAME | LEVEL | +----+-----------+-------+ | 1 | me | 100 | | 2 | our team | 100 | | 3 | HPE | 100 | | 4 | teacher | 100 | | 5 | docker | 100 | | 6 | google | 100 | | 7 | PV | 8888 | +----+-----------+-------+ 7 rows in set (0.00 sec) mysql>
我们把MySQL pod删除,让它重新构建
[root@k8s-master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE mysql-1415028949-0z3tt 1/1 Running 0 50m 172.16.96.3 k8s-node-2 tomcat-app-4111270462-j9cc3 1/1 Running 0 42m 172.16.5.4 k8s-node-1 tomcat-app-4111270462-mpc0r 1/1 Running 0 41m 172.16.96.5 k8s-node-2 tomcat-app-4111270462-tjgtc 1/1 Running 0 42m 172.16.96.4 k8s-node-2 [root@k8s-master k8s]# kubectl delete pod mysql-1415028949-0z3tt pod "mysql-1415028949-0z3tt" deleted [root@k8s-master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE mysql-1415028949-3n47s 0/1 ContainerCreating 0 52s <none> k8s-node-1 tomcat-app-4111270462-j9cc3 1/1 Running 0 44m 172.16.5.4 k8s-node-1 tomcat-app-4111270462-mpc0r 1/1 Running 0 43m 172.16.96.5 k8s-node-2 tomcat-app-4111270462-tjgtc 1/1 Running 0 44m 172.16.96.4 k8s-node-2 [root@k8s-master k8s]# kubectl get pod -o wide NAME READY STATUS RESTARTS AGE IP NODE mysql-1415028949-3n47s 1/1 Running 0 2m 172.16.5.2 k8s-node-1 tomcat-app-4111270462-j9cc3 1/1 Running 0 46m 172.16.5.4 k8s-node-1 tomcat-app-4111270462-mpc0r 1/1 Running 0 45m 172.16.96.5 k8s-node-2 tomcat-app-4111270462-tjgtc 1/1 Running 0 46m 172.16.96.4 k8s-node-2 [root@k8s-master k8s]# mysql -uroot -p123456 -h172.16.5.2 -P3306 …… mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | HPE_APP | | mysql | | performance_schema | | sys | | www | +--------------------+ 6 rows in set (0.00 sec) mysql> use HPE_APP Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> select * from T_USERS; +----+-----------+-------+ | ID | USER_NAME | LEVEL | +----+-----------+-------+ | 1 | me | 100 | | 2 | our team | 100 | | 3 | HPE | 100 | | 4 | teacher | 100 | | 5 | docker | 100 | | 6 | google | 100 | | 7 | PV | 8888 | +----+-----------+-------+ 7 rows in set (0.04 sec) mysql>