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>