kubernetes資料持久化PV-PVC詳解(一)

梨花海棠 發表於 2022-11-27
Kubernetes

官方文件地址: https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

1. 什麼是PV,PVC?

1.1 什麼是PV

PresistentVolume(PV)是指叢集管理員配置提供的某儲存系統上的一段儲存空間,它是對底層共享儲存的抽象,將共享儲存作為一種可由使用者申請使用的資源,實現"儲存消費"機制,透過儲存外掛,PV支援使用多種網路儲存等多種後端儲存系統,例如,NFS、CephFS、RBD。PV是叢集級別的資源,不屬於任何名稱空間,使用者對PV資源的使用需要透過PersistentVolumeClaim(PVC)提供的使用申請來完成繫結,PVC是PV資源的消費者,它向PV申請特定大小的空間及訪問模式(rw或ro)從而建立出PVC儲存卷。然後再由Pod資源透過PersistentVolumeClaim儲存卷關聯使用。

1.2 什麼是PVC?

PersistentVolumeClaim,PVC是儲存卷型別的資源,它透過申請佔用某個PersistentVolume而建立,它與PV是一對一的關係,使用者無須關心其底層實現細節,申請時,使用者只需要指定目標空間的大小,訪問模式,PV標籤選擇器和StorageClass等相關資訊即可。

2. PV資源實踐;

2.1 PV配置欄位詳解

PresistentVolume Spec支援如下幾個通用欄位,用於定義PV的容量,訪問模式和回收策。
1.Capacity: PV的容量
2.volumeMode: 卷型別,用於指定此卷可被用作檔案系統還是裸格式的塊裝置,預設為Filesystem。
3.accessMode: PV的訪問模式參考官方

  • 1.ReadWriteOnce: 僅可被單個節點讀寫掛載;命令列中簡寫RWO。
  • 2.ReadOnlyMany: 僅可被多個節點同時只讀掛在;命令列簡寫ROX。
  • 3.ReadyWriteMany: 可被多個節點同時讀寫掛載;命令列中簡寫RWX。

4.persistentVolumeReclaimPolicy: PV空間的處理機制,可用型別為Retain(預設)、Recycle或Delete。

  • 1.Retain: 保持不動,由管理員手動回收。
  • 2.Recycle: 空間回收,即刪除儲存卷下的所有檔案(包括子目錄和隱藏檔案rm -rf /thevolume/*),目前僅NFS和hostpath支援此功能。
  • 3.Delete: 刪除儲存卷,諸如 AWS EBS、GCE PD、Azure Disk 或 OpenStack Cinder 卷這類關聯儲存資產也被刪除。

5.storageClassName: 當前PV所屬的StorageClass的名稱,預設為空,即不屬於任何StorageClass。
6.mountOptions: 掛載選項組成的列表,如ro,soft和hard等。

2.2 HostPath PV示例

[[email protected] pv]# cat hostpath-pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-volume-001    
spec: 
  storageClassName: "host-storage"   資源型別的標識
  persistentVolumeReclaimPolicy: "Retain"  回收策略預設為Retain
  capacity:    定義空間
    storage: 1Gi  定義空間大小
  accessModes:    訪問模式
    - ReadWriteOnce  訪問模式為僅被單個節點讀寫掛載,單路讀寫
  hostPath:     臨時儲存在哪個地方
    path: "/mnt/data"
[[email protected] pv]# kubectl get pv
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv-volume-001   1Gi        RWO            Retain           Available           host-storage            4m36s

2.2 NFS PV示例

[[email protected] pv]# cat nfs-pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv
  labels:     標籤
    release: nfs-redis
spec:
  storageClassName: "nfs-storage"  資源型別表示
  persistentVolumeReclaimPolicy: "Recycle"  回收策略為Recycle相當rm -rf /
  capacity: 
    storage: 0.5Gi
  accessModes:
  - ReadWriteMany
  nfs: 
    server: 10.0.0.15
    path: /data/redis
[[email protected] pv]# kubectl get pv
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM             STORAGECLASS   REASON   AGE
nfs-pv          512Mi      RWX            Recycle          Available                     nfs-storage             62m
pv-volume-001   1Gi        RWO            Retain           Bound       default/001-pvc   host-storage            160m

3. PVC資源實踐;

3.1 PVC配置清單詳解。

PersistentVolumeClaim,PVC是儲存卷型別的資源,它透過申請佔用某個PersistentVolume而建立,它與PV是一對一的關係,使用者無須關心其底層實現細節, 申請時,使用者只需要指定目標空間的大小,訪問模式,PV標籤選擇器和StorageClass等相關資訊即可。
PVC的Spec欄位可巢狀欄位如下,

  1. accessMode: 當前PVC的訪問模式,其可用模式與PV相同。
  2. resource當前PVC儲存卷需要佔用的資源的最大和最小值。
  3. selector繫結時對PV應用的標籤選擇器,matchlabels或者匹配表示式matchEx-pressions用於挑選要繫結的PV,如果同時指定來兩種挑選機制,則必須同時滿足兩種選擇機制的PV才能被選出。
  4. storageClassName: 所依賴的儲存卷的名稱。
  5. volumeName: 用於直接制定要繫結的PV的卷名。

3.2 hostPath-PVC示例

[[email protected] pv]# cat hostpath-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: 001-pvc
spec:
  storageClassName: "host-storage"  和PV的storageclassname須一致,否則無法識別。
  accessModes:
    - ReadWriteOnce
  resources:     pvc的資源限定僅指其空間大小。
    requests:
      storage: 0.9Gi  大小為0.9Gi;
[[email protected] pv]#  kubectl apply -f hostpath-pvc.yaml 

Available: 可用狀態的自由資源,尚未被繫結PVC。
Bound: 已經繫結至某個PVC。
Released: 繫結的PVC已經被刪除,但資源尚被叢集回收。
Failed: 因自動回收資源失敗而處於的故障狀態。
[[email protected] pv]# kubectl get pv pv-volume-001
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
pv-volume-001   1Gi        RWO            Retain           Bound    default/001-pvc   host-storage            33m


[[email protected] pv]# kubectl describe pv pv-volume-001
Name:            pv-volume-001
Labels:          <none>
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    host-storage
Status:          Bound
Claim:           default/001-pvc
Reclaim Policy:  Retain
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        1Gi
Node Affinity:   <none>
Message:         
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /mnt/data
    HostPathType:  
Events:            <none>
[[email protected] pv]# kubectl describe pvc 001-pvc 
Name:          001-pvc
Namespace:     default
StorageClass:  host-storage
Status:        Bound   已繫結
Volume:        pv-volume-001
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      1Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Used By:       <none>
Events:        <none>

3.3 NFS-PV-PVC實踐之準備NFS共享儲存。

生產環境建議使用Ceph其他儲存。

[[email protected] ~]# yum install nfs-utils -y 

[[email protected] ~]# cat /etc/exports
/nfs/data5/ 10.0.0.0/24(rw,no_root_squash)
/data/redis 10.0.0.0/24
10.0.0.0/24  pod訪問nfs服務會將源IP修改為節點IP,允許所有節點訪問NFS服務
(ro,no_root_squash)訪問NFS-SERVER共享目錄的使用者如果是root,它對共享目錄有root許可權
準備資料共享目錄
[[email protected] ~]# mkdir /data/redis -p 

[[email protected] ~]# systemctl enable nfs-server
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-server.service to /usr/lib/systemd/system/nfs-server.service.


服務端配置
各個工作節點安裝nfs-utils
[[email protected] pv]# showmount -e 10.0.0.15
Export list for 10.0.0.15:
/data/redis 10.0.0.0/24
master節點和node節點都需要安裝
[[email protected] ~]# showmount -e 10.0.0.15
Export list for 10.0.0.15:
/data/redis 10.0.0.0/24

3.4 準備NFS-PVC

[[email protected] pv]# cat nfs-pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-pvc
  labels:    首先標籤須匹配,不然無法匹配,也可以稱為強行繫結。
    release: nfs-redis
spec:
  storageClassName: "nfs-storage"  須同屬一個
  accessModes: 
  - ReadWriteMany
  resources:
    requests:
      storage: 0.5Gi  指定大小。

[[email protected] pv]# kubectl apply -f nfs-pvc.yaml 
persistentvolumeclaim/nfs-pvc created

顯示已為繫結狀態。
[[email protected] pv]# kubectl get pv,pvc 
NAME                             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM             STORAGECLASS   REASON   AGE
persistentvolume/nfs-pv          512Mi      RWX            Recycle          Bound    default/nfs-pvc   nfs-storage             78m
persistentvolume/pv-volume-001   1Gi        RWO            Retain           Bound    default/001-pvc   host-storage            175m

NAME                            STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/001-pvc   Bound    pv-volume-001   1Gi        RWO            host-storage   143m
persistentvolumeclaim/nfs-pvc   Bound    nfs-pv          512Mi      RWX            nfs-storage    6s

透過describe來檢視
[[email protected] pv]# kubectl describe pv nfs-pv
Name:            nfs-pv
Labels:          release=nfs-redis   所屬標籤
Annotations:     pv.kubernetes.io/bound-by-controller: yes
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    nfs-storage    storageclass名稱
Status:          Bound   繫結狀態
Claim:           default/nfs-pvc   名稱空間
Reclaim Policy:  Recycle  回收策略
Access Modes:    RWX    訪問模式
VolumeMode:      Filesystem
Capacity:        512Mi  大小
Node Affinity:   <none>
Message:         
Source:
    Type:      NFS (an NFS mount that lasts the lifetime of a pod)
    Server:    10.0.0.15  來自那個nfs伺服器
    Path:      /data/redis   共享的資料目錄
    ReadOnly:  false
Events:        <none>
3.4.1準備Pod並使用PVC
[[email protected] pv]# cat pod-redis.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: redis
spec: 
  containers:
  - name: redis
    image: redis
    volumeMounts:
    - name: redis-data
      mountPath: /data
  volumes:
  - name: redis-data
    persistentVolumeClaim:
      claimName: nfs-pvc 
	  
[[email protected] pv]# kubectl describe pods redis
Containers:
  redis:
    Container ID:   docker://d82061a1a86f56432e9956fc46bc810e577a0d89b91894e266e883bef68f5d9d
    Image:          redis
    Image ID:       docker-pullable://[email protected]:db485f2e245b5b3329fdc7eff4eb00f913e09d8feb9ca720788059fdc2ed8339
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sun, 27 Nov 2022 21:57:34 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /data from redis-data (rw)   已經掛載
	  
	  
[[email protected] pv]# kubectl describe pvc nfs-pvc
Name:          nfs-pvc
Namespace:     default
StorageClass:  nfs-storage
Status:        Bound
Volume:        nfs-pv
Labels:        release=nfs-redis
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      512Mi
Access Modes:  RWX
VolumeMode:    Filesystem
Used By:       redis  這裡可以看到是redis這個Pod正在使用這個PVC
Events:        <none>
3.4.2 測試資料永續性。
[[email protected] pv]# redis-cli -h 192.168.1.86
192.168.1.86:6379> set key haitang 
OK
192.168.1.86:6379> get key
"haitang"
192.168.1.86:6379> bgsave
Background saving started
192.168.1.86:6379> exit


可以看到資料是寫到nfs-server了
[[email protected] redis]# ll
總用量 4
-rw-r--r-- 1 polkitd input 110 11月 27 22:14 dump.rdb


刪除Pod後,資料是不會丟失的。
[[email protected] pv]# kubectl delete pods redis
pod "redis" deleted

資料是還在的。
[[email protected] redis]# ll
總用量 4
-rw-r--r-- 1 polkitd input 110 11月 27 22:20 dump.rdb