Kubernetes集群高級存儲資源PV及PVC
文章目錄
- Kubernetes集群高級存儲資源PV及PVC
-
- 1.高級存儲PV和PVC概念部分
- 2.PV和PVC資源的生命周期
- 3.PV資源介紹與案例配置
- 4.PVC資源介紹與案例配置
-
-
- 4.2.2.指定PVC使用某個PV
- 4.3.查看pvc的詳細輸出
-
- 5.創建Pod資源使用PVC高級存儲
-
- 5.1.編寫pv及pvc資源yaml文件
- 5.2.創建pod並觀察資源狀態
- 5.3.向nfs存儲中寫入數據觀察pod的效果
- 6.將PV的回收策略設置為Recycle觀察生命周期
1.高級存儲PV和PVC概念部分
像NFS類型提供的存儲需要用戶會搭建NFS系統,並且會在yaml中配置nfs,由於k8s支持的存儲系統很多,要求用戶全部掌握不太現實。
針對以上現象,k8s提供了PV和PVC兩種資源對象。
PV(persistent Volume)是持久化卷的意思,是對底層共享存儲的一種抽象,一般情況下PV通過插件完成與共享存儲的對接。
PVC(Persistent Volume Claim)是持久卷聲明的意思,表示從哪個PV中獲取存儲空間。
PV具體對存儲進行配置和分配,pod等資源可以使用PV抽象出來的存儲資源PVC,不需要指定集群的存儲細節。
PV和PVC類似於Pod和Node的關系,創建pod需要消耗一定的node資源,node上提供了各種控制器類型,而PV則提供了各種存儲資源,PVC只需要指定使用哪個PV,就可以從PV中分配一定的資源給PVC,最后Pod掛載PVC就可以實現數據的持久化。
注意:PVC需要分配namespace,不分配默認在default命名空間中,一個pod只能使用當前namespace中的pvc

2.PV和PVC資源的生命周期
PV和PVC是一一對應的,即一個PV只能為一個PVC服務
生命周期的幾個階段:
-
資源供應:運維手動創建底層存儲和PV資源
-
資源綁定:用戶創建PVC后kubernetes負責根據PVC的聲明自動去匹配合適的PV並進行綁定,也可以通過標簽選擇器讓PVC去匹配指定的PV資源
在用戶定義好PVC之后,系統將根據PVC對存儲資源的請求,選擇一個滿足條件的PV進行綁定
PVC在綁定PV時會有兩種情況:
- 匹配到合適的PV,就與該PV進行綁定,Pod應用也就可以使用該PVC作為存儲
- 如果匹配不到合適的PV,PVC則會處於Pengding狀態,知道出現一個符合要求的PV
PV一旦綁定上某個PVC,就會被這個PVC獨占,不能在與其他PVC進行綁定 -
資源使用:可以在Pod中像volume一樣使用pvc作為持久化存儲,在pod中定義volumes,類型為PVC,在容器中定義volumMounts調用PV並指定PVC掛載的路徑
-
資源釋放:運維刪除PVC來釋放PV
當存儲資源使用完畢后,運維可以刪除PVC,與該PVC綁定的PV將會被標記為“已釋放(Released)”狀態,但是還不能立刻與其他PVC進行綁定,通過之前PVC寫入的數據還被保留在存儲設備上,只有在回收之后,該PV才能被再次使用
-
資源回收:kubernetes根據PV設置的回收策略進行資源的回收
對於PV,可以設定回收策略,用於設置與之綁定的PVC釋放資源后如何處理遺留數據的問題,只有PV的存儲空間完成回收,才能為新的PVC提供綁定和使用
PV和PVC的生命周期: 1.首先准備好存儲設備,例如nfs、gfs等 2.通過yaml創建pv,創建好pv后,此時pv處於待使用狀態 3.通過yaml創建pvc,pvc創建后,kubernetes根據pvc的聲明自動匹配一個符合要求的pv,並與pv進行綁定,如果沒有符合要求的pv,pvc將會處於pengding狀態,直到出現符合要求的pv為止 4.pvc准備好之后就可以讓pod進行使用了,pod可以通過valume的方式將pvc掛載到容器的某個路徑上,實現持久化存儲 5.當pvc資源使用完畢,被刪除后,pv此時處於released狀態,這時新的pvc是不能在當前pv上進行綁定,只有當回收策略執行完畢,pv上遺留的之前pvc數據清除后,新的pvc才能與pv進行綁定 6.當pv通過回收策略將pvc的數據清除后,pv再次處於待使用狀態 pv和pvc的德勝門周期類似一個環形結構,一輪一輪的反復工作
3.PV資源介紹與案例配置
3.1.PV資源清單文件
apiVersion: v1 kind: PersistentVolume metadata: name: pv1 spec: nfs: //存儲類型,不同的存儲類型配置都不相同,nfs則填寫nfs capacity: //存儲能力,目前只支持存儲空間的設置 storage: 2Gi //具體的存儲大小 accessModes: //訪問模式 storageClassName: //存儲類別 persistentVolumeReclaimPolicy: //回收策略 PV關鍵參數配置說明: 存儲類型 底層實際存儲的類型,k8s支持多種存儲類型,每種存儲類型都存在配置差異 存儲能力(capacity) 目前只支持存儲空間的設置,未來可能會加入iops、吞吐量等指標的配置 訪問模式(accessMode) 用於描述pv對應存儲資源的訪問權限,有三種訪問權限配置 ReadWriteOnce(RWO):讀寫權限,但是只能被單個節點掛載,也就是說只能被一個pvc進行掛載,第二個pvc無法使用當前pv ReadOnlyMany(ROX):只讀權限,可以被多個節點掛載,也就是說可以被多個pvc同時使用,但是只有讀權限 ReadWriteMany(RWX):讀寫權限,可以被多個節點掛載,也就是說可以被多個pvc同時使用,並且可讀可寫 底層不同的存儲類型可能支持的訪問模式不同 存儲類別(storageClassName) PV可以通過storageClassName指定一個存儲類別 具有特定類別的PV只能與請求了該類別的PVC進行綁定,也就是說某個PV設置了存儲類別,只有有pvc請求申請資源時指定了與PV相同的存儲類別才能進行匹配 未設定類別的PV只能與未請求任何類別的PVC進行綁定,也就是說PV沒有設置存儲類別時,只有有pvc請求申請資源時不指定任何存儲類別才能進行匹配 回收策略(persistentVolumeReclaimPolicy) 當PV不再被使用了后,對其的處理方式,目前支持三種策略: Retain(保留)保留數據,需要運維手工清理數據 Recycle(回收)清除PV對應PVC的數據,相當於執行rm -rf volume Delete(刪除)與PV項鏈的后端存儲完成volume數據的刪除,也就相當於nfs自己刪除里面的數據,常用於雲服務商和存儲服務 不同底層存儲支持的回收策略不同 狀態(status) 一個pv的生命周期中,會存在4中不同的階段 Available(可用):表示可用狀態,還未被任何PVC進行綁定 Bound(已綁定):表示PV已經被PVC進行綁定 Released(已釋放):表示PVC被刪除,但是資源還未被集群重新聲明,處於Released狀態下的pv無法讓pvc進行綁定,只有將上次pv殘留的數據刪除后才能再次使用 Failed(失敗):表示該PV的自動回收策略失敗
3.2.創建一個PV資源
以nfs為底層存儲創建3個pv,大小分別為1/2/3G
1)准備nfs共享路徑
1.准備nfs存儲路徑
[root@k8s-master ~]# mkdir /data/pv_{1..3} -p
2.配置nfs將新建的路徑提供共享存儲
[root@k8s-master ~]# vim /etc/exports
/data/pv_1 192.168.81.0/24(rw,no_root_squash)
/data/pv_2 192.168.81.0/24(rw,no_root_squash)
/data/pv_3 192.168.81.0/24(rw,no_root_squash)
3.重啟nfs
[root@k8s-master ~]# systemctl restart nfs
4.查看共享存儲路徑列表
[root@k8s-master ~]# showmount -e
Export list for k8s-master:
/data/pv_3 192.168.81.0/24
/data/pv_2 192.168.81.0/24
/data/pv_1 192.168.81.0/24
2)編寫yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-1
spec:
capacity:
storage: 1Gi #存儲空間大小
accessModes: #訪問模式
- ReadWriteMany #多主機讀寫
persistentVolumeReclaimPolicy: Retain #回收策略為保留
nfs: #使用nfs存儲類型
path: /data/pv_1 #nfs共享路徑
server: 192.168.81.210 #nfs服務器地址
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-2
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /data/pv_2
server: 192.168.81.210
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-3
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /data/pv_3
server: 192.168.81.210
3)創建PV並查看PV的狀態
1.創建pv
[root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pv.yaml
persistentvolume/pv-1 created
persistentvolume/pv-2 created
persistentvolume/pv-3 created
2.查看pv
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE VOLUMEMODE
pv-1 1Gi RWX Retain Available 72s Filesystem
pv-2 2Gi RWX Retain Available 72s Filesystem
pv-3 3Gi RWX Retain Available 72s Filesystem
3.查看pv的詳細信息
[root@k8s-master ~/k8s_1.19_yaml]# kubectl describe pv pv-1
Name: pv-1
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass:
Status: Available
Claim:
Reclaim Policy: Retain
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 1Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 192.168.81.210
Path: /data/pv_1
ReadOnly: false
Events: <none>
4.PVC資源介紹與案例配置
4.1.PVC資源清單文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc
namespace: dev
spec:
accessModes: //訪問模式
selector: //采用標簽選擇具體的pv
storageClassName: //存儲類別
resources: //請求空間
requests:
storage: 5Gi //具體的請求大小
PVC關鍵參數配置說明:
- 訪問模式(accessModes)
- 用於描述pvc對存儲資源的訪問權限,必須和pv的accessModes保持一致
- 選擇條件(selector)
- 通過Label Selector的設置,指定pvc使用哪個pv
- 資源請求:(resources)
- 配置pvc所使用pv的容量
PVC可以根據配置參數自動匹配一個隨機PV,也可以通過selector指定使用某個PV
當pvc刪除后,pv才能被刪除
4.2.創建一個PVC資源
4.2.1.PVC隨機匹配PV
1.查看在2.2中創建的pv資源
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-1 1Gi RWX Retain Available 72s
pv-2 2Gi RWX Retain Available 72s
pv-3 3Gi RWX Retain Available 72s
2.編寫pvc yaml
#創建3個pvc,其中2個容量設置成1G,1個設置成5G,使pvc根據容量大小隨機匹配pv
[root@k8s-master ~/k8s_1.19_yaml]# vim pvc-suiji.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-1
namespace: dev
spec:
accessModes: #設置訪問模式
- ReadWriteMany #多節點可讀可寫
resources: #設置請求的PV容量
requests:
storage: 1Gi \#設置容量為1G,`可以匹配到pv-1`
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-2
namespace: dev
spec:
accessModes: #設置訪問模式
- ReadWriteMany #多節點可讀可寫
resources: #設置請求的PV容量
requests:
storage: 1Gi \#設置容量為1G,`可以匹配到pv-2`
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-3
namespace: dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 5Gi \#設置容量為5G,`應該是無法匹配到任何pv`
3.創建pvc
[root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pvc-suiji.yaml
persistentvolumeclaim/pvc-1 created
persistentvolumeclaim/pvc-2 created
persistentvolumeclaim/pvc-3 created
4.查看pvc的狀態
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pvc -n dev
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
pvc-1 Bound pv-1 1Gi RWX 2m16s
pvc-2 Bound pv-2 2Gi RWX 2m16s
pvc-3 Pending 2m16s
#由於pv-3設置的請求容量為5G,沒有任何pv的容量在5G以上,因此pvc-3一直處於penging狀態,無法匹配pvc
5.查看pv的狀態
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv -n dev
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-1 1Gi RWX Retain Bound dev/pvc-1 13m
pv-2 2Gi RWX Retain Bound dev/pvc-2 13m
pv-3 3Gi RWX Retain Available 13m
#可以看到pvc-1匹配到了pv-1的pv,pvc-2匹配到哦pv-2的pv
4.2.2.指定PVC使用某個PV
需求:pvc-1綁定pv-2 pvc-2綁定pv-1 交叉綁定
主要是通過標簽選擇器的方式讓pvc指定使用某個pv
1)編寫yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pvc-zhiding.yaml
apiVersion: v1
kind: PersistentVolume #控制器類型為pv
metadata:
name: pv-1
labels: #定義一組標簽,用於pvc調用
pv: pv-1 #標簽pv值為pv-1
spec:
capacity: #定義pv的容量
storage: 2Gi
accessModes: #定義訪問模式為多主機可讀可寫
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain #定義回收策略
nfs: #定義使用的存儲類型
path: /data/pv_1 #共享存儲路徑
server: 192.168.81.210 #nfs地址
---
apiVersion: v1
kind: PersistentVolume #控制器類型為pv
metadata:
name: pv-2
labels:
pv: pv-2
spec:
capacity:
storage: 2Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /data/pv_2
server: 192.168.81.210
---
apiVersion: v1
kind: PersistentVolumeClaim #控制器類型為pvc
metadata:
name: pvc-1
namespace: dev #指定所在的namespace
spec:
accessModes: #定義訪問模式,多主機可讀可寫,和pv的訪問模式保持一致
- ReadWriteMany
resources: #定義申請pv資源的大小
requests:
storage: 1Gi
selector: #定義標簽選擇器,用於關聯具體使用哪個pv資源
matchLabels:
pv: pv-2
---
apiVersion: v1
kind: PersistentVolumeClaim #控制器類型為pvc
metadata:
name: pvc-2
namespace: dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
selector:
matchLabels:
pv: pv-1
2)創建資源並查看資源狀態
1.創建資源 [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pvc-zhiding.yaml persistentvolume/pv-1 created persistentvolume/pv-2 created persistentvolumeclaim/pvc-1 created persistentvolumeclaim/pvc-2 created 2.查看pv的狀態 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pv-1 2Gi RWX Retain Bound dev/pvc-2 6s pv-2 2Gi RWX Retain Bound dev/pvc-1 6s #pv-1的pv存儲卷綁定了pvc-2 ,pv-2的pv存儲卷綁定了dev/pvc-1 3.查看pvc的狀態 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pvc -n dev NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-1 Bound pv-2 2Gi RWX 10s pvc-2 Bound pv-1 2Gi RWX 10s #pvc-1綁定在了pv-2的存儲卷,pvc-2綁定在了pv-1的存儲卷

4.3.查看pvc的詳細輸出
[root@k8s-master ~/k8s_1.19_yaml]# kubectl describe pvc pvc-1 -n dev
Name: pvc-1
Namespace: dev
StorageClass:
Status: Bound
Volume: pv-2 #掛載的pv
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 2Gi #可用的大小
Access Modes: RWX #訪問權限
VolumeMode: Filesystem
Mounted By: <none>
Events: <none>
5.創建Pod資源使用PVC高級存儲
需求:創建兩個pod,pod-pvc1使用pvc-1,pod-pvc2使用pvc-2,根據3.2.2中pvc的交叉綁定,理想形態應是pod-pvc1使用pvc-1但是存儲在pv-2上,pod-pvc2使用pvc-2但是存儲在pv-1上
注意:PVC需要分配namespace,不分配默認在default命名空間中,一個pod只能使用當前namespace中的pvc
如果pvc和pod不再一個namespace下,pod將會一直處於pengding狀態,並且提示pvc找不到

5.1.編寫pv及pvc資源yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pod-pv-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc1
namespace: dev
spec:
containers:
- name: nginx-1
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts: #定義持久卷掛載路徑
- name: volume-1 #指定pvc名稱
mountPath: /usr/share/nginx/html #指定pvc掛載到容器的路徑
volumes: #定義持久卷信息
- name: volume-1 #定義持久卷名稱
persistentVolumeClaim: #使用pvc類型
claimName: pvc-1 #指定使用的pvc名稱
readOnly: false #關閉只讀
---
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc2
namespace: dev
spec:
containers:
- name: nginx-2
image: nginx:1.17.1
ports:
- containerPort: 80
volumeMounts:
- name: volume-2
mountPath: /usr/share/nginx/html
volumes:
- name: volume-2
persistentVolumeClaim:
claimName: pvc-2
readOnly: false
5.2.創建pod並觀察資源狀態
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv,pvc -n dev NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pv-1 2Gi RWX Retain Bound dev/pvc-2 20h persistentvolume/pv-2 2Gi RWX Retain Bound dev/pvc-1 20h NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/pvc-1 Bound pv-2 2Gi RWX 20h persistentvolumeclaim/pvc-2 Bound pv-1 2Gi RWX 20h 1.創建資源 [root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pod-pv-pvc.yaml pod/pod-pvc1 created pod/pod-pvc2 created 2.查看pod資源狀態 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pod -n dev NAME READY STATUS RESTARTS AGE pod-pvc1 1/1 Running 0 17m pod-pvc2 1/1 Running 0 17m 3.查看pv,pvc狀態 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv,pvc -n dev NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE persistentvolume/pv-1 2Gi RWX Retain Bound dev/pvc-2 20h persistentvolume/pv-2 2Gi RWX Retain Bound dev/pvc-1 20h NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE persistentvolumeclaim/pvc-1 Bound pv-2 2Gi RWX 20h persistentvolumeclaim/pvc-2 Bound pv-1 2Gi RWX 20h
查看pod資源的詳細信息,明顯看出掛載的設備是什么。
5.3.向nfs存儲中寫入數據觀察pod的效果
pod-pvc1對應的是pv-2,pod-pvc2對應的是pv-1,如果看pod-pvc1的數據是否寫入成功則需要看對應的pv-1的存儲設備,看pod-pvc2的數據是否寫入成功則需要看對應pv-2的存儲設備。
1.向pod-pvc1寫入數據 [root@k8s-master ~/k8s_1.19_yaml]# echo "pod-pvc1 pv-2 pvc-1" > /data/pv_2/index.html 2.向pod-pvc2寫入數據 [root@k8s-master ~/k8s_1.19_yaml]# echo "pod-pvc2 pv-1 pvc-1" > /data/pv_1/index.html 3.查看pod的ip地址 [root@k8s-master ~/k8s_1.19_yaml]# kubectl get pod -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-pod 1/1 Running 1 6h44m 10.244.1.51 k8s-node1 <none> <none> pod-pvc1 1/1 Running 1 6h34m 10.244.1.53 k8s-node1 <none> <none> pod-pvc2 1/1 Running 1 6h34m 10.244.1.50 k8s-node1 <none> <none> 4.訪問pod [root@k8s-master ~/k8s_1.19_yaml]# curl 10.244.1.53 pod-pvc1 pv-2 pvc-1 [root@k8s-master ~/k8s_1.19_yaml]# curl 10.244.1.50 pod-pvc2 pv-1 pvc-1 #均是我們想要的信息
6.將PV的回收策略設置為Recycle觀察生命周期
將PV的回收策略設置為Recycle觀察PV的狀態
1.編寫yaml文件
[root@k8s-master ~/k8s_1.19_yaml]# vim pv-recycle.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-3
spec:
capacity:
storage: 3Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Recycle #將PV回收策略設置為Recycle
nfs:
path: /data/pv_3
server: 192.168.81.210
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-3
namespace: dev
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 2Gi
2.創建資源
[root@k8s-master ~/k8s_1.19_yaml]# kubectl create -f pv-recycle.yaml
persistentvolume/pv-3 created
persistentvolumeclaim/pvc-3 created
3.查看pv和pvc的狀態
[root@k8s-master ~/k8s_1.19_yaml]# kubectl get pv,pvc -n dev
#可以看到pvc-3綁定了pv-3
4.刪除pvc-3
[root@k8s-master ~/k8s_1.19_yaml]# kubectl delete persistentvolumeclaim/pvc-3 -n dev
persistentvolumeclaim "pvc-3" deleted
5.持續觀察pv的狀態
[root@k8s-master ~]# kubectl get pv -w
總結:當pvc-3刪除后,對應吃pv-3首先處於released狀態,當回收策略完成后,pv-3再次處於available狀態。
轉:https://www.tuicool.com/wx/M7fuquJ
