k8s如何使用NFS作為StorageClass提供動態(tài)存儲
一、概要
本文主要以下幾方面介紹k8s中的StorageClass:
- 什么是StorageClass
- 為什么要引入StorageClass
- StorageClass實現(xiàn)方式
- 定義StorageClass(NFS)
- 關(guān)于StorageClass回收策略對數(shù)據(jù)的影響
- 設(shè)置默認的StorageClass
二、什么是StorageClass
存儲類,在K8s集群中創(chuàng)建用于動態(tài)PV的管理,可以鏈接至不同的后端存儲,比如Ceph、GlusterFS、NFS等。之后對存儲的請求可以指向StorageClass,然后StorageClass會自動的創(chuàng)建、刪除PV。
每個 StorageClass 都包含provisioner、parameters和reclaimPolicy字段, 這些字段會在 StorageClass 需要動態(tài)制備 PersistentVolume 以滿足 PersistentVolumeClaim (PVC) 時使用到。
StorageClass可以定義以下屬性:
- volumeBindingMode:指定持久卷綁定模式,可以是"Immediate"或"WaitForFirstConsumer"。"Immediate"表示持久卷將立即綁定到聲明的請求,而"WaitForFirstConsumer"表示持久卷將等待第一個消費者使用它之前才進行綁定
- provisioner:指定用于創(chuàng)建持久卷的存儲提供商。不同的存儲提供商可能具有不同的實現(xiàn)和配置要求
- parameters:存儲提供商特定的參數(shù),用于配置持久卷的創(chuàng)建和屬性。例如,可以指定存儲容量、存儲類別、訪問模式等
- reclaimPolicy:指定在釋放持久卷時應(yīng)如何處理底層存儲資源??梢赃x擇"Retain"(保留)、"Delete"(刪除)或"Recycle"(回收)
- MountOptions:通過StorageClass動態(tài)創(chuàng)建的PV可以使用MountOptions指定掛載參數(shù)。如果指定的卷插件不支持指定的掛載選項,就不會被創(chuàng)建成功,因此在設(shè)置時需要進行確認。
- AllowVolumeExpansion:是否允許對PV進行擴容,需要后端存儲支持,一般不推薦進行縮容
注意:
- StorageClass 對象的命名很重要,用戶使用這個命名來請求生成一個特定的類。
- 當(dāng)創(chuàng)建 StorageClass 對象時,管理員設(shè)置 StorageClass 對象的命名和其他參數(shù),一旦創(chuàng)建了對象就不能再對其更新。
三、為什么要引入StorageClass
雖然使用PV和PVC能屏蔽一些存儲使用上的細節(jié),降低了存儲使用的復(fù)雜度,但是也會有另一個問題無法解決。當(dāng)公司Kubernetes集群很多,并且使用它們的技術(shù)人員過多時,對于PV的創(chuàng)建是一個很耗時、耗力的工作,并且達到一定規(guī)模后,過多的PV將難以維護。所以就需要某種機制用于自動管理PV的生命周期,比如創(chuàng)建、刪除、自動擴容等,于是Kubernetes就設(shè)計了一個名為StorageClass(縮寫為SC,沒有命名空間隔離性)的東西,通過它可以動態(tài)管理集群中的PV,這樣Kubernetes管理員就無須浪費大量的時間在PV的管理中。
在Kubernetes中,管理員可以只創(chuàng)建StorageClass“鏈接”到后端不同的存儲,比如Ceph、GlusterFS、OpenStack的Cinder、其他公有云提供的存儲等,之后有存儲需求的技術(shù)人員,創(chuàng)建一個PVC指向?qū)?yīng)的StorageClass即可,StorageClass會自動創(chuàng)建PV供Pod使用,也可以使用StatefulSet的volumeClaimTemplate自動分別為每個Pod申請一個PVC。
四、StorageClass實現(xiàn)方式
StorageClass的實現(xiàn)方式取決于Kubernetes集群所使用的存儲插件和存儲提供商。不同的存儲插件和提供商可能有不同的實現(xiàn)細節(jié)和配置要求。
針對不同廠商的存儲管理,k8s編寫相應(yīng)的代碼。而不同廠商為了適配k8s,都會提供一個驅(qū)動(CSI或者Fiex Volume)安裝到k8s集群中,然后StorageClass只需要配置該驅(qū)動即可,驅(qū)動器會代替StorageClass管理存儲。
每個 StorageClass 都有一個制備器(Provisioner),用來決定使用哪個卷插件制備 PV。 該字段必須指定。
五、定義StorageClass(NFS)
下面演示一個基本的StorageClass配置,使用nfs作為后端存儲,NFS類型的sc只建議在測試環(huán)境使用,因為NFS存在性能瓶頸及單點故障問題,生產(chǎn)環(huán)境推薦使用分布式存儲。
1.環(huán)境準(zhǔn)備
主機IP | 用途 | 版本 | 安裝方式 | 備注 |
---|---|---|---|---|
10.3.248.136 | k8s-master | v1.24.4 | 二進制 | 安裝了nfs-until |
10.3.248.143 | k8s-node01 | v1.24.4 | 二進制 | 安裝了nfs-until |
10.3.248.144 | k8s-node02 | v1.24.4 | 二進制 | 安裝了nfs-until |
10.3.248.134 | NFS-SERVER |
2.創(chuàng)建NFS的sa及rbac
vim nfs-rbac.yaml
apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default #根據(jù)實際環(huán)境設(shè)定namespace,下面類同 --- 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 # replace with namespace where provisioner is deployed 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 # replace with namespace where provisioner is deployed namespace: default 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
創(chuàng)建
kubectl apply -f nfs-rbac.yaml
3.創(chuàng)建NFS資源的StroageClass
vim nfs-storageClass.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage provisioner: test-nfs-storage #這里的名稱要和provisioner配置文件中的環(huán)境變量PROVISIONER_NAME保持一致 parameters: # archiveOnDelete: "false" # archiveOnDelete: "true"
創(chuàng)建
kubectl apply -f nfs-storageClass.yaml
4.創(chuàng)建NFS provisioner
vim nfs-provisioner.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default #與RBAC文件中的namespace保持一致 spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: registry.cn-hangzhou.aliyuncs.com/k8s_study_rfb/nfs-subdir-external-provisioner:v4.0.0 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: test-nfs-storage #provisioner名稱,請確保該名稱與 nfs-StorageClass.yaml文件中的provisioner名稱保持一致 - name: NFS_SERVER value: 10.3.248.134 #NFS Server IP地址 - name: NFS_PATH value: "/data/k8s" #NFS掛載卷 volumes: - name: nfs-client-root nfs: server: 10.3.248.134 #NFS Server IP地址 path: "/data/k8s" #NFS 掛載卷
創(chuàng)建
kubectl apply -f nfs-provisioner.yaml
5.查看狀態(tài)
# kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage test-nfs-storage Retain Immediate false 13d
6.創(chuàng)建測試pod驗證
創(chuàng)建pvc鏈接至nfs的的storgeClass
vim pvc-claim.yaml
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-claim annotations: #與nfs-storageClass.yaml metadata.name保持一致 volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" spec: storageClassName: "managed-nfs-storage" accessModes: - ReadWriteMany #- ReadWriteOnce resources: requests: storage: 1Gi
創(chuàng)建并查看PVC:要確保狀態(tài)為Bound,如果為pending,肯定是有問題 ,需要進一步檢查原因
# kubectl apply -f pvc-claim.yaml # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test-claim Bound pvc-ae9942dc-73ea-4cea-ab1b-f26baf0b61f9 1Gi RWX managed-nfs-storage 4m20s
創(chuàng)建pod
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment-pvc labels: app: nginx spec: replicas: 1 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: 10.3.248.134:10080/k8s/nginx:1.25.2 ports: - containerPort: 80 volumeMounts: - mountPath: /usr/share/nginx/html name: nfs-pvc-claim volumes: - name: nfs-pvc-claim # name of volume persistentVolumeClaim: claimName: test-claim # name of pvc
創(chuàng)建
kubectl apply -f pvc-nginx.yaml
進入pod創(chuàng)建一個文件
# kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-5d5f87db5b-v5r2r 1/1 Running 0 3d23h nginx-deployment-pvc-7774b9d564-rnwl2 1/1 Running 0 3m2s # kubectl exec -it nginx-deployment-pvc-7774b9d564-rnwl2 -- bash root@nginx-deployment-pvc-7774b9d564-rnwl2:/# cd /usr/share/nginx/html/ root@nginx-deployment-pvc-7774b9d564-rnwl2:/usr/share/nginx/html# echo "Hello NFS StorgeClass" >index.html root@nginx-deployment-pvc-7774b9d564-rnwl2:/usr/share/nginx/html# exit
訪問nginx的pod
# kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-5d5f87db5b-v5r2r 1/1 Running 0 3d23h 172.16.178.203 mongodb <none> <none> nginx-deployment-pvc-7774b9d564-rnwl2 1/1 Running 0 5m46s 172.16.178.212 mongodb <none> <none> # curl 172.16.178.212 Hello NFS StorgeClass
刪除pod再次訪問
# kubectl delete pod nginx-deployment-pvc-7774b9d564-rnwl2 pod "nginx-deployment-pvc-7774b9d564-rnwl2" deleted # kubectl get pod -owide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nfs-client-provisioner-5d5f87db5b-v5r2r 1/1 Running 0 4d 172.16.178.203 mongodb <none> <none> nginx-deployment-pvc-7774b9d564-2gmfk 1/1 Running 0 26s 172.28.82.243 k8s-master <none> <none> # curl 172.28.82.243 Hello NFS StorgeClass
此時我們可以發(fā)現(xiàn)進入pod創(chuàng)建的文件已經(jīng)持久化存儲了,即使刪除了pod文件不會丟失。
六、關(guān)于StorageClass回收策略對數(shù)據(jù)的影響
1.第一種配置
archiveOnDelete: "false" reclaimPolicy: Delete #默認沒有配置,默認值為Delete
測試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV被刪除且NFS Server對應(yīng)數(shù)據(jù)被刪除
2.第二種配置
archiveOnDelete: "false" reclaimPolicy: Retain
測試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV不會別刪除,且狀態(tài)由Bound變?yōu)镽eleased,NFS Server對應(yīng)數(shù)據(jù)被保留
- 4.重建sc后,新建PVC會綁定新的pv,舊數(shù)據(jù)可以通過拷貝到新的PV中
3.第三種配置
archiveOnDelete: "ture" reclaimPolicy: Retain
測試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV不會別刪除,且狀態(tài)由Bound變?yōu)镽eleased,NFS Server對應(yīng)數(shù)據(jù)被保留
- 4.重建sc后,新建PVC會綁定新的pv,舊數(shù)據(jù)可以通過拷貝到新的PV中
4第四種配置
archiveOnDelete: "ture" reclaimPolicy: Delete
測試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV不會別刪除,且狀態(tài)由Bound變?yōu)镽eleased,NFS Server對應(yīng)數(shù)據(jù)被保留
- 4.重建sc后,新建PVC會綁定新的pv,舊數(shù)據(jù)可以通過拷貝到新的PV中
總結(jié):除以第一種配置外,其他三種配置在PV/PVC被刪除后數(shù)據(jù)依然保留
七、設(shè)置默認的StorageClass
官網(wǎng)地址改變默認 StorageClass | Kubernetes
kubectl patch命令
kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
這里的standard
是你選擇的 StorageClass 的名字。
注意:最多只能有一個 StorageClass 能夠被標(biāo)記為默認。 如果它們中有兩個或多個被標(biāo)記為默認,Kubernetes 將忽略這個注解, 也就是它將表現(xiàn)為沒有默認 StorageClass。
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Centos?8.2?升級內(nèi)核通過elrepo源的方法
這篇文章主要介紹了Centos?8.2?升級內(nèi)核通過elrepo源,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-10-10