k8s 持久化儲存 PV 和 PVC 的簡單使用
概述
Kubernetes
對於有狀態的容器應用或者對資料需要持久化的應用,可以通過 hostPath
或者 emptyDir
的方式來持久化我們的資料,但是我們需要更加可靠的儲存來儲存應用的持久化資料。不過儲存資源和 CPU 資源以及記憶體資源有很大不同,為了遮蔽底層的技術實現細節,讓使用者更加方便的使用,Kubernetes
便引入了 PV
和 PVC
兩個重要的資源物件來實現對儲存的管理。
概念
PV (PersistentVolume)
是對底層網路共享儲存的抽象,將共享儲存定義為一種 “資源”。PV 一般由K8S的管理員所建立和配置,它和具體的底層的共享儲存技術的實現方式有關,比如 Ceph
GlusterFS
、NFS
等,都是通過外掛機制完成與共享儲存的對接。
PVC (PersistentVolumeClaim)
是使用者對儲存資源的一個 “申請”。就像 Pod
消費 Node
資源一樣,PVC
能夠消費 PV
的資源。Pod
可以請求節點的CPU和記憶體,而 PVC
可以請求特定的儲存空間和訪問模式。對於使用者來說,不需要關心底層的儲存實現細節,只需要直接使用 PVC
即可。
實戰:基於NFS共享儲存建立PV和PVC
示例:基於NFS儲存來建立PV和PVC
本次共享儲存資源選擇本地自建的NFS,關於搭建NFS的教程參考之前寫的博文:centos7搭建NFS服務
試驗環境如下,注意所有k8s節點都要安裝nfs,yum install -y nfs-tools
主機名hostname | IP地址 | 說明 |
---|---|---|
master | 192.168.18.10 | k8s主節點 |
node1 | 192.168.18.11 | k8s的node1節點 |
node2 | 192.168.18.12 | k8snode2節點 |
db | 192.168.18.7 | NFS伺服器,共享目錄/data/nfs/test-pv |
PV
PV 作為儲存資源,主要包括儲存能力、訪問模式、儲存型別、回收策略、後端儲存型別等關鍵資訊的設定。PV 是沒有名稱空間的隔離性的。下面來建立一個PV 資源物件:
apiVersion: v1 kind: PersistentVolume metadata: name: pv001 spec: capacity: storage: 5Gi accessModes: - ReadWriteMany persistentVolumeReclaimPolicy: Recycle storageClassName: nfs-slow nfs: path: /data/nfs/test-pv server: 192.168.18.7
上面yaml檔案表明:建立了一個名字是pv001的PV,使用NFS型別的後端儲存,宣告5G的儲存空間,訪問模式是 ReadWriteMany
,回收策略為 Recyle
。有了yaml檔案後,直接建立即可。
# 建立pv
[root@master k8s-yaml]# kubectl create -f pv.yaml
# 檢視pv
[root@master k8s-yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 5Gi RWX Recycle Available nfs-slow 5s
PV的常用配置引數
1. 儲存能力(Capacity)
一個 PV 物件一般都要指定一個儲存能力,通過 PV 的 capacity
屬性來設定的,比如這裡的 storage: 5Gi
,目前只支援對儲存空間的設定,未來可能加入IOIPS、吞吐量等指標的設定。
2. 訪問模式(Access Modes)
對 PV 進行訪問模式的設定,用於描述使用者的應用對儲存資源的訪問許可權。分為三種:
ReadWriteOnce
:讀寫許可權,並且只能被單個 Node 掛載;ReadOnlyMany
:只讀許可權,允許被多個 Node 掛載;ReadWriteMany
:讀寫許可權,允許被多個 Node 掛載
一些 PV 可能支援多種訪問模式,但是在掛載的時候只能使用一種訪問模式,多種訪問模式是不會生效的。
3. 儲存類別(Class)
PV 可以設定其儲存的類別,通過 storageClassName
引數指定一個 StorageClass
資源物件的名稱。具有特定類別的 PV 只能與請求了該類別的 PVC 進行繫結。未設定類別的 PV 則只能與不請求任何類別的 PVC 進行繫結。
4. 回收策略
回收策略是通過 persistentVolumeReclaimPolicy
引數進行設定,可選性如下:
Retain
:保留,需要手動清理資料Recycle
:回收,清楚PV中的資料,相當於rm -rf /thevolume/*
命令Delete
:刪除,與 PV 相連的後端儲存完成volume的刪除操作,刪除 PVC 後,PV也會被刪掉。這一類的PV,需要支援刪除功能,是動態儲存的預設方式。
PV 的生命週期
一個 PV 在生命週期可能處於下面四個階段之一:
Available
:可用狀態,還沒有於某個PVC進行繫結Bound
:已跟某個PVC繫結Released
:繫結的PVC已經刪除,資源已經釋放,但是沒有被叢集回收Failed
:自動資源回收失敗
上面建立了PV之後,由於還沒有任何PVC跟PV繫結,所以PV的狀態還是 Available
。
PVC
PVC 作為使用者對儲存資源的需求申請,主要包括儲存空間請求、訪問模式、PV選擇條件和儲存類別的資訊的設定。如下,新建一個PVC,跟上面建立的PV進行繫結。
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 3Gi
storageClassName: nfs-slow
該PVC申請了與儲存類別名稱為 nfs-slow
的 PV 進行繫結,請求3G的儲存容量,訪問模式是 ReadWriteMany
,建立該PVC:
[root@master k8s-yaml]# kubectl create -f pvc.yaml
# 檢視default名稱空間下的PVC
[root@master k8s-yaml]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
myclaim Bound pv001 5Gi RWX nfs-slow 6s
# 注意,PVC有名稱空間的隔離性
[root@master k8s-yaml]# kubectl get pvc -n kube-system
No resources found in kube-system namespace.
# 檢視PV狀態
[root@master k8s-yaml]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv001 5Gi RWX Recycle Bound default/myclaim nfs-slow 3h29m
可以看到,在PVC與PV進行繫結之後,PV的狀態變成了 Bound
。但是從上面也看出,我的 PVC 裡面宣告的容量是3G,而PV裡面宣告的容量是5G,結果創建出來的PVC容量卻是5G,說明,PV的容量是多少,PVC的容量就是多少。
如果PVC裡面設定的容量超過PV裡面定義的容量,那麼PVC是建立不成功的,會一直處於Pending狀態。
使用PVC
上面建立了PV和PVC,接下來就可以使用它們了,使用下面nginx-pvc.yaml
進行測試:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-pvc
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.18.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
volumeMounts:
- mountPath: /usr/share/nginx/html
name: my-pvc-volume
volumes:
- name: my-pvc-volume
persistentVolumeClaim:
claimName: myclaim
然後在nfs的共享目錄裡面建立個html檔案:
[root@db ]# cd /data/nfs/test-pv/
[root@db test-pv]# echo "hello k8s pvc" > index.html
建立Deployment
[root@master k8s-yaml]# kubectl create -f nginx-pvc.yaml
檢視Pod:
[root@master k8s-yaml]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-pvc-78c9859d7-94lxn 1/1 Running 0 38s 10.244.166.165 node1 <none> <none>
訪問Pod:
[root@master k8s-yaml]# curl 10.244.166.165
hello k8s pvc
可以看到,Pod內部的容器已經成功掛載nfs的後端儲存。
參考資料
-
《Kubernetes 權威指南:從 Docker 到 Kubernetes 實踐全接觸 (第四版) 》