Kubernetes中存儲中有四個重要的概念:
Volume、PersistentVolume PV、PersistentVolumeClaim PVC、StorageClass
一、存儲系統核心概念
Volume(卷)
定義:Kubernetes 中最基礎的存儲單元,用于將外部存儲掛載到 Pod 中的容器。
特點:
生命周期與 Pod 綁定(Pod 刪除則 Volume 銷毀,但部分類型如 PV 可持久化)。
支持多種存儲類型:本地存儲(
emptyDir
、hostPath
)、網絡存儲(NFS、CephFS)、云存儲(AWS EBS、GCE PD)等。
典型用法:
yaml
volumes: # 定義存儲類型 - name: datahostPath:path: /mnt/data volumeMounts: # 掛載到容器路徑 - name: datamountPath: /app/data
PersistentVolume(PV,持久卷)
定義:集群級別的存儲資源(如一塊云磁盤、一個 Ceph RBD 鏡像),由管理員預先創建。
核心屬性:
capacity
:存儲容量(如 10Gi)。accessModes
:訪問模式(單節點讀寫?ReadWriteOnce
、多節點只讀?ReadOnlyMany
、多節點讀寫?ReadWriteMany
)。persistentVolumeReclaimPolicy
:回收策略(保留 Retain、刪除 Delete)。
示例:
yaml
apiVersion: v1 kind: PersistentVolume metadata:name: ceph-pv spec:capacity: { storage: 10Gi }accessModes: [ReadWriteOnce]cephfs:monitors: ["ceph-mon:6789"]path: /datastorageClassName: ceph-storage
PersistentVolumeClaim(PVC,持久卷聲明)
定義:用戶對存儲資源的“需求清單”,聲明所需的存儲大小、訪問模式等,由 Kubernetes 自動綁定到匹配的 PV。
核心屬性:
resources.requests.storage
:請求的存儲大小(如 5Gi)。storageClassName
:指定動態供給的存儲類型。
示例:
yaml
kind: PersistentVolumeClaim apiVersion: v1 metadata:name: app-data-pvc spec:accessModes: [ReadWriteOnce]resources:requests:storage: 5GistorageClassName: ceph-storage
StorageClass(存儲類)
定義:動態供給的模板,定義如何按需創建 PV(例如自動創建云盤或 Ceph RBD 鏡像)。
核心屬性:
provisioner
:存儲驅動(如?kubernetes.io/aws-ebs
)。parameters
:存儲后端參數(如 Ceph 集群地址)。
示例:
yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: ceph-rbd provisioner: kubernetes.io/rbd parameters:monitors: ceph-mon:6789adminId: adminpool: kube
1、工作流程對比
? ? ? 靜態供給:
管理員創建PV → 用戶創建PVC → 系統綁定PV/PVC → Pod使用PVC
? ? ? 動態供給:
用戶創建PVC → StorageClass自動創建PV → 系統綁定 → Pod使用PVC
二、核心流程對比
靜態 PV 工作流程
步驟:
管理員創建 PV(如 Ceph RBD 鏡像)。
用戶創建 PVC,聲明存儲需求。
Kubernetes 將 PVC 綁定到匹配的 PV。
Pod 掛載 PVC。
痛點:需人工維護大量 PV,存儲擴容需手動操作。
動態 PV 工作流程
步驟:
管理員創建 StorageClass(定義存儲類型)。
用戶創建 PVC,指定 StorageClass。
Kubernetes 自動創建 PV 并綁定 PVC。
Pod 掛載 PVC。
優勢:自動化創建存儲資源,適合云環境彈性需求。
如果還不清晰,這里用租房子的比喻來解釋這四個概念和兩種供給模式,再配上實際流程,保證通俗易懂。
三、核心概念和流程比喻(通俗版):
想象你要租房子(需要存儲空間):
Volume (卷):?就像你最終拿到手的房子鑰匙和門牌號。它定義了具體的存儲位置(地址)和如何掛載到你的應用(Pod)里使用(鑰匙)。Volume 是 Pod 的一部分配置。
PersistentVolume (PV, 持久卷):?就像城市里可出租的實體房子資源。這些房子是由物業公司(集群管理員)提前建好(配置好)并登記在冊的。每套房子(PV)有明確的屬性:
大小?(capacity): 比如 80 平米(100Gi)。
訪問規則?(accessModes): 是只能一個人住(單節點讀寫?
ReadWriteOnce
),還是可以很多人參觀但不能住(多節點只讀?ReadOnlyMany
),或者可以合租(多節點讀寫?ReadWriteMany
)。地段/特性?(storageClassName): 屬于哪個小區、是公寓還是別墅(存儲類型,比如?
fast-ssd
,?ceph-rbd
)。退租處理?(persistentVolumeReclaimPolicy): 租客退租后,房子是保留原樣等人再租(
Retain
),還是清空重新裝修(舊模式?Recycle
,已基本不用),或是直接拆掉(Delete
)。
PersistentVolumeClaim (PVC, 持久卷聲明):?就像你提交給租房中介的一份租房需求清單。你告訴中介(Kubernetes 系統):
我要多大?(resources.requests.storage): 至少 60 平米(5Gi)。
我要怎么用?(accessModes): 我一個人住要能做飯洗澡(
ReadWriteOnce
)。我想租哪種類型?(storageClassName): 我想要交通方便的公寓(比如?
fast-ssd
)。
StorageClass (SC, 存儲類):?就像一個高效的房屋建造和管理中介公司。它定義了:
我們能提供什么類型的房子?(provisioner): 比如“快速公寓建造公司”(
kubernetes.io/aws-ebs
,?kubernetes.io/gce-pd
,?rbd.csi.ceph.com
)。房子的默認配置?(parameters): 比如默認精裝修、帶電梯(存儲后端的具體參數,如 Ceph 集群地址、池名)。
我們的服務規則: 比如先簽合同再建房(
WaitForFirstConsumer
,等 Pod 調度好再創建 PV),或者有現房(立即創建)。
它們之間的關系:
PVC 綁定 PV:?你的租房需求清單 (PVC) 會被中介 (Kubernetes) 拿去匹配現成的房子 (PV)。如果找到大小、類型、訪問規則都滿足的房子,就把這套房子分配給你(綁定)。Pod 不能直接租房子 (PV),必須通過你的需求清單 (PVC) 來租。
SC 動態創建 PV:?如果中介 (Kubernetes) 發現沒有現成的房子 (PV) 能滿足你的需求清單 (PVC),并且你的清單里指定了要找某個房屋建造中介公司 (StorageClass),那么中介公司 (SC) 就會立刻根據你的需求清單 (PVC) 自動建造一套新房子 (PV),然后中介 (Kubernetes) 再把這套新房分配給你 (綁定 PVC 和 PV)。
Pod 使用 Volume:?當你 (Pod) 要入住時,中介 (Kubernetes) 會告訴你具體的門牌號和給你鑰匙 (Volume)。你 (Pod) 在配置里寫明“我要用清單A對應的房子” (引用 PVC 名字),系統就會自動把對應的門牌號和鑰匙 (Volume) 配置給你,你就可以搬進去住(把存儲掛載到容器里指定路徑)了。
靜態供給流程 (管理員提前造好房子):
管理員造房 (創建 PV):?集群管理員像物業公司,提前在存儲后端(如 NFS 服務器、Ceph 集群)準備好“房子”(存儲空間),并在 Kubernetes 里創建?
PersistentVolume
?(PV) 對象來描述這些房子(大小、訪問模式、地址等)。例子:?管理員在 Ceph 里創建了一個 100GB 的 RBD 鏡像?
image-db
,然后創建 PV:yaml
apiVersion: v1 kind: PersistentVolume metadata:name: pv-ceph-db-100g # 房子名字:Ceph數據庫房100G spec:capacity:storage: 100Gi # 大小:100平米accessModes:- ReadWriteOnce # 訪問規則:單租客可讀寫cephfs: # 或者 rbd: 取決于類型monitors:- 10.0.0.1:6789 # Ceph 監控地址path: /data/db # 具體路徑 / 池和鏡像名user: adminsecretRef:name: ceph-secretpersistentVolumeReclaimPolicy: Retain # 退租處理:保留原樣storageClassName: ceph-slow # 地段/類型:Ceph普通盤區
用戶提交需求 (創建 PVC):?開發者(用戶)編寫應用部署文件 (如?
deployment.yaml
),在里面聲明需要一個?PersistentVolumeClaim
?(PVC)。例子:?應用需要 80GB 數據庫存儲,單節點讀寫。
yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata:name: pvc-mysql-data # 我的需求清單名字:MySQL數據需求 spec:accessModes:- ReadWriteOnce # 我要單租客可讀寫resources:requests:storage: 80Gi # 我要至少80平米storageClassName: ceph-slow # 我想租Ceph普通盤區的房子 (可選,如果指定必須匹配PV的class)
系統匹配房源 (綁定 PV & PVC):?Kubernetes 系統(中介)看到 PVC 需求后,在現成的 PV(房子)里找:
大小滿足:PVC 要 80Gi,PV 有 100Gi (80 <= 100,滿足)。
訪問模式匹配:都是?
ReadWriteOnce
。存儲類匹配:如果 PVC 指定了?
ceph-slow
,PV 也必須是?ceph-slow
;如果 PVC 沒指定,則匹配沒有存儲類或任意存儲類的 PV(但通常建議明確指定)。找到后,系統將 PV 和 PVC?綁定 (Bound)。PV 的狀態從?
Available
?變成?Bound
。
用戶入住 (Pod 掛載 Volume):?用戶創建 Pod(比如 MySQL 數據庫 Pod)。在 Pod 的配置里:
聲明要使用哪個 PVC (
pvc-mysql-data
)。指定把存儲掛載到容器里的哪個路徑 (
/var/lib/mysql
)。
yaml
apiVersion: v1 kind: Pod metadata:name: mysql-pod spec:containers:- name: mysqlimage: mysql:8.0volumeMounts:- name: mysql-storage # 給這個掛載起個名字mountPath: /var/lib/mysql # 容器內的掛載點volumes:- name: mysql-storage # 上面掛載名字對應的存儲定義persistentVolumeClaim:claimName: pvc-mysql-data # 使用之前申請的PVC
Pod 運行:?Kubernetes 調度 Pod 到某個 Node 上運行。該 Node 上的 kubelet 組件負責:
根據 PVC 找到已綁定的 PV。
根據 PV 的描述(如 Ceph RBD),聯系對應的存儲系統(Ceph 集群),獲取訪問權限(掛載)。
將存儲掛載到 Node 上的一個臨時目錄。
將這個臨時目錄映射(掛載)到 Pod 中容器指定的路徑 (
/var/lib/mysql
)。應用啟動,讀寫?
/var/lib/mysql
?就是在讀寫持久化的 Ceph 存儲。
動態供給流程 (中介按需快速建新房):
管理員找中介公司 (創建 StorageClass):?集群管理員提前創建一個或多個?
StorageClass
?(SC) 對象。這相當于引入了幾家不同風格的房屋建造中介公司,每家公司專長不同(AWS EBS, GCP PD, Ceph RBD, NFS Provisioner 等)。例子:?創建一個負責快速建造 Ceph RBD “公寓”的中介公司:
yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:name: ceph-rbd-fast # 中介公司名:Ceph快速公寓建造 provisioner: rbd.csi.ceph.com # 建造公司類型:Ceph RBD CSI 驅動 (現代標準) parameters: # 建造公司的默認配置clusterID: my-ceph-cluster # Ceph集群IDpool: kube-pool-fast # 用哪個池建房imageFeatures: layering,exclusive-lock # 房子特性csi.storage.k8s.io/provisioner-secret-name: ceph-csi-secretcsi.storage.k8s.io/provisioner-secret-namespace: kube-system reclaimPolicy: Delete # 默認退租處理:拆掉房子 (可選 Retain) volumeBindingMode: WaitForFirstConsumer # 服務規則:等租客確定住哪再建房 (避免建錯位置)
用戶提交需求 (創建 PVC 并指定 SC):?開發者(用戶)編寫 PVC,這次明確指定要找哪家中介公司 (StorageClass) 來滿足需求。
例子:?應用需要 200GB 高速數據庫存儲,單節點讀寫,找?
ceph-rbd-fast
?公司建房。yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata:name: pvc-mongodb-data # 需求清單:MongoDB數據 spec:accessModes:- ReadWriteOnceresources:requests:storage: 200Gi # 要200平米storageClassName: ceph-rbd-fast # 必須指定:找Ceph快速公寓建造公司!
中介公司立刻建房 (動態創建 PV):?Kubernetes 系統(平臺)看到 PVC 指定了?
ceph-rbd-fast
?這個 StorageClass。系統會調用?
ceph-rbd-fast
?這個 SC 里定義的?provisioner
?(Ceph RBD CSI 驅動)。CSI 驅動收到指令:“按 PVC 要求(200Gi, RWO)建一套新房!”
CSI 驅動聯系 Ceph 集群后端:
在指定的?
kube-pool-fast
?池里創建一個新的 RBD 鏡像 (image),大小 200GB。在 Kubernetes 里自動創建一個對應的?
PersistentVolume
?(PV) 對象來描述這個新建的 RBD 鏡像。
新建的 PV 的?
storageClassName
?自動設置為?ceph-rbd-fast
。系統自動將這個新建的 PV 與發起請求的 PVC 綁定 (Bound)。PVC 的狀態直接變成?
Bound
。
用戶入住 (Pod 掛載 Volume):?和靜態流程完全一樣!用戶創建 Pod,聲明使用 PVC?
pvc-mongodb-data
,并指定容器內的掛載點。Kubernetes 調度 Pod 并完成掛載。
核心區別總結:
特性 | 靜態供給 (Static Provisioning) | 動態供給 (Dynamic Provisioning) |
---|---|---|
PV 創建者 | 管理員手動創建 | StorageClass (通過 Provisioner) 自動創建 |
創建時機 | 在 PVC 出現之前?預先創建好 PV | 在 PVC 出現之后,響應 PVC 請求即時創建 PV |
運維負擔 | 高。管理員需預估需求,提前創建、管理大量 PV。 | 低。管理員只需配置好 StorageClass,PV 按需創建。 |
靈活性 | 低。擴容麻煩(需手動操作 PV 和存儲后端)。 | 高。PVC 修改大小可能觸發自動擴容(需存儲后端和 SC 支持)。 |
適用場景 | 存儲需求固定、明確;特殊存儲配置;不支持動態供給的存儲。 | 云環境、容器化平臺主流方式;存儲需求彈性大;追求自動化。 |
關鍵組件 | PV, PVC | StorageClass, PVC, (自動創建的 PV) |
比喻 | 管理員提前建好一批毛坯房/精裝房放在市場上。 | 引入中介公司,用戶提交需求單,中介按需快速建好精裝房交付。 |
為什么動態供給是趨勢?
自動化:?省去了管理員手動管理 PV 的巨大工作量。
按需分配:?避免資源閑置浪費(靜態供給往往需要預先分配較大的 PV)。
敏捷性:?開發者只需關心 PVC 需求,無需等待管理員操作,加速應用部署。
云原生:?完美契合 Kubernetes 聲明式 API 和彈性伸縮的理念。
作為小白,記住關鍵點:
Pod 用 Volume 訪問存儲。
持久化存儲要用 PV 和 PVC。
PV 是“房子”,PVC 是“租房需求單”。
靜態供給:管理員提前造好 PV (房子) 等 PVC (需求單) 來租。
動態供給:PVC (需求單) 指定 StorageClass (中介公司),中介公司立刻造好 PV (房子) 并租給你。
生產環境強烈推薦用動態供給!