Pod 數據持久化(數據卷與數據持久化卷)


1.Volume

volume使用說明

  • Kubernetes中的Volume提供了在容器中掛載外部存儲的能力
  • Pod需要設置卷來源(spec.volume)和掛載點(spec.containers.volumeMounts)兩個信息后才可 以使用相應的Volume

 

volume的分類

大致可以分為三類

 

volume 官網:https://kubernetes.io/docs/concepts/storage/volumes/

 

emptyDir

創建一個空卷,掛載到Pod中的容器。Pod刪除該卷也會被刪除。

應用場景:Pod中容器之間數據共享

read-write-pod.yaml

apiVersion: v1 kind: Pod metadata:  name: my-pod spec:  containers:  - name: write  image: centos  command: ["bash","-c","for i in {1..100};do echo $i>> /data/hello;sleep 1;done"]  volumeMounts:  - name: data  mountPath: /data  - name: read  image: centos  command: ["bash","-c","tail -f /data/hello"]  volumeMounts:  - name: data  mountPath: /data  volumes:  - name: data  emptyDir: {}

兩個pod 共用本地存儲。

image.png

image.png

去 k8s-node2 查看映射在宿主機 上的目錄,這個就是 pod 共享的目錄

image.png

hostPath

掛載Node文件系統上文件或者目錄到Pod中的容器,pod刪除后宿主機上的目錄不會被清除

應用場景:Pod中容器需要訪問宿主機文件

hostpath.yaml

apiVersion: v1 kind: Pod metadata:  name: my-pod spec:  containers:  - name: busybox  image: busybox  args:  - /bin/sh  - -c  - sleep 36000  volumeMounts:  - name: data  mountPath: /data  volumes:  - name: data  hostPath:  path: /tmp  type: Directory 

pod被調度到 k8s-node2  容器中的/data 目錄 映射到宿主機的/tmp目錄

image.png

image.png

反之如果在宿主機的/tmp目錄下創建文件 在容器中的 /data 目錄一樣可以看到。

但是如果 重建pod調度到 非之前的節點,那么之前pod 的數據就會看不到了。

 

NFS

部署nfs:

#nfs服務端 yum install nfs-utils -y 編輯 /etc/exports 增加內容 /opt/nfs *(rw,no_root_squash) mkdir /opt/nfs systemctl start nfs;systemctl enable nfs;systemctl status nfs #nfs客戶端 mount -t nfs 192.168.31.65:/opt/nfs /mnt #192.168.31.65是server端 

驗證nfs共享存儲:

在任意客戶端的 掛載目錄創建個 123文件

image.png

在其他客戶端的 /mnt  或者服務端的 /opt/nfs 都可以看到

image.png

image.png

 

測試k8s中使用nfs存儲

 

apiVersion: apps/v1 kind: Deployment metadata:  name: nginx-deployment spec:  selector:  matchLabels:  app: nginx  replicas: 3  template:  metadata:  labels:  app: nginx  spec:  containers:  - name: nginx  image: nginx  volumeMounts:  - name: wwwroot  mountPath: /usr/share/nginx/html  ports:  - containerPort: 80  volumes:  - name: wwwroot  nfs:  server: 192.168.31.65  path: /opt/nfs

 

image.png

向 /opt/nfs  目錄下創建 test.html 內容為hello test 作為 nginx的首頁文件

如果是再nfs client端操作 是 /mnt目錄

cd /root/learn/ echo 'hello test' >/mnt/test.html

請求首頁進行驗證

image.png

當我們重建一個pod 是否有效?

image.png

answer is 有效

image.png

使用nfs 網絡共享存儲的優勢是即使pod 重建后調度到其他node上 依舊可以保留之前的數據。

 

2.PersistentVolume

  • PersistentVolume(PV):對存儲資源創建和使用的抽象,使得存儲作為集群中的資源管理
  • PersistentVolumeClaim(PVC):讓用戶不需要關心具體的Volume實現細節

為什么會有pv和pvc這個概念:

image.png

對於 nfs server的 地址 掛載路徑 用戶不關心,那么是否可以將這資源抽象出來,將這些存儲資源划分給集群管理,定義個名稱或者標記,用戶直接使用。

pv靜態供給

提前申請好 多個pv形成一個pv池子 供pod從pv池里選取存儲容量合適的pv申請成pvc 。

image.png

Kubernetes支持持久卷的存儲插件: https://kubernetes.io/docs/concepts/storage/persistent-volumes/

 

向存儲池申請3個pv

apiVersion: v1 kind: PersistentVolume metadata:  name: pv001 spec:  capacity:  storage: 5Gi  accessModes:  - ReadWriteMany  nfs:  path: /opt/nfs/pv001  server: 192.168.31.65 --- apiVersion: v1 kind: PersistentVolume metadata:  name: pv002 spec:  capacity:  storage: 10Gi  accessModes:  - ReadWriteMany  nfs:  path: /opt/nfs/pv002  server: 192.168.31.65 --- apiVersion: v1 kind: PersistentVolume metadata:  name: pv003 spec:  capacity:  storage: 30Gi  accessModes:  - ReadWriteMany  nfs:  path: /opt/nfs/pv003  server: 192.168.31.65

image.png

pv對應的各個字段的含義

  • NAME: pv的名稱
  • CAPACITY: pv的容量
  • ACCESS MODES: 訪問策略

ReadWriteOnce  – RWO - ReadWriteOnce一人讀寫

ReadOnlyMany  – ROX - ReadOnlyMany 多人只讀

ReadWriteMany – RWX - ReadWriteMany多人讀寫

  • RECLAIM POLICY: 

用戶刪除PVC釋放對PV的占用后,系統根據PV的"reclaim policy"決定對PV執行何種回收操作。 目前,"reclaim policy"有三種方式:Retained、Recycled、Deleted。

 

官網描述:

PersistentVolumes 可以有多種回收策略,包括 “Retain”、”Recycle” 和 “Delete”。對於動態配置的 PersistentVolumes 來說,默認回收策略為 “Delete”。這表示當用戶刪除對應的 PersistentVolumeClaim 時,動態配置的 volume 將被自動刪除。如果 volume 包含重要數據時,這種自動行為可能是不合適的。那種情況下,更適合使用 “Retain” 策略。使用 “Retain” 時,如果用戶刪除 PersistentVolumeClaim,對應的 PersistentVolume 不會被刪除。相反,它將變為 Released 狀態,表示所有的數據可以被手動恢復。

 

Recycle策略

當 PVC pvc001 被刪除后,我們發現 Kubernetes 啟動了一個新 Pod recycler-for-pv001,這個 Pod 的作用就是清除 PV pv001 的數據。此時 pv001的狀態為 Released,表示已經解除了與 pvc001的 Bound,正在清除數據,不過此時還不可用。

當數據清除完畢,pv001的狀態重新變為 Available,此時則可以被新的 PVC 申請。

 

Retain策略

當綁定再pv上的pvc被刪除后,並不會啟動一個 recycler-for-xxx 的pod來回收pv,刪除pvc后pv的狀態直接變為released,雖然pvc被刪除了,但是pv上的數據得到了保留,此時pv狀態一直是Released的不能被其他pvc 綁定,如果想要這個pv重新被使用只有刪除該pv 重建,重建后的pv狀態重新變成Available再次可以被其他pvc 綁定使用。

 

Delete策略

只有使用了 動態pv的才可以支持該策略,而且pv動態供給默認使用該模式,刪除pvc時同時刪除與之綁定的pv,共享存儲里之前pv的數據將會被歸檔,當pv 和pvc重新創建后會重新生成一個新目錄。

之前目錄將重命名為 archived-xxxxxxxxxx     xxxxxxx代表刪除pvc之前的名稱

 

  • STATUS :pv的狀態
  • CLAIM:   與pv綁定的pvc名稱
  • STORAGECLASS: 存儲插件類型

 

apiVersion: v1 kind: Pod metadata:  name: my-pod spec:  containers:  - name: nginx  image: nginx:latest  ports:  - containerPort: 80  volumeMounts:  - name: www  mountPath: /usr/share/nginx/html  volumes:  - name: www  persistentVolumeClaim:  claimName: my-pvc  --- apiVersion: v1 kind: PersistentVolumeClaim metadata:  name: my-pvc spec:  accessModes:  - ReadWriteMany  resources:  requests:  storage: 5Gi

image.png

 

image.png

如果pv,pvc一直處於Terminating

 

kubectl patch pv pv001 -p '{"metadata":{"finalizers":null}}' kubectl patch pvc my-pvc -p '{"metadata":{"finalizers": []}}' --type=merge

 

 

pv動態供給

Kubernetes支持持久卷的存儲插件: https://kubernetes.io/docs/concepts/storage/persistent-volumes/

image.png

Dynamic Provisioning機制工作的核心在於StorageClass的API對象。

StorageClass聲明存儲插件,用於自動創建PV

 

k8s支持動態供給的存儲插件

https://kubernetes.io/docs/concepts/storage/storage-classes/

 

 

社區開發nfs 支持動態供給的存儲插件 https://github.com/kubernetes-incubator/external-storage/tree/master/nfs-client/deploy

image.png

 

實現動態pv供給需要解決的問題:

1.創建共享目錄

2.創建pv

3.pv使用哪個存儲后端(ip)

 

這些步驟將會由 支持pv動態供給的插件自動化完成

 

部署nfs動態供給支持插件

rbac.yaml

kind: ServiceAccount apiVersion: v1 metadata:  name: nfs-client-provisioner --- kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: nfs-client-provisioner-runner rules:  - apiGroups: [""]  resources: ["persistentvolumes"]  verbs: ["get", "list", "watch", "create", "delete"]  - apiGroups: [""]  resources: ["persistentvolumeclaims"]  verbs: ["get", "list", "watch", "update"]  - apiGroups: ["storage.k8s.io"]  resources: ["storageclasses"]  verbs: ["get", "list", "watch"]  - apiGroups: [""]  resources: ["events"]  verbs: ["create", "update", "patch"] --- kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: run-nfs-client-provisioner subjects:  - kind: ServiceAccount  name: nfs-client-provisioner  namespace: default roleRef:  kind: ClusterRole  name: nfs-client-provisioner-runner  apiGroup: rbac.authorization.k8s.io --- kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: leader-locking-nfs-client-provisioner rules:  - apiGroups: [""]  resources: ["endpoints"]  verbs: ["get", "list", "watch", "create", "update", "patch"] --- kind: RoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata:  name: leader-locking-nfs-client-provisioner subjects:  - kind: ServiceAccount  name: nfs-client-provisioner  # replace with namespace where provisioner is deployed  namespace: default roleRef:  kind: Role  name: leader-locking-nfs-client-provisioner  apiGroup: rbac.authorization.k8s.io

 

class.yaml

apiVersion: storage.k8s.io/v1 kind: StorageClass metadata:  name: managed-nfs-storage provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' parameters:  archiveOnDelete: "true" 

 

deployment.yaml

apiVersion: v1 kind: ServiceAccount metadata:  name: nfs-client-provisioner --- kind: Deployment apiVersion: apps/v1 metadata:  name: nfs-client-provisioner spec:  replicas: 1  strategy:  type: Recreate  selector:  matchLabels:  app: nfs-client-provisioner  template:  metadata:  labels:  app: nfs-client-provisioner  spec:  serviceAccountName: nfs-client-provisioner  imagePullSecrets:  - name: myregistry  containers:  - name: nfs-client-provisioner  image: registry.cn-hangzhou.aliyuncs.com/benjamin-learn/nfs-client-provisioner:latest  volumeMounts:  - name: nfs-client-root  mountPath: /persistentvolumes  env:  - name: PROVISIONER_NAME  value: fuseim.pri/ifs  - name: NFS_SERVER  value: 192.168.31.65  - name: NFS_PATH  value: /opt/nfs  volumes:  - name: nfs-client-root  nfs:  server: 192.168.31.65  path: /opt/nfs 

 

image.png

 

pv動態供給示例

dynamic-pv-pod.yaml

apiVersion: v1 kind: Pod metadata:  name: my-pod spec:  containers:  - name: nginx  image: nginx:latest  ports:  - containerPort: 80  volumeMounts:  - name: www  mountPath: /usr/share/nginx/html  volumes:  - name: www  persistentVolumeClaim:  claimName: my-pvc  --- apiVersion: v1 kind: PersistentVolumeClaim metadata:  name: my-pvc spec:  storageClassName: "managed-nfs-storage"  accessModes:  - ReadWriteMany  resources:  requests:  storage: 5Gi

 

image.png

 

進入my-pod 容器創建 index.html

image.png

default-my-pvc-pvc-f5ce89a7-b566-44df-affe-8221f13db74f 這個目錄由插件自動完成創建

image.png

 

這樣就可以完成了 自動pv供給,不需要再 手動申請pv


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM