概述
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 實踐全接觸 (第四版) 》