文章目錄
- 靜態配置(Static Provisioning):
- Persistent volume(PV)
- Local 示例:
- NFS 示例:
- 檢查pv
- PV 的常見狀態說明
- Persistent volume claim(PVC)
- 1. local PVC示例:
- 2.NFS PVC示例:
- 3. 檢查PVC:
- 掛載靜態供應卷
- 驗證靜態供應卷掛載:
- 1. 查看 Deployment 和 Pod 狀態
- 2. 進入容器內部驗證掛載目錄
- 動態供應(Dynamic Provisioning)
- StorageClasses:
- 使用 Helm 安裝 NFS 動態存儲卷插件
- 1. 添加存儲庫
- 2. 安裝命令(請替換你的 NFS IP 和共享路徑):
- 3. 檢查stogrageclass
- 4 . storageclass參收說明:
- 創建 PVC(動態)
- 檢查PVC:
- 動態掛載 PVC 到已部署 Pod
- 添加 Volume
- 添加 VolumeMount 到容器
- 驗證掛載
靜態配置(Static Provisioning):
由集群管理員預先創建 PersistentVolume(PV),這些 PV 攜帶實際存儲的詳細信息,可供集群用戶使用。
Persistent volume(PV)
PersistentVolume(PV)是集群中的一種存儲資源,可由管理員預先配置,或通過 StorageClass 實現動態配置。
Kubernetes 原生支持多種 PersistentVolume(PV)類型,叫做 volume plugins。它們允許你指定不同的底層存儲方式,例如本地目錄、NFS、云存儲等。
實際開發/部署中最常見的內建類型:
類型 | 適用場景 | 說明 |
---|---|---|
local | 本地快速測試或特殊需求 | 需要設置 nodeAffinity |
nfs | 簡單共享存儲,手動配置即可 | 靜態配置,適合小規模共享 |
hostPath | 單節點開發環境使用 | 不推薦用于生產 |
iscsi | 企業 SAN 接入 | 配置復雜 |
Local 示例:
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:name: mnt-pv
spec:accessModes:- ReadWriteManycapacity:storage: 100MivolumeMode: Filesystemlocal:fsType: ext4path: /mntnodeAffinity:required:nodeSelectorTerms:- matchExpressions:- key: kubernetes.io/hostnameoperator: Invalues:- k8sw01.lab.compersistentVolumeReclaimPolicy: Retain
EOF
檢查 persistent Volumes:
NFS 示例:
cat << EOF | kubectl -f -
apiVersion: v1
kind: PersistentVolume
metadata:name: static-nfs-pv
spec:accessModes:- ReadWriteManycapacity:storage: 100MivolumeMode: Filesystemnfs:server: 172.20.32.247path: /data/static-pvpersistentVolumeReclaimPolicy: Retain
EOF
檢查pv
kubectl get pv mnt-pv static-nfs-pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
mnt-pv 100Mi RWX Retain Available <unset> 41m
kubectl get pv 輸出中的 STATUS 列顯示 PersistentVolume (PV) 當前的狀態。上面輸出顯示 Available ,是 PV 的一種狀態,表示它當前沒有被綁定(Bound)給任何 PersistentVolumeClaim (PVC)。
PV 的常見狀態說明
狀態 | 說明 |
---|---|
Available | PV 目前未被任何 PVC 綁定,可以被新的 PVC 申請使用。 |
Bound | PV 已經綁定到某個 PVC,正在被使用中。 |
Released | PV 原先被綁定的 PVC 已被刪除,但 PV 還未被回收或重新配置,可能還保留舊數據。 |
Failed | PV 遇到錯誤或回收失敗,可能無法正常使用。 |
Persistent volume claim(PVC)
為已聲明的 PV 申請綁定:
1. local PVC示例:
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mnt-pvcnamespace: kubeuser
spec:accessModes:- ReadWriteManyresources:requests:storage: 100MivolumeMode: FilesystemvolumeName: mnt-pv
EOF
2.NFS PVC示例:
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: static-nfs-pvcnamespace: kubeuser
spec:accessModes:- ReadWriteManyresources:requests:storage: 100MivolumeMode: FilesystemvolumeName: static-nfs-pv
EOF
3. 檢查PVC:
kubectl get pvc mnt-pvc static-nfs-pvc -n kubeuser
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
mnt-pvc Bound mnt-pv 100Mi RWX <unset> 6m49s
static-nfs-pvc Bound static-nfs-pv 100Mi RWX <unset> 30s
掛載靜態供應卷
cat <<EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:name: nginx-deploymentnamespace: kubeuserlabels:app: nginx
spec:replicas: 1 # 啟動一個副本selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:latest # 使用官方 Nginx 鏡像ports:- containerPort: 80volumeMounts:- mountPath: /mnt/mnt-pvcname: mnt-pvc- mountPath: /mnt/static-nfs-pvcname: static-nfs-pvcvolumes:- name: mnt-pvcpersistentVolumeClaim:claimName: mnt-pvc- name: static-nfs-pvcpersistentVolumeClaim:claimName: static-nfs-pvc
EOF
驗證靜態供應卷掛載:
在成功部署 Nginx 應用并綁定靜態 NFS 卷后,我們可以通過以下步驟來驗證卷是否已經正確掛載到容器中。
1. 查看 Deployment 和 Pod 狀態
首先確認 nginx-deployment 已經成功運行,并且副本狀態正常:
kubectl get deploy nginx-deployment -n kubeuser -o wide
輸出結果類似如下,表示 Deployment 的 Pod 已就緒并運行中:
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
nginx-deployment 1/1 1 1 4m4s nginx nginx:latest app=nginx
接著查看 Pod 的具體名稱和狀態:
root@k8sm01:/home/kubeadmin/yaml/deployments# kubectl get pod -n kubeuser
輸出顯示:
NAME READY STATUS RESTARTS AGE
nginx-deployment-f975675bc-ldgnk 1/1 Running 0 6m48s
2. 進入容器內部驗證掛載目錄
使用 kubectl exec 命令進入 Pod 的容器內部:
kubectl exec -it nginx-deployment-f975675bc-ldgnk -n kubeuser -- bash
進入容器后,可以查看主機名以確認所處環境:
hostname
nginx-deployment-f975675bc-ldgnk
接著檢查掛載目錄內容,例如掛載在 /mnt 下的子目錄:
ls -lh /mnt/
total 8.0K
drwxr-xr-x 2 root root 4.0K Apr 23 2024 mnt-pvc
drwxr-xr-x 2 root root 4.0K May 27 15:14 static-nfs-pvc
這說明 PVC 已被正確掛載進 Pod 的指定路徑中,Pod 可以直接讀寫對應的 NFS 共享目錄,實現持久化存儲。
動態供應(Dynamic Provisioning)
當沒有任何靜態 PersistentVolume 匹配某個 PersistentVolumeClaim 時,集群可能會嘗試為該 PVC 進行動態分配。
此過程基于 StorageClass 進行。要在 Kubernetes 集群中實現 動態存儲卷動態供給(Dynamic Provisioning),必須安裝一個 StorageClass 和一個 支持動態創建 Volume 的 Provisioner。
StorageClasses:
在 GCP、AWS、Azure 或其他云平臺上部署 Kubernetes 集群時,系統會預設創建一個默認的 StorageClass,該 StorageClass 使用標準類型的持久性磁盤。
運行 kubectl get storageclass 返回"No resources found"
kubectl get storageclass
No resources found
默認 Kubernetes 并不會自動安裝這些,所以需要自己配置。
使用 Helm 安裝 NFS 動態存儲卷插件
有關helm的安裝與使用,請參考這篇文章循序漸進掌握Helm
1. 添加存儲庫
helm repo add stable https://charts.helm.sh/stable
helm repo update
2. 安裝命令(請替換你的 NFS IP 和共享路徑):
helm install nfs-client nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \--namespace default \--set nfs.server=172.20.32.247 \--set nfs.path=/data/dynamic-pv \--set storageClass.defaultClass=true \--set storageClass.name=nfs-client
3. 檢查stogrageclass
運行 kubectl get storageclass:
kubectl get storageclass
應該能看到:
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
nfs-client (default) cluster.local/nfs-client-nfs-subdir-external-provisioner Delete Immediate true 6m59s
storageclass yaml內容:
kubectl get storageclass -o yaml
apiVersion: v1
items:
- allowVolumeExpansion: trueapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:annotations:meta.helm.sh/release-name: nfs-clientmeta.helm.sh/release-namespace: defaultstorageclass.kubernetes.io/is-default-class: "true"creationTimestamp: "2025-05-28T14:48:18Z"labels:app: nfs-subdir-external-provisionerapp.kubernetes.io/managed-by: Helmchart: nfs-subdir-external-provisioner-4.0.18heritage: Helmrelease: nfs-clientname: nfs-clientresourceVersion: "1018780"uid: 5912911f-4993-4965-8e75-ba79fe2dca25parameters:archiveOnDelete: "true"provisioner: cluster.local/nfs-client-nfs-subdir-external-provisionerreclaimPolicy: DeletevolumeBindingMode: Immediate
4 . storageclass參收說明:
-
Provisioner(供給器):
StorageClass 中包含一個 provisioner,用于指定創建 PV 時所使用的存儲插件(volume plugin)。 -
Reclaim Policy(回收策略):
該策略決定當 PVC 被刪除后,PV 應該如何處理。可以設置為:
Delete**:自動刪除相關存儲資源。
Retain**:保留數據,需要手動清理。
默認值為 Delete。 -
Volume Binding Mode(卷綁定模式):
volumeBindingMode 字段用于控制卷綁定(volume binding)和動態供給(dynamic provisioning)發生的時機。
Immediate(默認):立即分配卷。 -
Access Modes(訪問模式):
PersistentVolume 支持以下訪問模式:
ReadWriteOnce:卷可被單個節點以讀寫方式掛載。
ReadOnlyMany:卷可被多個節點以只讀方式掛載。
ReadWriteMany:卷可被多個節點以讀寫方式掛載
創建 PVC(動態)
cat << EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: dynamic-nfs-pvcnamespace: kubeuser
spec:storageClassName: nfs-clientaccessModes:- ReadWriteManyresources:requests:storage: 100MivolumeMode: Filesystem
EOF
檢查PVC:
可以看到剛剛創建的dynamic-nfs-pvc ,已經綁定storageclass:nfs-client,但status仍為pending狀態,如果綁定成功,PVC 狀態將變為 Bound,并關聯到系統自動創建的 PV。
kubectl get pvc -n kubeuser
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
dynamic-nfs-pvc Pending nfs-client <unset> 3m6s
mnt-pvc Bound mnt-pv 100Mi RWX <unset> 23h
static-nfs-pvc Bound static-nfs-pv 100Mi RWX <unset> 23h
使用kubectl describe查看,將顯示此pvc的細節信息
kubectl describe pvc dynamic-nfs-pvc -n kubeuser
輸出顯示仍然等待綁定
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal ExternalProvisioning 110s (x42 over 11m) persistentvolume-controller Waiting for a volume to be created either by the external provisioner 'cluster.local/nfs-client-nfs-subdir-external-provisioner' or manually by the system administrator. If volume creation is delayed, please verify that the provisioner is running and correctly registered.
動態掛載 PVC 到已部署 Pod
由于在靜態供應(Static Provisioning)中已經部署了示例deployment,我們將繼續使用這個deployment,并通過 kubectl patch 命令對已有 Deployment 添加動態 PVC:
kubectl patch deployment nginx-deployment -n kubeuser -p '{"spec":{"template":{"spec":{"volumes":[{"name":"dynamic-nfs-pvc","persistentVolumeClaim":{"claimName":"dynamic-nfs-pvc"}}]}}}}'
deployment.apps/nginx-deployment patched
添加 Volume
kubectl patch deployment nginx-deployment -n kubeuser -p '{"spec":{"template":{"spec":{"containers":[{"name":"nginx","volumeMounts":[{"mountPath":"/mnt/dynamic-nfs-pvc","name":"dynamic-nfs-pvc"}]}]}}}}'
添加 VolumeMount 到容器
kubectl get pvc -n kubeuser
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
dynamic-nfs-pvc Bound pvc-5179e3bb-831b-45f7-b0a0-96911e6b2b21 100Mi RWX nfs-client <unset> 22h
mnt-pvc Bound mnt-pv 100Mi RWX <unset> 45h
static-nfs-pvc Bound static-nfs-pv 100Mi RWX <unset> 45h
驗證掛載
get pvc dynamic-nfs-pvc -n kubeuser
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
dynamic-nfs-pvc Bound pvc-5179e3bb-831b-45f7-b0a0-96911e6b2b21 100Mi RWX nfs-client <unset> 23h
進入容器內部
kubectl exec -it nginx-deployment-64699f648c-jlrl2 -n kubeuser -- bash
確認已經進入容器內部
hostname
nginx-deployment-64699f648c-jlrl2
輸出目錄中應包含:
ls -lh /mnt
total 12K
drwxrwxrwx 2 root root 4.0K May 28 15:21 dynamic-nfs-pvc
drwxr-xr-x 2 root root 4.0K Apr 23 2024 mnt-pvc
drwxr-xr-x 2 root root 4.0K May 27 15:14 static-nfs-pvc
說明所有三種 PVC(local、static NFS、dynamic NFS)已成功掛載,Pod 可讀寫使用。