k8s如何使用NFS作為StorageClass提供動(dòng)態(tài)存儲(chǔ)
一、概要
本文主要以下幾方面介紹k8s中的StorageClass:
- 什么是StorageClass
- 為什么要引入StorageClass
- StorageClass實(shí)現(xiàn)方式
- 定義StorageClass(NFS)
- 關(guān)于StorageClass回收策略對(duì)數(shù)據(jù)的影響
- 設(shè)置默認(rèn)的StorageClass
二、什么是StorageClass
存儲(chǔ)類,在K8s集群中創(chuàng)建用于動(dòng)態(tài)PV的管理,可以鏈接至不同的后端存儲(chǔ),比如Ceph、GlusterFS、NFS等。之后對(duì)存儲(chǔ)的請(qǐng)求可以指向StorageClass,然后StorageClass會(huì)自動(dòng)的創(chuàng)建、刪除PV。
每個(gè) StorageClass 都包含provisioner、parameters和reclaimPolicy字段, 這些字段會(huì)在 StorageClass 需要?jiǎng)討B(tài)制備 PersistentVolume 以滿足 PersistentVolumeClaim (PVC) 時(shí)使用到。
StorageClass可以定義以下屬性:
- volumeBindingMode:指定持久卷綁定模式,可以是"Immediate"或"WaitForFirstConsumer"。"Immediate"表示持久卷將立即綁定到聲明的請(qǐng)求,而"WaitForFirstConsumer"表示持久卷將等待第一個(gè)消費(fèi)者使用它之前才進(jìn)行綁定
- provisioner:指定用于創(chuàng)建持久卷的存儲(chǔ)提供商。不同的存儲(chǔ)提供商可能具有不同的實(shí)現(xiàn)和配置要求
- parameters:存儲(chǔ)提供商特定的參數(shù),用于配置持久卷的創(chuàng)建和屬性。例如,可以指定存儲(chǔ)容量、存儲(chǔ)類別、訪問模式等
- reclaimPolicy:指定在釋放持久卷時(shí)應(yīng)如何處理底層存儲(chǔ)資源??梢赃x擇"Retain"(保留)、"Delete"(刪除)或"Recycle"(回收)
- MountOptions:通過StorageClass動(dòng)態(tài)創(chuàng)建的PV可以使用MountOptions指定掛載參數(shù)。如果指定的卷插件不支持指定的掛載選項(xiàng),就不會(huì)被創(chuàng)建成功,因此在設(shè)置時(shí)需要進(jìn)行確認(rèn)。
- AllowVolumeExpansion:是否允許對(duì)PV進(jìn)行擴(kuò)容,需要后端存儲(chǔ)支持,一般不推薦進(jìn)行縮容
注意:
- StorageClass 對(duì)象的命名很重要,用戶使用這個(gè)命名來請(qǐng)求生成一個(gè)特定的類。
- 當(dāng)創(chuàng)建 StorageClass 對(duì)象時(shí),管理員設(shè)置 StorageClass 對(duì)象的命名和其他參數(shù),一旦創(chuàng)建了對(duì)象就不能再對(duì)其更新。
三、為什么要引入StorageClass
雖然使用PV和PVC能屏蔽一些存儲(chǔ)使用上的細(xì)節(jié),降低了存儲(chǔ)使用的復(fù)雜度,但是也會(huì)有另一個(gè)問題無法解決。當(dāng)公司Kubernetes集群很多,并且使用它們的技術(shù)人員過多時(shí),對(duì)于PV的創(chuàng)建是一個(gè)很耗時(shí)、耗力的工作,并且達(dá)到一定規(guī)模后,過多的PV將難以維護(hù)。所以就需要某種機(jī)制用于自動(dòng)管理PV的生命周期,比如創(chuàng)建、刪除、自動(dòng)擴(kuò)容等,于是Kubernetes就設(shè)計(jì)了一個(gè)名為StorageClass(縮寫為SC,沒有命名空間隔離性)的東西,通過它可以動(dòng)態(tài)管理集群中的PV,這樣Kubernetes管理員就無須浪費(fèi)大量的時(shí)間在PV的管理中。
在Kubernetes中,管理員可以只創(chuàng)建StorageClass“鏈接”到后端不同的存儲(chǔ),比如Ceph、GlusterFS、OpenStack的Cinder、其他公有云提供的存儲(chǔ)等,之后有存儲(chǔ)需求的技術(shù)人員,創(chuàng)建一個(gè)PVC指向?qū)?yīng)的StorageClass即可,StorageClass會(huì)自動(dòng)創(chuàng)建PV供Pod使用,也可以使用StatefulSet的volumeClaimTemplate自動(dòng)分別為每個(gè)Pod申請(qǐng)一個(gè)PVC。
四、StorageClass實(shí)現(xiàn)方式
StorageClass的實(shí)現(xiàn)方式取決于Kubernetes集群所使用的存儲(chǔ)插件和存儲(chǔ)提供商。不同的存儲(chǔ)插件和提供商可能有不同的實(shí)現(xiàn)細(xì)節(jié)和配置要求。
針對(duì)不同廠商的存儲(chǔ)管理,k8s編寫相應(yīng)的代碼。而不同廠商為了適配k8s,都會(huì)提供一個(gè)驅(qū)動(dòng)(CSI或者Fiex Volume)安裝到k8s集群中,然后StorageClass只需要配置該驅(qū)動(dòng)即可,驅(qū)動(dòng)器會(huì)代替StorageClass管理存儲(chǔ)。
每個(gè) StorageClass 都有一個(gè)制備器(Provisioner),用來決定使用哪個(gè)卷插件制備 PV。 該字段必須指定。
五、定義StorageClass(NFS)
下面演示一個(gè)基本的StorageClass配置,使用nfs作為后端存儲(chǔ),NFS類型的sc只建議在測(cè)試環(huán)境使用,因?yàn)镹FS存在性能瓶頸及單點(diǎn)故障問題,生產(chǎn)環(huán)境推薦使用分布式存儲(chǔ)。
1.環(huán)境準(zhǔn)備
主機(jī)IP | 用途 | 版本 | 安裝方式 | 備注 |
---|---|---|---|---|
10.3.248.136 | k8s-master | v1.24.4 | 二進(jìn)制 | 安裝了nfs-until |
10.3.248.143 | k8s-node01 | v1.24.4 | 二進(jìn)制 | 安裝了nfs-until |
10.3.248.144 | k8s-node02 | v1.24.4 | 二進(jìn)制 | 安裝了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ù)實(shí)際環(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名稱,請(qǐng)確保該名稱與 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)建測(cè)試pod驗(yàn)證
創(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,肯定是有問題 ,需要進(jìn)一步檢查原因
# 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
進(jìn)入pod創(chuàng)建一個(gè)文件
# 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
此時(shí)我們可以發(fā)現(xiàn)進(jìn)入pod創(chuàng)建的文件已經(jīng)持久化存儲(chǔ)了,即使刪除了pod文件不會(huì)丟失。
六、關(guān)于StorageClass回收策略對(duì)數(shù)據(jù)的影響
1.第一種配置
archiveOnDelete: "false" reclaimPolicy: Delete #默認(rèn)沒有配置,默認(rèn)值為Delete
測(cè)試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV被刪除且NFS Server對(duì)應(yīng)數(shù)據(jù)被刪除
2.第二種配置
archiveOnDelete: "false" reclaimPolicy: Retain
測(cè)試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV不會(huì)別刪除,且狀態(tài)由Bound變?yōu)镽eleased,NFS Server對(duì)應(yīng)數(shù)據(jù)被保留
- 4.重建sc后,新建PVC會(huì)綁定新的pv,舊數(shù)據(jù)可以通過拷貝到新的PV中
3.第三種配置
archiveOnDelete: "ture" reclaimPolicy: Retain
測(cè)試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV不會(huì)別刪除,且狀態(tài)由Bound變?yōu)镽eleased,NFS Server對(duì)應(yīng)數(shù)據(jù)被保留
- 4.重建sc后,新建PVC會(huì)綁定新的pv,舊數(shù)據(jù)可以通過拷貝到新的PV中
4第四種配置
archiveOnDelete: "ture" reclaimPolicy: Delete
測(cè)試結(jié)果
- 1.pod刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 2.sc刪除重建后數(shù)據(jù)依然存在,舊pod名稱及數(shù)據(jù)依然保留給新pod使用
- 3.刪除PVC后,PV不會(huì)別刪除,且狀態(tài)由Bound變?yōu)镽eleased,NFS Server對(duì)應(yīng)數(shù)據(jù)被保留
- 4.重建sc后,新建PVC會(huì)綁定新的pv,舊數(shù)據(jù)可以通過拷貝到新的PV中
總結(jié):除以第一種配置外,其他三種配置在PV/PVC被刪除后數(shù)據(jù)依然保留
七、設(shè)置默認(rèn)的StorageClass
官網(wǎng)地址改變默認(rèn) StorageClass | Kubernetes
kubectl patch命令
kubectl patch storageclass standard -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
這里的standard
是你選擇的 StorageClass 的名字。
注意:最多只能有一個(gè) StorageClass 能夠被標(biāo)記為默認(rèn)。 如果它們中有兩個(gè)或多個(gè)被標(biāo)記為默認(rèn),Kubernetes 將忽略這個(gè)注解, 也就是它將表現(xiàn)為沒有默認(rèn) StorageClass。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
centos搭建k8s環(huán)境詳細(xì)步驟及常用命令
kubernetes是google開源的容器集群管理系統(tǒng),提供應(yīng)用部署、維護(hù)、擴(kuò)展機(jī)制等功能,利用kubernetes能方便管理跨集群運(yùn)行容器化的應(yīng)用,這篇文章主要給大家介紹了關(guān)于centos搭建k8s環(huán)境詳細(xì)步驟及常用命令的相關(guān)資料,需要的朋友可以參考下2024-01-01k8s編排之Deployment知識(shí)點(diǎn)詳解
這篇文章主要為大家介紹了k8s編排之Deployment知識(shí)點(diǎn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01kubernetes?部署dashboard最新詳細(xì)步驟
這篇文章主要介紹了kubernetes?部署dashboard最新詳細(xì)步驟,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06再分享6個(gè)可無限激活阿里云盤邀請(qǐng)碼,不信你不能激活阿里云盤
這篇文章主要分享6個(gè)可無限激活的阿里云盤邀請(qǐng)碼,不信你不能激活阿里云盤,需要的朋友可以參考下2020-11-11Centos?8.2?升級(jí)內(nèi)核通過elrepo源的方法
這篇文章主要介紹了Centos?8.2?升級(jí)內(nèi)核通過elrepo源,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10