K8s進階之一文搞懂PV,PVC及SC
前言
想了解Pod的基本存儲,可以參考這篇文章:K8s新手系列之Pod的基本存儲
概述
官方文檔:
- 配置Pod使用PV進行存儲:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-persistent-volume-storage/
- PV(持久卷):https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/
- SC(存儲類):https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/
什么是PV?
PV(Persistent Volume)是持久化卷的意思,是對底層的共享存儲的一種抽象。一般情況下PV由kubernetes管理員進行創建和配置,它與底層具體的共享存儲技術有關,并通過插件完成與共享存儲的對接。
什么是PVC?
PVC(Persistent Volume Claim)是持久卷聲明的意思,是用戶對于存儲需求的一種聲明。換句話說,PVC其實就是用戶向kubernetes系統發出的一種資源需求申請。
什么是SC?
SC(StorageClass)是存儲類的意思,Kubernetes 可以根據 StorageClass 的定義動態地創建持久化存儲卷(PersistentVolume, PV)和持久化卷聲明(PersistentVolumeClaim, PVC)。StorageClass 提供了一種抽象層,允許用戶在不關心底層存儲實現細節的情況下請求存儲資源。


PV詳解
PV 是集群中可被申請的存儲資源,由管理員提前創建并定義存儲參數(如容量、訪問權限、回收策略等)。它與具體的 Pod 解耦,可被多個 Pod 聲明(通過 PVC)和使用。
PV分類
靜態PV
由管理員手動創建 PV 資源清單,預先定義存儲容量、訪問模式、存儲路徑等參數,不依賴StorageClass。
適用于預先配置好的存儲(如自建 NFS、GlusterFS 共享目錄),或需要精細控制存儲配置的場景。
動態PV:
通過StorageClass自動創建,無需手動編寫 PV 清單,Kubernetes 根據PersistentVolumeClaim(PVC)的請求動態分配存儲。
適用于云原生環境(如 AWS EBS、GCE PD)或需要按需分配存儲的場景。
核心作用
解耦應用與存儲基礎設施:Pod 無需關心底層存儲細節(如 NFS 服務器地址、云硬盤類型),通過 PVC 聲明存儲需求即可。
提供持久化存儲:數據不隨 Pod 銷毀而丟失,適用于有狀態應用(如數據庫、文件服務)。
PV的生命周期
-
供應階段(Provisioning):
- 靜態供應(Static Provisioning):管理員手動創建 PV 資源,預先定義存儲細節(如容量、訪問模式、存儲類型等),適用于已知存儲需求的場景。
- 動態供應(Dynamic Provisioning):通過StorageClass自動創建 PV,當 PVC 申請存儲時,Kubernetes 根據 SC 配置調用存儲插件(如 NFS CSI 驅動)動態生成 PV。
-
綁定階段(Binding)
- Bound:找到匹配的 PV,兩者綁定(如用戶示例中的pvc-sc-01狀態為Bound)。
- Pending:未找到匹配 PV(如用戶示例中的pvc-sc-02因未指定 SC,但默認 SC 可能不滿足條件而處于Pending)。
-
使用階段(Using)
- Pod 通過 PVC 掛載 PV,數據持久化存儲到后端存儲(如 NFS 共享目錄)。
- 支持動態擴縮容(需 SC 開啟allowVolumeExpansion: true),通過kubectl patch pvc調整容量。
-
釋放階段(Releasing)
當 PVC 被刪除(kubectl delete pvc),PV 進入Released狀態:- PV 不再被 PVC 綁定,但數據仍保留在后端存儲中(取決于 SC 的reclaimPolicy)。
- 此時 PV 可能存在 “孤兒” 狀態(如 PV 配置與新 PVC 需求不匹配,無法重新綁定)。
-
回收階段(Reclaiming)
PV 的回收行為由reclaimPolicy決定(定義在 PV 或 SC 中,SC 優先級高于 PV),支持三種策略:- Retain(保留,默認)
PV 釋放后保留數據,需管理員手動清理后端存儲或刪除 PV。
適用于需要手動管理數據的場景(如用戶示例中的 SC 配置reclaimPolicy: Retain)。 - Delete(刪除)
PV 釋放后自動刪除后端存儲資源(如 NFS 共享目錄會被刪除,需謹慎?。?。
適用于臨時存儲或無狀態應用。 - Recycle(回收,已棄用)
清除 PV 數據(如執行rm -rf /data/*),Kubernetes 1.17 + 已廢棄,推薦使用Delete或Retain。
- Retain(保留,默認)
PV資源清單文件詳解
apiVersion: v1 # API版本,PV屬于core API組,版本固定為v1
kind: PersistentVolume # 資源類型為PersistentVolume
metadata:
name: pv-nfs # PV名稱,全局唯一
labels: # 可選標簽,用于篩選和關聯PVC
storage: nfs
annotations: # 可選注解,附加元數據
description: "NFS storage for web apps"
spec:
capacity: # PV的存儲容量,必填
storage: 10Gi # 容量大小,支持Gi、Ti等單位
accessModes: # 訪問模式,定義PV如何被掛載,必填(至少一個)
- ReadWriteOnce # RWO:單節點讀寫(最常用,支持Node或Pod級別)
- ReadOnlyMany # ROX:多節點只讀
- ReadWriteMany # RWX:多節點讀寫(需存儲支持,如NFS、GlusterFS)
persistentVolumeReclaimPolicy: # 回收策略,定義PV釋放后的處理方式,默認Retain
Retain # 保留數據,需手動清理(默認)
# Recycle # 已棄用,等價于Delete(僅支持NFS等少數存儲)
# Delete # 刪除存儲(如云硬盤EBS會被刪除,NFS僅刪除PVC綁定)
storageClassName: "" # 關聯的StorageClass名稱,空字符串表示默認類,或不指定
mountOptions: # 掛載時的額外選項(如文件系統參數),可選
- hard
- nfsvers=4.1
nfs: # 存儲類型配置(不同存儲類型字段不同,此處以NFS為例)
server: 10.0.0.30 # NFS服務器IP
path: /data/nfs # NFS共享路徑
# 其他存儲類型(如hostPath、AWS EBS、Ceph等)的配置字段不同,見下方說明
關鍵字段說明
spec.accessModes(訪問模式):必須至少指定一個模式,需與存儲類型兼容:
- ReadWriteOnce (RWO):單節點讀寫(支持同一節點上的多個 Pod 共享)。
- ReadOnlyMany (ROX):多節點只讀(如 NFS 允許多個節點掛載為只讀)。
- ReadWriteMany (RWX):多節點讀寫(需存儲支持,如 NFS、GlusterFS、CephFS)。
注意:云硬盤(如 EBS、PD)通常僅支持 RWO,而 NFS、CephFS 等分布式存儲支持 RWX。
spec.persistentVolumeReclaimPolicy(回收策略)
- Retain(保留)(默認):當 PVC 刪除時,PV 數據保留,狀態變為 Released,需手動清理數據或刪除 PV。
- Delete(刪除):當 PVC 刪除時,自動刪除底層存儲(如云硬盤、S3 Bucket),適用于動態創建的存儲。
- Recycle(回收)(已棄用):清空存儲數據,僅適用于 NFS 等少數存儲,Kubernetes 1.14 + 已移除。
創建靜態pv實戰案例
示例:
# 定義pv
[root@master01 ~/volumes]# cat pv-test01.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-01
labels:
name: pv-01
spec:
capacity:
storage: 10Gi
# 指定存儲類型為nfs
nfs:
server: 10.0.0.30
path: /data/nfs/nginx/pv-01
# 訪問模式
accessModes:
# 多節點讀寫
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
# 創建pv
[root@master01 ~/volumes]# kubectl apply -f pv-test01.yaml
persistentvolume/pv-01 created
# 查看pv
[root@master01 ~/volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-01 10Gi RWX Retain Available 7s
# 查看詳細信息
[root@master01 ~/volumes]# kubectl describe pv pv-01
Name: pv-01
Labels: <none>
Annotations: <none>
Finalizers: [kubernetes.io/pv-protection]
StorageClass:
Status: Available
Claim:
Reclaim Policy: Retain
Access Modes: RWX
VolumeMode: Filesystem
Capacity: 20Gi
Node Affinity: <none>
Message:
Source:
Type: NFS (an NFS mount that lasts the lifetime of a pod)
Server: 10.0.0.30
Path: /data/nfs/nginx/pv-01
ReadOnly: false
Events: <none>
使用kubectl管理pv
查看pv
kubectl get pv <pv-name>
kubectl describe pv <pv-name>
刪除pv
kubectl delete pv <pv-name>
修改pv
方式一:修改資源清單文件再apply即可
方式二:通過kubectl edit修改保存即可
PVC詳解
PVC(Persistent Volume Claim)是持久卷聲明的意思,是用戶對于存儲需求的一種聲明。換句話說,PVC其實就是用戶向kubernetes系統發出的一種資源需求申請。
核心概念
PVC 是名稱空間級別的資源,用于聲明:
- 需要的存儲容量(如 5Gi)。
- 支持的訪問模式(如 ReadWriteOnce)。
- 期望的存儲類型(通過storageClassName關聯 StorageClass)。
PVC 與 PV 的關系類似于 Pod 與 Node 的關系:PVC 請求資源,PV 提供資源,兩者通過綁定機制匹配。
PVC資源清單文件詳解
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc # PVC名稱,命名空間內唯一
namespace: default # 命名空間,默認default
labels:
app: my-app
spec:
accessModes: # 訪問模式,必須與PV兼容
- ReadWriteOnce # 單節點讀寫
resources:
requests:
storage: 5Gi # 請求的存儲容量
storageClassName: "standard" # 關聯的StorageClass名稱,""表示使用默認類
selector: # 可選,通過標簽篩選PV
matchLabels:
storage-type: "ssd"
關鍵字段說明
spec.accessModes(訪問模式):必須至少指定一個模式,需與存儲類型兼容:
- ReadWriteOnce (RWO):單節點讀寫(支持同一節點上的多個 Pod 共享)。
- ReadOnlyMany (ROX):多節點只讀(如 NFS 允許多個節點掛載為只讀)。
- ReadWriteMany (RWX):多節點讀寫(需存儲支持,如 NFS、GlusterFS、CephFS)。
注意:云硬盤(如 EBS、PD)通常僅支持 RWO,而 NFS、CephFS 等分布式存儲支持 RWX。
創建PVC關聯PV實戰
創建PV
以上面案例為基礎,可以修改一下,參考下面的資源文件
[root@master01 ~/volumes]# cat pv-test01.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-01
labels:
name: pv-01
spec:
capacity:
storage: 10Gi
# 指定存儲類型為nfs
nfs:
server: 10.0.0.30
path: /data/nfs/nginx/pv-01
# 訪問模式
accessModes:
# 多節點讀寫
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
創建PVC
# 定義資源文件
[root@master01 ~/volumes]# cat pvc-test01.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-01
labels:
name: pvc-01
namespace: default
spec:
# 定義訪問模式,和pv一樣即可
accessModes:
- ReadWriteMany
# 標簽選擇器,選擇哪一個PV
selector:
matchExpressions:
- key: name
operator: In
values:
- pv-01
# 申請PV的容量,這里申請5G
resources:
requests:
storage: 5G
# 創建PVC
[root@master01 ~/volumes]# kubectl apply -f pvc-test01.yaml
persistentvolumeclaim/pvc-01 created
查看pv和pvc
[root@master01 ~/volumes]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv-01 10Gi RWX Retain Bound default/pvc-01 27m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc-01 Bound pv-01 10Gi RWX 7s
# 查看詳情
[root@master01 ~/volumes]# kubectl describe pvc pvc-01
Name: pvc-01
Namespace: default
StorageClass:
Status: Bound
Volume: pv-01
Labels: name=pvc-01
Annotations: pv.kubernetes.io/bind-completed: yes
pv.kubernetes.io/bound-by-controller: yes
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 10Gi
Access Modes: RWX
VolumeMode: Filesystem
Used By: <none>
Events: <none>
創建Pod關聯PVC使用PV存儲
這里創建MySQL
# 定義資源文件
[root@master01 ~/volumes]# cat pod-mysql.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc
spec:
volumes:
- name: data
# 指定存儲類型為PVC
persistentVolumeClaim:
# 指定PVC的名稱
claimName: pvc-01
# 是否只讀,默認值為false,代表可讀寫
readOnly: false
containers:
- name: mysql
image: mysql:8.0.26
env:
- name: "MYSQL_ROOT_PASSWORD"
value: "root123"
# 掛載存儲卷
volumeMounts:
# 指定存儲卷的名稱
- name: data
mountPath: /var/lib/mysql
# 創建pod
[root@master01 ~/volumes]# kubectl apply -f pod-mysql.yaml
pod/pod-pvc created
查看PV存儲路徑的數據
[root@master01 ~/volumes]# ll /data/nfs/nginx/pv-01/
total 198068
-rw-r----- 1 999 999 196608 May 11 14:45 '#ib_16384_0.dblwr'
-rw-r----- 1 999 999 8585216 May 11 14:45 '#ib_16384_1.dblwr'
drwxr-x--- 2 999 999 4096 May 11 14:45 '#innodb_temp'/
drwxr-xr-x 6 999 root 4096 May 11 14:45 ./
drwxr-xr-x 4 root root 4096 May 11 14:44 ../
-rw-r----- 1 999 999 56 May 11 14:45 auto.cnf
-rw-r----- 1 999 999 3117023 May 11 14:45 binlog.000001
-rw-r----- 1 999 999 156 May 11 14:45 binlog.000002
-rw-r----- 1 999 999 32 May 11 14:45 binlog.index
-rw------- 1 999 999 1680 May 11 14:45 ca-key.pem
-rw-r--r-- 1 999 999 1112 May 11 14:45 ca.pem
-rw-r--r-- 1 999 999 1112 May 11 14:45 client-cert.pem
-rw------- 1 999 999 1680 May 11 14:45 client-key.pem
-rw-r----- 1 999 999 5718 May 11 14:45 ib_buffer_pool
-rw-r----- 1 999 999 50331648 May 11 14:45 ib_logfile0
-rw-r----- 1 999 999 50331648 May 11 14:45 ib_logfile1
-rw-r----- 1 999 999 12582912 May 11 14:45 ibdata1
-rw-r----- 1 999 999 12582912 May 11 14:46 ibtmp1
drwxr-x--- 2 999 999 4096 May 11 14:45 mysql/
-rw-r----- 1 999 999 31457280 May 11 14:45 mysql.ibd
drwxr-x--- 2 999 999 4096 May 11 14:45 performance_schema/
-rw------- 1 999 999 1676 May 11 14:45 private_key.pem
-rw-r--r-- 1 999 999 452 May 11 14:45 public_key.pem
-rw-r--r-- 1 999 999 1112 May 11 14:45 server-cert.pem
-rw------- 1 999 999 1680 May 11 14:45 server-key.pem
drwxr-x--- 2 999 999 4096 May 11 14:45 sys/
-rw-r----- 1 999 999 16777216 May 11 14:45 undo_001
-rw-r----- 1 999 999 16777216 May 11 14:45 undo_002
驗證刪除Pod示例之后數據是否保留
創建模擬數據
# 進入容器
[root@master01 ~/volumes]# kubectl exec -it pod-pvc -- /bin/bash
# 連接MySQL
root@pod-pvc:/# mysql -uroot -proot123
# 創建測試庫
mysql> create database testdb;
Query OK, 1 row affected (0.01 sec)
# 查看數據庫
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.01 sec)
刪除Pod后重新創建
# 刪除pod
[root@master01 ~/volumes]# kubectl delete po pod-pvc
pod "pod-pvc" deleted
# 查看pv和pvc
[root@master01 ~/volumes]# kubectl get pv,pvc
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
persistentvolume/pv-01 10Gi RWX Retain Bound default/pvc-01 47m
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc-01 Bound pv-01 10Gi RWX 20m
# 重新創建
[root@master01 ~/volumes]# kubectl apply -f pod-mysql.yaml
pod/pod-pvc created
進入新創建的pod內查看庫是否存在
# 進入容器
[root@master01 ~/volumes]# kubectl exec -it pod-pvc -- /bin/bash
# 連接數據庫
root@pod-pvc:/# mysql -uroot -proot123
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.26 MySQL Community Server - GPL
Copyright (c) 2000, 2021, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
# 查看數據
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| testdb |
+--------------------+
5 rows in set (0.00 sec)
測試刪除Pod和PVC之后,PV的數據是否還存在
經過驗證,數據依舊存在
# 刪除pod和pvc
[root@master01 ~/volumes]# kubectl delete po pod-pvc
pod "pod-pvc" deleted
[root@master01 ~/volumes]# kubectl delete pvc pvc-01
persistentvolumeclaim "pvc-01" deleted
# 查看pv,狀態為Released
[root@master01 ~/volumes]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-01 10Gi RWX Retain Released default/pvc-01 50m
# 查看數據是否存在
[root@master01 ~/volumes]# ll /data/nfs/nginx/pv-01/
total 185784
-rw-r----- 1 999 999 196608 May 11 14:54 '#ib_16384_0.dblwr'
-rw-r----- 1 999 999 8585216 May 11 14:45 '#ib_16384_1.dblwr'
drwxr-x--- 2 999 999 4096 May 11 14:55 '#innodb_temp'/
drwxr-xr-x 7 999 root 4096 May 11 14:55 ./
drwxr-xr-x 4 root root 4096 May 11 14:44 ../
-rw-r----- 1 999 999 56 May 11 14:45 auto.cnf
-rw-r----- 1 999 999 3117023 May 11 14:45 binlog.000001
-rw-r----- 1 999 999 370 May 11 14:52 binlog.000002
-rw-r----- 1 999 999 179 May 11 14:55 binlog.000003
-rw-r----- 1 999 999 48 May 11 14:52 binlog.index
-rw------- 1 999 999 1680 May 11 14:45 ca-key.pem
-rw-r--r-- 1 999 999 1112 May 11 14:45 ca.pem
-rw-r--r-- 1 999 999 1112 May 11 14:45 client-cert.pem
-rw------- 1 999 999 1680 May 11 14:45 client-key.pem
-rw-r----- 1 999 999 3482 May 11 14:55 ib_buffer_pool
-rw-r----- 1 999 999 50331648 May 11 14:54 ib_logfile0
-rw-r----- 1 999 999 50331648 May 11 14:45 ib_logfile1
-rw-r----- 1 999 999 12582912 May 11 14:55 ibdata1
drwxr-x--- 2 999 999 4096 May 11 14:45 mysql/
-rw-r----- 1 999 999 31457280 May 11 14:52 mysql.ibd
drwxr-x--- 2 999 999 4096 May 11 14:45 performance_schema/
-rw------- 1 999 999 1676 May 11 14:45 private_key.pem
-rw-r--r-- 1 999 999 452 May 11 14:45 public_key.pem
-rw-r--r-- 1 999 999 1112 May 11 14:45 server-cert.pem
-rw------- 1 999 999 1680 May 11 14:45 server-key.pem
drwxr-x--- 2 999 999 4096 May 11 14:45 sys/
drwxr-x--- 2 999 999 4096 May 11 14:49 testdb/
-rw-r----- 1 999 999 16777216 May 11 14:54 undo_001
-rw-r----- 1 999 999 16777216 May 11 14:54 undo_002
PVC和PV的綁定機制
PVC 與 PV 的綁定遵循以下規則:
- 訪問模式匹配:PVC 的accessModes必須是 PV 支持的子集(如 PV 支持 RWX,PVC 可請求 RWO 或 RWX)。
- 容量匹配:PV 的容量必須≥PVC 請求的容量。
- 存儲類匹配:
- 若 PVC 指定storageClassName,則僅匹配相同 StorageClass 的 PV。
- 若 PVC 未指定storageClassName,則僅匹配未關聯任何 StorageClass的 PV。
- 標簽選擇器匹配:若 PVC 使用selector,則 PV 必須包含所有指定標簽。
綁定狀態:
- Bound:已成功綁定 PV。
- Pending:未找到匹配的 PV(需等待或手動創建)。
- Lost:綁定的 PV 已消失(如被管理員刪除)。
SC詳解
SC(StorageClass)是存儲類的意思,Kubernetes 可以根據 StorageClass 的定義動態地創建持久化存儲卷(PersistentVolume, PV)和持久化卷聲明(PersistentVolumeClaim, PVC)。StorageClass 提供了一種抽象層,允許用戶在不關心底層存儲實現細節的情況下請求存儲資源。
SC的核心作用
-
動態存儲供給
傳統靜態供給需要管理員手動創建 PV(PersistentVolume),而 StorageClass 支持動態供給:當用戶創建 PVC(PersistentVolumeClaim)時,Kubernetes 會根據 PVC 指定的 StorageClass 自動創建對應的 PV,無需手動預定義。 -
存儲類型分類
可定義多種 StorageClass(如 fast、slow、ssd、hdd),每種類型對應不同的存儲參數(如存儲介質、性能、備份策略等),滿足不同業務需求。 -
靈活配置 Provisioner
通過關聯存儲插件(Provisioner),支持對接多種后端存儲(如 AWS EBS、NFS、Ceph、GlusterFS 等),實現對不同存儲系統的統一管理。
資源清單文件詳解
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard # StorageClass 名稱,PVC 通過此名稱引用
provisioner: kubernetes.io/aws-ebs # 存儲插件(Provisioner)
parameters: # 存儲插件專屬參數
type: gp2 # 例如 AWS EBS 的卷類型(gp2、io1 等)
reclaimPolicy: Delete # 回收策略(Delete 或 Retain,默認 Delete)
volumeBindingMode: Immediate # 卷綁定模式(Immediate 或 WaitForFirstConsumer,默認 Immediate)
allowVolumeExpansion: true #允許卷擴容
mountOptions: # 掛載選項(可選)
- debug
核心字段說明
provisioner(必選)
指定負責創建 PV 的存儲插件,通常格式為 廠商名稱.插件類型,例如:
- kubernetes.io/aws-ebs(AWS EBS 卷)
- nfs-client.provisioner(NFS 客戶端插件)
- local.csi.k8s.io(本地存儲 CSI 插件)
parameters(可選)
傳遞給 Provisioner 的參數,不同插件參數不同,例如:
- NFS 插件:server=10.0.0.10, share=/nfs/share
- AWS EBS 插件:type=io1, iopsPerGB=10
reclaimPolicy(可選,默認 Delete)
當 PVC 被刪除時,PV 的處理策略:
- Delete:自動刪除 PV 及后端存儲資源(如 EBS 卷)。
- Retain:保留 PV 及數據,需手動清理(適用于需要數據持久化的場景)。
volumeBindingMode(可選,默認 Immediate)
控制 PV 與節點的綁定時機:
- Immediate:立即綁定,適用于不需要節點親和性的場景。
- WaitForFirstConsumer:延遲綁定,直到 Pod 調度時才綁定 PV,支持結合節點親和性選擇存儲位置(如本地存儲需綁定到特定節點)。
配置以NFS為存儲的SC插件
K8s原生組件并不支持NFS動態存儲,所以需要一些額外的配置
K8s官網:https://kubernetes.io/zh-cn/docs/concepts/storage/storage-classes/#nfs
項目官網:https://github.com/kubernetes-csi/csi-driver-nfs#readme
我這里使用kubectl進行安裝:
參考:https://github.com/kubernetes-csi/csi-driver-nfs/blob/master/docs/install-csi-driver-master.md
實操:
[root@master01 ~]# wget https://github.com/kubernetes-csi/csi-driver-nfs/archive/refs/tags/v4.11.0.tar.gz
[root@master01 ~]# tar -xvf csi-driver-nfs-4.11.0.tar.gz
[root@master01 ~]# cd csi-driver-nfs-4.11.0
# 修改鏡像源,防止鏡像拉不下來
[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# sed -i s#registry.k8s.io#k8s.m.daocloud.io#g v4.11.0/csi-nfs-controller.yaml
[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# sed -i s#registry.k8s.io#k8s.m.daocloud.io#g v4.11.0/csi-snapshot-controller.yaml
[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# sed -i s#registry.k8s.io#k8s.m.daocloud.io#g v4.11.0/csi-nfs-node.yaml
# 執行安裝,注意腳本后面添加參數
[root@master01 ~/csi-driver-nfs-4.11.0/deploy]# ./install-driver.sh master v4.11.0
Installing NFS CSI driver, version: master ...
serviceaccount/csi-nfs-controller-sa created
serviceaccount/csi-nfs-node-sa created
clusterrole.rbac.authorization.k8s.io/nfs-external-provisioner-role created
clusterrolebinding.rbac.authorization.k8s.io/nfs-csi-provisioner-binding created
clusterrole.rbac.authorization.k8s.io/nfs-external-resizer-role created
clusterrolebinding.rbac.authorization.k8s.io/nfs-csi-resizer-role created
csidriver.storage.k8s.io/nfs.csi.k8s.io created
deployment.apps/csi-nfs-controller created
daemonset.apps/csi-nfs-node created
NFS CSI driver installed successfully.
# 檢查一下pod是否啟動Running
[root@master01 ~/csi-driver-nfs-4.11.0]# kubectl -n kube-system get pod -o wide -l app=csi-nfs-node
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
csi-nfs-node-4w6fg 3/3 Running 0 89s 10.0.0.32 node02 <none> <none>
csi-nfs-node-jhsf2 3/3 Running 0 89s 10.0.0.31 node01 <none> <none>
csi-nfs-node-sbp76 3/3 Running 0 89s 10.0.0.30 master01 <none> <none>
[root@master01 ~/csi-driver-nfs-4.11.0]# kubectl -n kube-system get pod -o wide -l app=csi-nfs-controller
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
csi-nfs-controller-6d4bb5ddbc-fgmq6 5/5 Running 1 (41s ago) 105s 10.0.0.30 master01 <none> <none>
創建SC實戰
[root@master01 ~/volumes]# cat sc-01.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sc-01 # StorageClass名稱,PVC通過該名稱引用此存儲類
provisioner: nfs.csi.k8s.io # 指定使用NFS CSI驅動作為存儲供給器
parameters: # 傳遞給NFS CSI驅動的參數
server: 10.0.0.30 # NFS服務器的IP地址
share: /data/nfs/nginx/sc-01 # NFS服務器上的共享目錄路徑
# csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume
# csi.storage.k8s.io/provisioner-secret-name: "mount-options"
# csi.storage.k8s.io/provisioner-secret-namespace: "default"
reclaimPolicy: Retain # 回收策略:當PVC被刪除時,PV保留不刪除
volumeBindingMode: Immediate # 卷綁定模式:立即綁定,不需要等待Pod調度
allowVolumeExpansion: true # 允許卷擴容:支持通過修改PVC請求更大容量
# 創建sc
[root@master01 ~/volumes]# kubectl apply -f sc-01.yaml
storageclass.storage.k8s.io/sc-01 created
# 查看sc
[root@master01 ~/volumes]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
sc-01 nfs.csi.k8s.io Retain Immediate true 5s
創建PVC關聯SC
# 定義資源文件
[root@master01 ~/volumes]# cat pvc-sc-01.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-sc-01
spec:
accessModes:
- ReadWriteMany
# 指定sc的名稱進行關聯
storageClassName: sc-01
resources:
requests:
storage: 5Gi
# 創建sc
[root@master01 ~/volumes]# kubectl apply -f pvc-sc-01.yaml
persistentvolumeclaim/pvc-sc-01 unchanged
# 查看pvc和sc
[root@master01 ~/volumes]# kubectl get pvc,sc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc-sc-01 Bound pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d 5Gi RWX sc-01 28s
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storageclass.storage.k8s.io/sc-01 nfs.csi.k8s.io Retain Immediate true 6m4s
創建Pod關聯PVC使用SC
示例:
#定義資源文件
[root@master01 ~/volumes]# cat pod-sc.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-sc
spec:
volumes:
- name: data
# 指定存儲類型為PVC
persistentVolumeClaim:
# 指定PVC的名稱
claimName: pvc-sc-01
# 是否只讀,默認值為false,代表可讀寫
readOnly: false
containers:
- name: mysql
image: mysql:8.0.26
env:
- name: "MYSQL_ROOT_PASSWORD"
value: "root123"
# 掛載存儲卷
volumeMounts:
# 指定存儲卷的名稱
- name: data
mountPath: /var/lib/mysql
# 創建pod
[root@master01 ~/volumes]# kubectl apply -f pod-sc.yaml
pod/pod-sc created
查看掛載的路徑
[root@master01 ~]# cd /data/nfs/nginx/sc-01/
# pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d/的名稱和PVC的VOLUME字段對應
[root@master01 /data/nfs/nginx/sc-01]# ll
total 12
drwxr-xr-x 3 root root 4096 May 11 16:03 ./
drwxr-xr-x 5 root root 4096 May 11 15:57 ../
drwxr-xr-x 6 999 root 4096 May 11 16:07 pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d/
[root@master01 /data/nfs/nginx/sc-01]# ll pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d/
total 198068
-rw-r----- 1 999 999 196608 May 11 16:07 '#ib_16384_0.dblwr'
-rw-r----- 1 999 999 8585216 May 11 16:07 '#ib_16384_1.dblwr'
drwxr-x--- 2 999 999 4096 May 11 16:07 '#innodb_temp'/
drwxr-xr-x 6 999 root 4096 May 11 16:07 ./
drwxr-xr-x 3 root root 4096 May 11 16:03 ../
-rw-r----- 1 999 999 56 May 11 16:07 auto.cnf
-rw-r----- 1 999 999 3117023 May 11 16:07 binlog.000001
-rw-r----- 1 999 999 156 May 11 16:07 binlog.000002
-rw-r----- 1 999 999 32 May 11 16:07 binlog.index
-rw------- 1 999 999 1680 May 11 16:07 ca-key.pem
-rw-r--r-- 1 999 999 1112 May 11 16:07 ca.pem
-rw-r--r-- 1 999 999 1112 May 11 16:07 client-cert.pem
-rw------- 1 999 999 1680 May 11 16:07 client-key.pem
-rw-r----- 1 999 999 5721 May 11 16:07 ib_buffer_pool
-rw-r----- 1 999 999 50331648 May 11 16:07 ib_logfile0
-rw-r----- 1 999 999 50331648 May 11 16:07 ib_logfile1
-rw-r----- 1 999 999 12582912 May 11 16:07 ibdata1
-rw-r----- 1 999 999 12582912 May 11 16:08 ibtmp1
drwxr-x--- 2 999 999 4096 May 11 16:07 mysql/
-rw-r----- 1 999 999 31457280 May 11 16:07 mysql.ibd
drwxr-x--- 2 999 999 4096 May 11 16:07 performance_schema/
-rw------- 1 999 999 1680 May 11 16:07 private_key.pem
-rw-r--r-- 1 999 999 452 May 11 16:07 public_key.pem
-rw-r--r-- 1 999 999 1112 May 11 16:07 server-cert.pem
-rw------- 1 999 999 1680 May 11 16:07 server-key.pem
drwxr-x--- 2 999 999 4096 May 11 16:07 sys/
-rw-r----- 1 999 999 16777216 May 11 16:07 undo_001
-rw-r----- 1 999 999 16777216 May 11 16:07 undo_002
配置默認的SC
默認的 SC(StorageClass) 是指當創建 PVC(PersistentVolumeClaim) 時未顯式指定 storageClassName 時,系統自動使用的 StorageClass。以下是關于默認 SC 的配置和相關說明:
在 Kubernetes 集群中,默認 StorageClass(SC)的數量是0 個或 1 個。Kubernetes 不強制要求必須有默認 SC,但如果存在,只能有一個被標記為默認
創建默認的SC
默認 SC 通過 metadata.annotations 中的 storageclass.kubernetes.io/is-default-class: "true" 標記
示例
# 定義資源清單文件
[root@master01 ~/volumes]# cat sc-default.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
# StorageClass名稱,PVC通過該名稱引用此存儲類
name: sc-default
annotations:
# 標記為默認存儲類
storageclass.kubernetes.io/is-default-class: "true"
# 指定使用NFS CSI驅動作為存儲供給器
provisioner: nfs.csi.k8s.io
# 傳遞給NFS CSI驅動的參數
parameters:
# NFS服務器的IP地址
server: 10.0.0.30
# NFS服務器上的共享目錄路徑
share: /data/nfs/nginx/sc-default
# csi.storage.k8s.io/provisioner-secret is only needed for providing mountOptions in DeleteVolume
# csi.storage.k8s.io/provisioner-secret-name: "mount-options"
# csi.storage.k8s.io/provisioner-secret-namespace: "default"
# 回收策略:當PVC被刪除時,PV保留不刪除
reclaimPolicy: Retain
# 卷綁定模式:立即綁定,不需要等待Pod調度
volumeBindingMode: Immediate
# 允許卷擴容:支持通過修改PVC請求更大容量
allowVolumeExpansion: true
# 創建sc
[root@master01 ~/volumes]# kubectl apply -f sc-default.yaml
storageclass.storage.k8s.io/sc-default created
# 查看sc
[root@master01 ~/volumes]# kubectl get sc
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
sc-01 nfs.csi.k8s.io Retain Immediate true 20m
# 默認存儲類
sc-default (default) nfs.csi.k8s.io Retain Immediate true 3s
創建PVC關聯默認的SC
# 定義資源清單文件
[root@master01 ~/volumes]# cat pvc-sc-02.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-sc-02
spec:
accessModes:
- ReadWriteMany
# 這里不指定sc的名稱,使用默認的SC
# storageClassName: sc-default
resources:
requests:
storage: 5Gi
# 創建pvc
[root@master01 ~/volumes]# kubectl apply -f pvc-sc-02.yaml
persistentvolumeclaim/pvc-sc-02 created
# 查看pvc和sc,發現都綁定成功了
[root@master01 ~/volumes]# kubectl get pvc,sc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
persistentvolumeclaim/pvc-sc-01 Bound pvc-4ed0c30c-6827-4498-bd53-bff5accbd47d 5Gi RWX sc-01 19m
persistentvolumeclaim/pvc-sc-02 Bound pvc-ae0b0c76-7c00-4986-b589-aa62ff9472fa 5Gi RWX sc-default 2m20s
NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE
storageclass.storage.k8s.io/sc-01 nfs.csi.k8s.io Retain Immediate true 25m
storageclass.storage.k8s.io/sc-default (default) nfs.csi.k8s.io Retain Immediate true 3m36s
創建Pod關聯PVC使用SC(省略,自行測試)
本文來自博客園,作者:huangSir-devops,轉載請注明原文鏈接:http://www.rzrgm.cn/huangSir-devops/p/18871414,微信Vac666666,歡迎交流

浙公網安備 33010602011771號