k8s的持久化存儲PV&&PVC

1.PV和PVC的引入

Volume 提供了很是好的數據持久化方案,不過在可管理性上還有不足。node

拿前面 AWS EBS 的例子來講,要使用 Volume,Pod 必須事先知道以下信息:mysql

  1. 當前 Volume 來自 AWS EBS。sql

  2. EBS Volume 已經提早建立,而且知道確切的 volume-id。數據庫

Pod 一般是由應用的開發人員維護,而 Volume 則一般是由存儲系統的管理員維護。開發人員要得到上面的信息:安全

  1. 要麼詢問管理員。服務器

  2. 要麼本身就是管理員。app

這樣就帶來一個管理上的問題:應用開發人員和系統管理員的職責耦合在一塊兒了。若是系統規模較小或者對於開發環境這樣的狀況還能夠接受。但當集羣規模變大,特別是對於生成環境,考慮到效率和安全性,這就成了必需要解決的問題。ide

Kubernetes 給出的解決方案是 PersistentVolume 和 PersistentVolumeClaim。學習

PersistentVolume (PV) 是外部存儲系統中的一塊存儲空間,由管理員建立和維護。與 Volume 同樣,PV 具備持久性,生命週期獨立於 Pod。spa

PersistentVolumeClaim (PVC) 是對 PV 的申請 (Claim)。PVC 一般由普通用戶建立和維護。須要爲 Pod 分配存儲資源時,用戶能夠建立一個 PVC,指明存儲資源的容量大小和訪問模式(好比只讀)等信息,Kubernetes 會查找並提供知足條件的 PV。

有了 PersistentVolumeClaim,用戶只須要告訴 Kubernetes 須要什麼樣的存儲資源,而沒必要關心真正的空間從哪裏分配,如何訪問等底層細節信息。這些 Storage Provider 的底層信息交給管理員來處理,只有管理員才應該關心建立 PersistentVolume 的細節信息。

 

2.經過NFS實現持久化存儲

2.1配置nfs

k8s-master  nfs-server

k8s-node1  k8s-node2 nfs-client

全部節點安裝nfs

yum install -y nfs-common nfs-utils 

在master節點建立共享目錄

[root@k8s-master k8s]# mkdir /nfsdata

受權共享目錄

[root@k8s-master k8s]# chmod 666 /nfsdata

編輯exports文件

[root@k8s-master k8s]# cat /etc/exports
/nfsdata *(rw,no_root_squash,no_all_squash,sync)

配置生效

  [root@k8s-master k8s]# export -r

啓動rpc和nfs(注意順序)

[root@k8s-master k8s]# systemctl start rpcbind
[root@k8s-master k8s]# systemctl start nfs

做爲準備工做,咱們已經在 k8s-master 節點上搭建了一個 NFS 服務器,目錄爲 /nfsdata

2.2建立PV

下面建立一個 PV mypv1,配置文件 nfs-pv1.yml 以下:

① capacity 指定 PV 的容量爲 1G。

② accessModes 指定訪問模式爲 ReadWriteOnce,支持的訪問模式有:
ReadWriteOnce – PV 能以 read-write 模式 mount 到單個節點。
ReadOnlyMany – PV 能以 read-only 模式 mount 到多個節點。
ReadWriteMany – PV 能以 read-write 模式 mount 到多個節點。

③ persistentVolumeReclaimPolicy 指定當 PV 的回收策略爲 Recycle,支持的策略有:
Retain – 須要管理員手工回收。
Recycle – 清除 PV 中的數據,效果至關於執行 rm -rf /thevolume/*
Delete – 刪除 Storage Provider 上的對應存儲資源,例如 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

④ storageClassName 指定 PV 的 class 爲 nfs。至關於爲 PV 設置了一個分類,PVC 能夠指定 class 申請相應 class 的 PV。

⑤ 指定 PV 在 NFS 服務器上對應的目錄。

建立 mypv1

STATUS 爲 Available,表示 mypv1 就緒,能夠被 PVC 申請。

 

2.3建立PVC

接下來建立 PVC mypvc1,配置文件 nfs-pvc1.yml 以下:

PVC 就很簡單了,只須要指定 PV 的容量,訪問模式和 class。

執行命令建立 mypvc1

從 kubectl get pvc 和 kubectl get pv 的輸出能夠看到 mypvc1 已經 Bound 到 mypv1,申請成功。

2.4建立pod

上面已經建立好了pv和pvc,pod中直接使用這個pvc便可

與使用普通 Volume 的格式相似,在 volumes 中經過 persistentVolumeClaim 指定使用 mypvc1 申請的 Volume。

 經過命令建立mypod1

2.5驗證

可見,在 Pod 中建立的文件 /mydata/hello 確實已經保存到了 NFS 服務器目錄 /nfsdata中。

若是再也不須要使用 PV,可用刪除 PVC 回收 PV。

3.PV的回收

當 PV 再也不須要時,可經過刪除 PVC 回收。

未刪除pvc以前  pv的狀態是Bound

刪除pvc以後pv的狀態變爲Available,,此時解除綁定後則能夠被新的 PVC 申請。

/nfsdata文件中的文件被刪除了

 

由於 PV 的回收策略設置爲 Recycle,因此數據會被清除,但這可能不是咱們想要的結果。若是咱們但願保留數據,能夠將策略設置爲 Retain

經過 kubectl apply 更新 PV:

 

回收策略已經變爲 Retain,經過下面步驟驗證其效果:

 

① 從新建立 mypvc1

② 在 mypv1 中建立文件 hello

③ mypv1 狀態變爲 Released

④ PV 中的數據被完整保留。

雖然 mypv1 中的數據獲得了保留,但其 PV 狀態會一直處於 Released,不能被其餘 PVC 申請。爲了從新使用存儲資源,能夠刪除並從新建立 mypv1。刪除操做只是刪除了 PV 對象,存儲空間中的數據並不會被刪除。

 

新建的 mypv1 狀態爲 Available,已經能夠被 PVC 申請。

PV 還支持 Delete 的回收策略,會刪除 PV 在 Storage Provider 上對應存儲空間。NFS 的 PV 不支持 Delete,支持 Delete 的 Provider 有 AWS EBS、GCE PD、Azure Disk、OpenStack Cinder Volume 等。

4.PV的動態供給

前面的例子中,咱們提早建立了 PV,而後經過 PVC 申請 PV 並在 Pod 中使用,這種方式叫作靜態供給(Static Provision)。

與之對應的是動態供給(Dynamical Provision),即若是沒有知足 PVC 條件的 PV,會動態建立 PV。相比靜態供給,動態供給有明顯的優點:不須要提早建立 PV,減小了管理員的工做量,效率高。

動態供給是經過 StorageClass 實現的,StorageClass 定義瞭如何建立 PV,下面是兩個例子。

StorageClass standard

StorageClass slow

這兩個 StorageClass 都會動態建立 AWS EBS,不一樣在於 standard 建立的是 gp2 類型的 EBS,而 slow 建立的是 io1 類型的 EBS。不一樣類型的 EBS 支持的參數可參考 AWS 官方文檔。

StorageClass 支持 Delete 和 Retain 兩種 reclaimPolicy,默認是 Delete

與以前同樣,PVC 在申請 PV 時,只須要指定 StorageClass 和容量以及訪問模式,好比:

 

除了 AWS EBS,Kubernetes 支持其餘多種動態供給 PV 的 Provisioner,完整列表請參考 https://kubernetes.io/docs/concepts/storage/storage-classes/#provisioner

5.PV&&PVC在應用在mysql的持久化存儲

下面演示如何爲 MySQL 數據庫提供持久化存儲,步驟爲:

  1. 建立 PV 和 PVC。

  2. 部署 MySQL。

  3. 向 MySQL 添加數據。

  4. 模擬節點宕機故障,Kubernetes 將 MySQL 自動遷移到其餘節點。

  5. 驗證數據一致性。

 

首先建立 PV 和 PVC,配置以下:

mysql-pv.yml

 

mysql-pvc.yml

建立 mysql-pv 和 mysql-pvc

 

接下來部署 MySQL,配置文件以下:

 

 PVC mysql-pvc Bound 的 PV mysql-pv 將被 mount 到 MySQL 的數據目錄 var/lib/mysql

MySQL 被部署到 k8s-node2,下面經過客戶端訪問 Service mysql

kubectl run -it --rm --image=mysql:5.6 --restart=Never mysql-client -- mysql -h mysql -ppassword

 

更新數據庫:

① 切換到數據庫 mysql。

② 建立數據庫表 my_id。

③ 插入一條數據。

④ 確認數據已經寫入。

 關閉 k8s-node2,模擬節點宕機故障。

 

驗證數據的一致性:

 因爲node2節點已經宕機,node1節點接管了這個任務。

經過kubectl run 命令 進入node1的這個pod裏,查看數據是否依舊存在

 

MySQL 服務恢復,數據也無缺無損。

6.小結

本章咱們討論了 Kubernetes 如何管理存儲資源。

emptyDir 和 hostPath 類型的 Volume 很方便,但可持久性不強,Kubernetes 支持多種外部存儲系統的 Volume。

PV 和 PVC 分離了管理員和普通用戶的職責,更適合生產環境。咱們還學習瞭如何經過 StorageClass 實現更高效的動態供給。

最後,咱們演示瞭如何在 MySQL 中使用 PersistentVolume 實現數據持久性。

相關文章
相關標籤/搜索