目錄
一、 Volume 的概念
二、 Volume 的類型
三、 通過 emptyDir 共享數據
1. EmptyDir 特性
2. EmptyDir 共享數據
四:使用 HostPath 掛載宿主機文件
1.??HostPath 特性
2.?掛載宿主機時區文件
五、?掛載 NFS 至容器
1.?前置準備(所有 K8s 節點 + NFS 服務器)
六、PersistentVolume(PV,持久卷)
1. 引入背景
2. 核心特性
3. 回收策略
4. 訪問策略
5. 靜態配置實踐
七、PersistentVolumeClaim(PVC,持久卷聲明)
1.??核心作用
2.?PVC 配置與綁定
3.?PVC 掛載到 Pod
一、 Volume 的概念
對于大多數項目而言,數據文件存儲是常見需求(如用戶頭像、文件、數據庫數據)。在 Kubernetes 中,應用部署的高擴展性和編排性,決定了容器內存儲數據不可取(無法保障安全)。
應將有狀態應用剝離為無狀態:數據從應用中分離,存儲到云端(如分布式存儲、公有云 NAS 服務)。常見方案:
- NFS(生產不建議,單點故障);
- Ceph、GlusterFS、Minio 等分布式存儲。
傳統架構中,存儲需提前在宿主機掛載,新增節點易忘掛載引發問題。Kubernetes 抽象出?Volume 概念,解決數據存儲難題。
二、 Volume 的類型
Kubernetes 支持多種 Volume 類型:
- 通用類型:
RBD
、HostPath
?等;- 獨有類型:
ConfigMap
:存儲配置文件;Secret
:存儲敏感數據;EmptyDir
:同 Pod 內多容器共享數據;PersistentVolumeClaim
:申請 PersistentVolume。
三、 通過 emptyDir 共享數據
1. EmptyDir 特性
- 特殊 Volume:Pod 刪除時,EmptyDir 數據也刪除;
- 場景:同 Pod 內容器共享數據(如 Filebeat 收集容器日志)。
2. EmptyDir 共享數據
(1)?編寫 Deployment 文件
[root@k8s-master ~]# cat <<EOF>nginx-empty.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: nginxname: nginxnamespace: default spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx01volumeMounts: # 容器1掛載:/opt → share-volume- mountPath: /optname: share-volume- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginx02command: ["sh", "-c", "sleep 3600"] # 保持容器運行volumeMounts: # 容器2掛載:/mnt → share-volume- mountPath: /mntname: share-volumevolumes: # 定義共享卷:share-volume 類型為 emptyDir- name: share-volumeemptyDir: {} # 可添加 medium: Memory 使用 tmpfs(內存存儲,節點重啟數據清除) EOF
(2)?部署與驗證
- 部署:
kubectl create -f nginx-empty.yaml
- 查看 Pod:
kubectl get pod
(示例:nginx-6fffbd7c7b-jrw7f 2/2 Running
)
容器 1 寫入數據:
kubectl exec -ti <pod-name> -c nginx01 -- sh # 在 /opt 創建文件(如 touch /opt/test.txt)
容器 2 驗證共享:
kubectl exec -ti <pod-name> -c nginx02 -- sh # 查看 /mnt 下是否有 test.txt
- 刪除 Pod:
kubectl delete -f nginx-empty.yaml
四:使用 HostPath 掛載宿主機文件
1.??HostPath 特性
將宿主機文件 / 目錄掛載到 Pod,實現 Pod 與宿主機數據共享(如掛載時區文件解決容器時間偏差)。
2.?掛載宿主機時區文件
(1)?編寫 Deployment 文件
[root@k8s-master ~]# cat <<EOF>nginx-hostPath.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: nginxname: nginxnamespace: default spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxvolumeMounts: # 容器內掛載:/etc/localtime → timezone-time- mountPath: /etc/localtimename: timezone-timevolumes: # 定義 HostPath 卷:掛載宿主機 /etc/localtime- name: timezone-timehostPath:path: /etc/localtime # 宿主機路徑type: file # 類型:文件必須存在 EOF
(2)?部署與驗證
- 部署:
kubectl create -f nginx-hostPath.yaml
驗證時間:
kubectl exec -ti <pod-name> -c nginx -- sh date # 檢查時區是否為 Asia/Shanghai
HostPath 類型說明:
類型 | 說明 |
---|---|
DirectoryOrCreate | 路徑不存在則創建空目錄(權限 0755) |
Directory | 路徑必須是已存在的目錄 |
FileOrCreate | 路徑不存在則創建空文件(權限 0644) |
File | 路徑必須是已存在的文件 |
Socket /CharDevice /BlockDevice | 對應類型的設備必須存在 |
五、?掛載 NFS 至容器
1.?前置準備(所有 K8s 節點 + NFS 服務器)
- 安裝 NFS 工具:
yum -y install nfs-utils
(所有節點);
NFS 服務器配置:
# 創建共享目錄 mkdir /opt/wwwroot && echo "NFS Test" > /opt/wwwroot/index.html # 配置共享規則(/etc/exports) echo "/opt/wwwroot 192.168.10.0/24(rw,sync,no_root_squash)" >> /etc/exports # 啟動服務 systemctl start nfs && systemctl start rpcbind
2.??編寫 Deployment 文件(掛載 NFS)
[root@k8s-master ~]# cat <<EOF>nginx-nfsVolume.yaml apiVersion: apps/v1 kind: Deployment metadata:labels:app: nginxname: nginxnamespace: default spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- image: nginx:1.7.9imagePullPolicy: IfNotPresentname: nginxvolumeMounts: # 容器內掛載:/usr/share/nginx/html → nfs-volume- mountPath: /usr/share/nginx/htmlname: nfs-volumevolumes: # 定義 NFS 卷- name: nfs-volumenfs:server: 192.168.10.101 # NFS 服務器IPpath: /opt/wwwroot # NFS 共享目錄 EOF
3. 部署與驗證
- 部署:
kubectl create -f nginx-nfsVolume.yaml
- 查看 Pod:
kubectl get pod
(示例:nginx-fbd476c4c-zscq9 1/1 Running
)
驗證掛載:
kubectl exec -ti <pod-name> -c nginx -- bash cat /usr/share/nginx/html/index.html # 應輸出 "NFS Test"
六、PersistentVolume(PV,持久卷)
1. 引入背景
- Volume 無法解決?數據回收、訪問模式、單 Pod 掛載?等復雜需求,且非 K8s 管理員難以配置。
- 引入?PV(管理員預配存儲)?和?PVC(用戶申請 PV),解耦存儲管理與使用。
2. 核心特性
- 生命周期獨立:不受 Pod 影響,管理員可單獨操作。
- 支持存儲:NFS、Ceph 等,可配置?訪問模式、容量、回收策略。
- 提供方式:靜態(預創建)、動態(依賴 StorageClass 自動創建)。
3. 回收策略
策略 | 行為 | 支持存儲 |
---|---|---|
Retain | 刪除 PVC 后,PV 及數據保留,需手動回收。 | 全類型 |
Recycle | 刪除 PVC 后,執行?rm -rf ?清理數據(已廢棄,僅 NFS/HostPath 支持)。 | NFS、HostPath |
Delete | 刪除 PVC 時,自動刪除 PV 及數據(動態 PV 默認策略)。 | 云存儲(如 AWS EBS) |
4. 訪問策略
策略 | 說明 | 存儲限制 |
---|---|---|
ReadWriteOnce (RWO) | 單節點讀寫 | 通用 |
ReadOnlyMany (ROX) | 多節點只讀 | 通用 |
ReadWriteMany (RWX) | 多節點讀寫(塊存儲多不支持,如 Ceph 塊) | NFS、GlusterFS 等 |
ReadWriteOncePod (RWOP) | 單 Pod 讀寫(K8s 1.22+) | - |
5. 靜態配置實踐
(1)?HostPath 類型 PV
所有 Node 創建目錄:mkdir /mnt/data
編寫?hostpath-pv.yaml
:
kind: PersistentVolume apiVersion: v1 metadata:name: mypv-hostpath spec:storageClassName: pv-hostpathcapacity: { storage: 10Gi }accessModes: [ReadWriteOnce]hostPath: { path: "/mnt/data" }
(2)?NFS 類型 PV(依賴 NFS 服務)
編寫?nfs-pv.yaml
:
apiVersion: v1 kind: PersistentVolume metadata: { name: mypv-nfs } spec:storageClassName: pv-nfscapacity: { storage: 5Gi }accessModes: [ReadWriteOnce]persistentVolumeReclaimPolicy: Recyclenfs:path: /opt/wwwrootserver: 192.168.10.101 # NFS 服務器 IP
創建 & 查看:kubectl create -f nfs-pv.yaml && kubectl get pv
七、PersistentVolumeClaim(PVC,持久卷聲明)
1.??核心作用
- 用戶通過 PVC 聲明?容量、訪問模式、StorageClass,自動綁定匹配的 PV,無需關心存儲細節。
2.?PVC 配置與綁定
(1)?HostPath PV 的 PVC
kind: PersistentVolumeClaim apiVersion: v1 metadata: { name: mypvc-hostpath } spec:storageClassName: pv-hostpath # 與 PV 一致accessModes: [ReadWriteOnce]resources: { requests: { storage: 10Gi } }
創建 & 查看:kubectl create -f pvc-hostpath.yaml && kubectl get pvc
(狀態為?Bound
)
(2)?NFS PV 的 PVC
kind: PersistentVolumeClaim apiVersion: v1 metadata: { name: mypvc-nfs } spec:storageClassName: pv-nfs # 與 PV 一致accessModes: [ReadWriteOnce]resources: { requests: { storage: 3Gi } } # ≤ PV 容量(5Gi)
創建 & 查看:kubectl create -f pvc-nfs.yaml && kubectl get pvc
(狀態為?Bound
)
3.?PVC 掛載到 Pod
kind: Pod apiVersion: v1 metadata: { name: hostpath-pv-pod } spec:volumes:- name: pv-volumepersistentVolumeClaim: { claimName: mypvc-hostpath } # 綁定 PVCcontainers:- name: test-containerimage: nginx:1.7.9volumeMounts:- mountPath: "/data"name: pv-volume
驗證:kubectl exec -ti hostpath-pv-pod -- ls /data