K8s PV和PVC持久化存儲詳解
提示: Kubernetes 官網(wǎng)PV文檔說明:https://kubernetes.io/docs/concepts/storage/persistent-volumes
提示: PV正常情況是由K8s管理員創(chuàng)建,PV是沒有namespace命名空間限制
- PersistentVolume 簡稱PV,是由Kubernetes管理員設(shè)置的存儲,可以配置Ceph、NFS、GlusterFs等常用存儲配置,相對于Volume配置,提供了更多的功能,比如生命周期的管理、大小的限制。PV分為靜態(tài)和動態(tài)。
- PersistentVolumeClaim 簡稱PVC,是對存儲PV的請求(調(diào)用)。
PVC調(diào)用PV流程圖

一、PV策略
1、PV回收策略
persistentVolumeReclaimPolicy參數(shù)配置pv回收策略有以下幾種方法:
- Retain 保留數(shù)據(jù),需要管理員手動回收資源,當(dāng)刪除PVC時,PV仍然存在,PV被視為已釋放,管理員可以手動回收卷。手動創(chuàng)建的PV默認(rèn)值為Retain。
- Delete 刪除數(shù)據(jù),如果Volume插件支持,刪除PVC時會同時刪除PV,目前支持Detele的存儲后端包括AWS EBS, GCE PD,Azure Disk, OpenStack Cinder等。動態(tài)創(chuàng)建的PV默認(rèn)值為Delete。
- Recycle(已過時) 回收數(shù)據(jù),如果Volume插件支持,當(dāng)刪除PV時,該策略會對卷執(zhí)行rm -rf清理該P(yáng)V,并使其可用于下一個新PVC,目前只有NFS和HostPath支持該策略,該策略不推薦使用。
2、PV訪問策略
- ReadWriteOnce(RWO) 可以被單節(jié)點以讀寫模式掛載,命令行中可以被縮寫為 RWO
- ReadOnlyMany(ROX) 可以被多個節(jié)點以只讀模式掛載,命令行中可以被縮寫為 ROX
- ReadWriteMany(RWX) 可以被多個節(jié)點以讀寫模式掛載,命令行中可以被縮寫為RWX
- ReadWriteOncePod(RWOP) 可以被單個Pod以讀寫模式掛載,命令行中可以被縮寫為RWXP(只支持 CSI 卷以及需要 Kubernetes 1.22 以上版本)
3、PV訪問策略支持的存儲類型
提示:Kubenetes官方文檔說明 https://kubernetes.io/docs/concepts/storage/persistent-volumes

4、存儲的分類
- 文件存儲 一些數(shù)據(jù)可能需要被多個節(jié)點使用,比如用戶的頭像、用戶上傳的文件等,實現(xiàn)方式:NFS、NAS、FTP、CephFS等。(NFS\FTP生產(chǎn)系統(tǒng)不推薦使用)
- 塊存儲 一些數(shù)據(jù)只能被一個節(jié)點使用,或者是需要將一塊裸盤整個掛載使用,比如MySQL數(shù)據(jù)庫、Redis等,實現(xiàn)方式:Ceph、GlusterFs、公有云
- 對象存儲 由程序代碼直接實現(xiàn)的一種存儲方式,云原生應(yīng)用無狀態(tài)化常用的實現(xiàn)方式,實現(xiàn)方式:一般是符合S3協(xié)議的云存儲,比如AWS的S3存儲、Minio等
5、PV參數(shù)說明
apiVersion: v1 # 填寫API資源版本號,通過kubectl api-resources | grep PersistentVolume命令查詢API資源版本號
kind: PersistentVolume # 指定資源類型,PersistentVolume資源類型是PersistentVolume
metadata: # 包含PersistentVolume元數(shù)據(jù)
name: nfs-pv # 自定義PersistentVolume名稱
labels: # 設(shè)置PersistentVolume標(biāo)簽
type: nfs-pv # 自定義PersistentVolume標(biāo)簽名稱
namespace: default # 指定PersistentVolume的命名空間,默認(rèn)default
spec: # 定義PersistentVolume規(guī)格
capacity: # 限制存儲容量大小,NFS不支持該參數(shù),默認(rèn)不限制
storage: 5Gi # 限制存儲容量為5GB
volumeMode: Filesystem # 定義PV的卷模式(存儲類型),支持Filesystem(文件系統(tǒng))或Block(塊設(shè)備), 其中Block類型需要后端存儲支持,默認(rèn)值Filesystem(文件系統(tǒng))
accessModes: # 定義PV的卷訪問模式(PV訪問策略),支持ReadWriteOnce(RWO)、ReadOnlyMany(ROX) 、ReadWriteMany(RWX)、ReadWriteOncePod(RWOP)
- ReadWriteOnce # 設(shè)置ReadWriteOnce,只允許單個節(jié)點以讀寫模式掛載
persistentVolumeReclaimPolicy: Retain # 定義PV的卷回收策略,支持Retain、Recycle、Delete,手動創(chuàng)建PV默認(rèn)值Retain,動態(tài)創(chuàng)建PV默認(rèn)值Delete
storageClassName: nfs-slow # 定義PV存儲類名稱,方便PVC調(diào)用使用,與PVC的spec.storageClassName參數(shù)值匹配
nfs: # 定義PV類型,當(dāng)前設(shè)置為NFS類似
server: 172.20.236.210 # 設(shè)置NFS服務(wù)器的IP地址
path: /nfs # 設(shè)置NFS服務(wù)器掛載目錄
6、PVC參數(shù)說明
apiVersion: v1 # 填寫API資源版本號,通過kubectl api-resources | grep PersistentVolumeCliam命令查詢API資源版本號
kind: PersistentVolumeClaim # 指定資源類型,PersistentVolumeCliam資源類型是PersistentVolumeCliam
metadata: # 包含PersistentVolumeCliam元數(shù)據(jù)
name: nfs-pvc # 自定義PersistentVolumeCliam名稱
labels: # 設(shè)置PersistentVolumeCliam標(biāo)簽
type: nfs-pvc # 自定義PersistentVolumeCliam標(biāo)簽名稱
namespace: default # 指定PersistentVolumeCliam的命名空間,默認(rèn)default
spec: # 定義PersistentVolumeCliam規(guī)格
storageClassName: nfs-slow # 定義PVC調(diào)用的存儲類名稱,與PersistentVolume的spec.storageClassName參數(shù)值匹配
accessModes: # 定義PVC的卷訪問模式(PV訪問策略),支持ReadWriteOnce(RWO)、ReadOnlyMany(ROX) 、ReadWriteMany(RWX)、ReadWriteOncePod(RWOP),此值要與請求的PV的spec.accessModes參數(shù)值匹配
- ReadWriteOnce # 設(shè)置ReadWriteOnce,只允許單個節(jié)點以讀寫模式掛載,此值要與請求的PV的spec.accessModes參數(shù)值匹配
resources: # 定義資源請求和限制
requests:
storage: 3Gi # 定義資源請求磁盤容量大小,當(dāng)前3GB
7、PV和PVC使用注意事項
(1)、PVC申請的空間大小不能大于PV的大小
(2)、PVC的spec.storageClassName參數(shù)值必須與PV的spec.storageClassName參數(shù)值一樣
(3)、PVC的spec.accessMode參數(shù)值必須與PV的spec.accessMode參數(shù)值一樣
(4)、一個PV只能被一個PVC請求調(diào)用使用,PVC和Pod必須在同一個Namespace命令空間下
二、創(chuàng)建PV(NFS)
提示: 生產(chǎn)系統(tǒng)不推薦使用NFS,推薦使用NAS,NFS是存在單點故障,NAS可配置高可用
1、創(chuàng)建PV(NFS)
### CentOS系統(tǒng)安裝NFS服務(wù)端(建議把NFS服務(wù)端安裝到K8s集群之外的服務(wù)器上,不要安裝到K8s集群任意的節(jié)點上)
mkdir -p /nfs
yum install -y nfs-utils rpcbind
cat > /etc/exports << 'EOF'
/nfs *(rw,sync,insecure,no_subtree_check,no_root_squash)
EOF
systemctl start rpcbind
systemctl start nfs
systemctl enable rpcbind
systemctl enable nfs
systemctl status rpcbind
systemctl status nfs
showmount -e localhost
### k8s集群選擇K8s-node01節(jié)點安裝NFS客戶端,測試掛載并卸載掛載
mkdir -p /nfs
apt install -y nfs-common
systemctl start rpcbind
systemctl enable rpcbind
systemctl status rpcbind
showmount -e 172.20.236.210
mount 172.20.236.210:/nfs /nfs
df -h
umount /nfs
### 創(chuàng)建PV
mkdir -p /data/yaml/pv
cat > /data/yaml/pv/nfs-pv.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolume
metadata:
name: nfs-pv
labels:
type: nfs-pv
namespace: default
spec:
capacity:
storage: 5Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: nfs-slow
nfs:
server: 172.20.236.210
path: /nfs
EOF
kubectl create -f /data/yaml/pv/nfs-pv.yaml
### 查看PV
kubectl get pv -n default -owide
kubectl get pv -n default -oyaml
# 查看PV的STATUS狀態(tài)說明
Available # 可用,沒有被PVC綁定的空閑資源
Bound # 已綁定,已經(jīng)被PVC綁定
Released # 已釋放,PV被刪除,但是資源還未被重新使用
Failed # 失敗,自動回收失敗
2、創(chuàng)建PVC并調(diào)用PV
### 創(chuàng)建PVC調(diào)用PV
cat > /data/yaml/pv/nfs-pvc.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nfs-pvc
labels:
type: nfs-pvc
namespace: default
spec:
storageClassName: nfs-slow
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
EOF
kubectl create -f /data/yaml/pv/nfs-pvc.yaml
### 查看PVC狀態(tài)
kubectl get pvc -n default
kubectl get pvc -n default -owide
kubectl get pvc -n default -oyaml
### 此時查看PV狀態(tài)STATUS顯示綁定
kubectl get pv -n default –owide
3、創(chuàng)建Deployment調(diào)用PVC
### K8s集群k8s-node01節(jié)點打標(biāo)簽并查看
kubectl label node k8s-node01 run=nfs
get node --show-labels -l run=nfs -owide
### 創(chuàng)建Deployment調(diào)用PVC(Pod必須指定運(yùn)行k8s-node01節(jié)點上,否則運(yùn)行在其它K8s節(jié)點都會失?。?
cat > /data/yaml/pv/nginx-deploy-pvc.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-pvc
name: nginx-deploy-pvc
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
nodeSelector:
run: nfs
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-nfs-storage
volumes:
- name: pv-nfs-storage
persistentVolumeClaim:
claimName: nfs-pvc
EOF
kubectl create -f /data/yaml/pv/nginx-deploy-pvc.yaml
kubectl get deploy -n default
kubectl get pods -n default -owide
### 登錄NFS服務(wù)器在NFS掛載的共享目錄創(chuàng)建一個文件
echo "Welcome to Nginx World" > /nfs/index.html
ls -l /nfs/index.html
cat /nfs/index.html
### 登錄兩個Pod資源的nginx容器測試
kubectl get pods -n default -owide
kubectl exec -n default nginx-deploy-pvc-659d6c64b9-b5d4b -- cat /usr/share/nginx/html/index.html
kubectl exec -n default nginx-deploy-pvc-659d6c64b9-bj446 -- cat /usr/share/nginx/html/index.html
curl 172.30.85.201
curl 172.30.85.202
### PVC刪除操作:先刪除Deployment,再刪除PVC,最后刪除PV
kubectl delete -f /data/yaml/pv/nginx-deploy-nfs.yaml
kubectl delete -f /data/yaml/pv/nfs-pvc.yaml
kubectl delete -f /data/yaml/pv/nfs-pv.yaml
三、創(chuàng)建PV(hostPath)
提示: 在使用PV(hostPath)掛載到任意一個K8s集群節(jié)點,推薦給選定的K8s集群節(jié)點打上標(biāo)簽,把PV(hostPath)掛載到選定的K8s集群節(jié)點
1、創(chuàng)建PV(hostPath)
### 創(chuàng)建PV
### spec.hostPath.type參數(shù)值為DirectoryOrCreate表示如果宿主機(jī)給定/mnt/data 路徑不存在,那么將自動創(chuàng)建一個權(quán)限為0755 的空目錄,和Kubelet 具有相同的組和權(quán)限
mkdir -p /data/yaml/pv
cat > /data/yaml/pv/pv-hostpath.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-hostpath
namespace: default
labels:
type: pv-local
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
storageClassName: hostpath-ide
hostPath:
path: "/mnt/data"
type: DirectoryOrCreate
EOF
kubectl create -f /data/yaml/pv/pv-hostpath.yaml
kubectl get pv -n default
kubectl get pv -n default -owide
kubectl get pv -n default -oyaml
2、創(chuàng)建PVC調(diào)用PV
### 創(chuàng)建PVC調(diào)用PV
cat > /data/yaml/pv/pvc-hostpath.yaml << 'EOF'
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-hostpath
namespace: default
spec:
storageClassName: hostpath-ide
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
EOF
kubectl create -f /data/yaml/pv/pvc-hostpath.yaml
kubectl get pvc -n default
kubectl get pvc -n default -owide
kubectl get pvc -n default -oyaml
kubectl get pv -n default
3、創(chuàng)建Deployment調(diào)用PVC
### 創(chuàng)建Deployment調(diào)用PVC
cat > /data/yaml/pv/nginx-deploy-hostpath.yaml << 'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx-deploy-hostpath
name: nginx-deploy-hostpath
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- image: registry.cn-shenzhen.aliyuncs.com/dockerghost/nginx:1.26
name: nginx
ports:
- containerPort: 80
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: pv-hostpath-storage
volumes:
- name: pv-hostpath-storage
persistentVolumeClaim:
claimName: pvc-hostpath
EOF
kubectl create -f /data/yaml/pv/nginx-deploy-hostpath.yaml
kubectl get deploy -n default
kubectl get pods -n default -owide
### 查看每個Pods資源中nginx容器分配置到的K8s集群節(jié)點宿主機(jī)是否自動創(chuàng)建了/mnt/data目錄
kubectl get pods -owide
### 登錄K8s集群nginx容器運(yùn)行的K8s節(jié)點創(chuàng)建測試文件
echo "Welcome to Nginx World" > /mnt/data/index.html
cat /mnt/data/index.html
### 登錄兩個Pod資源的nginx容器測試
kubectl get pods -n default -owide
kubectl exec -n default nginx-deploy-hostpath-bb7ddf9d6-87gn6 -- cat /usr/share/nginx/html/index.html
kubectl exec -n default nginx-deploy-hostpath-bb7ddf9d6-r57tl -- cat /usr/share/nginx/html/index.html
curl 172.30.135.137
curl 172.30.122.180
### PVC刪除操作:先刪除Deployment,再刪除PVC,最后刪除PV
kubectl delete -f /data/yaml/pv/nginx-deploy-hostpath.yaml
kubectl delete -f /data/yaml/pv/pvc-hostpath.yaml
kubectl delete -f /data/yaml/pv/pvc-hostpath.yaml
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Kubernetes k8s configmap 容器技術(shù)解析
這篇文章主要為大家介紹了k8s configmap 容器技術(shù)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
K8s學(xué)習(xí)之Pod的定義及詳細(xì)資源調(diào)用案例
Kubernetes將所有內(nèi)容抽象為資源,通過操作資源管理集群,核心單元是Pod,通過控制器管理Pod,資源管理分為命令式對象管理、命令式對象配置和聲明式對象配置,各有適用場景,需要的朋友可以參考下2024-09-09
k8s容器狀態(tài)Terminating無法刪除的問題及解決
這篇文章主要介紹了k8s容器狀態(tài)Terminating無法刪除的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2025-07-07
基于云服務(wù)MRS構(gòu)建DolphinScheduler2調(diào)度系統(tǒng)的案例詳解
這篇文章主要介紹了基于云服務(wù)MRS構(gòu)建DolphinScheduler2調(diào)度系統(tǒng),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-05-05

