網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
Kubernetes存儲(chǔ)系統(tǒng)數(shù)據(jù)持久化管理詳解_云其它
作者:運(yùn)維開(kāi)發(fā)故事 ? 更新時(shí)間: 2022-12-23 編程語(yǔ)言引言
Kubernetes為了能更好的支持有狀態(tài)應(yīng)用的數(shù)據(jù)存儲(chǔ)問(wèn)題,除了基本的HostPath和EmptyDir提供的數(shù)據(jù)持久化方案之外,還提供了PV,PVC和StorageClass資源對(duì)象來(lái)對(duì)存儲(chǔ)進(jìn)行管理。
PV的全稱(chēng)是Persistent Volume(持久化卷),是對(duì)底層數(shù)據(jù)存儲(chǔ)的抽象,PV由管理員創(chuàng)建、維護(hù)以及配置,它和底層的數(shù)據(jù)存儲(chǔ)實(shí)現(xiàn)方法有關(guān),比如Ceph,NFS,ClusterFS等,都是通過(guò)插件機(jī)制完成和共享存儲(chǔ)對(duì)接。
PVC的全稱(chēng)是Persistent Volume Claim(持久化卷聲明),我們可以將PV比喻為接口,里面封裝了我們底層的數(shù)據(jù)存儲(chǔ),PVC就是調(diào)用接口實(shí)現(xiàn)數(shù)據(jù)存儲(chǔ)操作,PVC消耗的是PV的資源。
StorageClass是為了滿(mǎn)足用于對(duì)存儲(chǔ)設(shè)備的不同需求,比如快速存儲(chǔ),慢速存儲(chǔ)等,通過(guò)對(duì)StorageClass的定義,管理員就可以將存儲(chǔ)設(shè)備定義為某種資源類(lèi)型,用戶(hù)根據(jù)StorageClass的描述可以非常直觀(guān)的知道各種存儲(chǔ)資源的具體特性,這樣就可以根據(jù)應(yīng)用特性去申請(qǐng)合適的資源了。
安裝存儲(chǔ)系統(tǒng)
存儲(chǔ)系統(tǒng)的選擇有很多,常見(jiàn)的有NFS、Ceph、GlusterFS、FastDFS等,具體使用什么根據(jù)企業(yè)情況而定。在這里使用的是NFS,下面簡(jiǎn)單介紹一下如何安裝。
(1)安裝服務(wù)
$ yum install nfs-utils rpcbind -y
(2)創(chuàng)建共享目錄
$ mkdir /data/k8s -p
(3)配置NFS配置文件
$ vim /etc/exports /data/k8s *(rw,sync,no_root_squash)
(4)啟動(dòng)服務(wù)
$ systemctl start rpcbind $ systemctl start nfs $ systemctl enable rpcbind $ systemctl enable nfs
(5)測(cè)試
$ showmount -e 192.168.205.128 Export list for 192.168.205.128: /data/k8s *
PS:所有節(jié)點(diǎn)都需要安裝NFS客戶(hù)端
PV
PV(Persistent Volume)作為Kubernetes存儲(chǔ)設(shè)備,可以由管理員提前配置,也可以通過(guò)StorageClass來(lái)動(dòng)態(tài)供應(yīng)。
PV是集群資源,可以通過(guò)kubectl explain pv來(lái)查看如何配置,主要包括存儲(chǔ)能力,訪(fǎng)問(wèn)模式,存儲(chǔ)類(lèi)型,回收信息等關(guān)鍵信息。例如:
apiVersion: v1 kind: PersistentVolume metadata: name: my-pv01 labels: storage: pv spec: accessModes: - ReadWriteOnce capacity: storage: 1Gi persistentVolumeReclaimPolicy: Recycle nfs: path: /data/k8s server: 192.168.205.128
參數(shù)說(shuō)明:
(1)、accessMode:訪(fǎng)問(wèn)模式,有ReadWriteOnce,ReadOnlyMany,ReadWriteMany。其中:
- ReadWriteOnce:表示具有讀寫(xiě)權(quán)限,但是只能被一個(gè)node掛載一次
- ReadOnlyMany:表示具有只讀權(quán)限,可以被多個(gè)node多次掛載
- ReadWriteMany:表示具有讀寫(xiě)權(quán)限,可以被多個(gè)node多次掛載
(2)、capacity:持久卷資源和容量的描述,存儲(chǔ)大小是唯一可設(shè)置或請(qǐng)求的資源。
(3)、persistentVolumeReclaimPolicy:回收策略,也就是釋放持久化卷時(shí)的策略,其有以下幾種:
- Retain:保留數(shù)據(jù),如果要清理需要手動(dòng)清理數(shù)據(jù),默認(rèn)的策略;
- Delete:刪除,將從Kubernetes中刪除PV對(duì)象,以及外部基礎(chǔ)設(shè)施中相關(guān)的存儲(chǔ)資產(chǎn),比如AWS EBS, GCE PD, Azure Disk, 或Cinder volume;
- Recycle:回收,清楚PV中的所有數(shù)據(jù),相當(dāng)于執(zhí)行rm -rf /pv-volume/*;
創(chuàng)建過(guò)后,PV的狀態(tài)如下:
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv01 1Gi RWO Recycle Available 5s $ kubectl describe pv my-pv01 Name: my-pv01 Labels: storage=pv Annotations: <none> Finalizers: [kubernetes.io/pv-protection] StorageClass: Status: Available Claim: Reclaim Policy: Recycle Access Modes: RWO VolumeMode: Filesystem Capacity: 1Gi Node Affinity: <none> Message: Source: Type: NFS (an NFS mount that lasts the lifetime of a pod) Server: 192.168.205.128 Path: /data/k8s ReadOnly: false Events: <none>
當(dāng)前PV的狀態(tài)是Available,表示處于隨時(shí)可用狀態(tài)。PV總共有以下四種狀態(tài):
- Available(可用):表示可用狀態(tài),還未被任何 PVC 綁定
- Bound(已綁定):表示 PVC 已經(jīng)被 PVC 綁定
- Released(已釋放):PVC 被刪除,但是資源還未被集群重新聲明
- Failed(失?。罕硎驹?PV 的自動(dòng)回收失敗
單純的創(chuàng)建PV,我們并不能直接使用,需要使用PVC(Persistent Volume Claim)來(lái)進(jìn)行聲明。
PVC
PVC(Persistent Volume Claim)用于表達(dá)用戶(hù)對(duì)存儲(chǔ)的需求,申請(qǐng)PVC會(huì)消耗掉PV的資源,可以通過(guò)kubectl explain pvc
來(lái)查看幫助文檔。
在上一節(jié)我們創(chuàng)建了PV,現(xiàn)在要申明PVC,如下:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-test spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
spec參數(shù)說(shuō)明:
(1)、accessModes:主要定義卷所應(yīng)該擁有的訪(fǎng)問(wèn)模式
(2)、resources:主要定義卷應(yīng)該擁有的最小資源
(3)、dataSource:定義如果提供者具有卷快照功能,就會(huì)創(chuàng)建卷,并將數(shù)據(jù)恢復(fù)到卷中,反之不創(chuàng)建
(4)、selector:定義綁定卷的標(biāo)簽查詢(xún)
(5)、storageClassName:定義的storageClass的名字
(6)、volumeMode:定義卷的類(lèi)型
(7)、volumeName:需要綁定的PV的名稱(chēng)鏈接
創(chuàng)建過(guò)后,查看PV和PVC的狀態(tài),如下:
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-test Bound my-pv01 1Gi RWO 2s $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv01 1Gi RWO Recycle Bound default/pvc-test 20m
我們從上面可以看到pvc處于Bound狀態(tài),Bound的VOLUME是my-pv01,我們?cè)倏磒v的狀態(tài)有Available變?yōu)锽ound,其CLAIM是default/pvc-test,其中default為namespace名稱(chēng)。
在上面我們創(chuàng)建了一個(gè)PVC,其綁定了我們創(chuàng)建的PV,如果此時(shí)我們?cè)賱?chuàng)建一個(gè)PVC,結(jié)果又會(huì)如何?我們copy以下上面的PVC文件,將其名稱(chēng)改一下,如下:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-test2 spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi
然后查看PVC的狀態(tài),如下
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-test Bound my-pv01 1Gi RWO 3m57s pvc-test2 Pending 4s
我們可以看到我們剛創(chuàng)建的pvc-test2的STATUS處于Pending狀態(tài),這是由于集群里聲明的PV都使用完了,PVC在申請(qǐng)的時(shí)候沒(méi)有找到合適的PV,所以處于這個(gè)狀態(tài),這時(shí)候如果我們創(chuàng)建一個(gè)新的并滿(mǎn)足要求的PV,則可以看到這個(gè)PVC會(huì)處于Bound狀態(tài)。如下:
$ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE my-pv01 1Gi RWO Recycle Bound default/pvc-test 27m my-pv02 1Gi RWO Recycle Available 5s $ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-test Bound my-pv01 1Gi RWO 6m50s pvc-test2 Bound my-pv02 1Gi RWO 2m57s
PVC也在申領(lǐng)PV的時(shí)候也不是隨意申領(lǐng)的,它需要符合以下要求:
(1)PVC申領(lǐng)的模式要和PV匹配上,假如PVC的模式是ReadWriteOnce,而PV的模式是ReadWriteMany,則申領(lǐng)部成功。
(2)PVC申領(lǐng)的容量要小于等于PV的容量,否則申請(qǐng)不成功。
(3)一個(gè)PV只能綁定一個(gè)PVC
另外,如果我們的PVC需求的容量小于PV的可用容量,綁定的容量是PV的可用容量。
StorageClass
上面介紹的PV和PVC模式是需要運(yùn)維人員先創(chuàng)建好PV,然后開(kāi)發(fā)人員定義好PVC進(jìn)行一對(duì)一的Bond,但是如果PVC請(qǐng)求成千上萬(wàn),那么就需要?jiǎng)?chuàng)建成千上萬(wàn)的PV,對(duì)于運(yùn)維人員來(lái)說(shuō)維護(hù)成本很高,Kubernetes提供一種自動(dòng)創(chuàng)建PV的機(jī)制,叫StorageClass,它的作用就是創(chuàng)建PV的模板。
具體來(lái)說(shuō),StorageClass會(huì)定義一下兩部分:
- PV的屬性 ,比如存儲(chǔ)的大小、類(lèi)型等;
- 創(chuàng)建這種PV需要使用到的存儲(chǔ)插件,比如Ceph等;
有了這兩部分信息,Kubernetes就能夠根據(jù)用戶(hù)提交的PVC,找到對(duì)應(yīng)的StorageClass,然后Kubernetes就會(huì)調(diào)用 StorageClass聲明的存儲(chǔ)插件,創(chuàng)建出需要的PV。
這里我們以NFS為例,要使用NFS,我們就需要一個(gè)nfs-client的自動(dòng)裝載程序,我們稱(chēng)之為Provisioner,這個(gè)程序會(huì)使用我們已經(jīng)配置好的NFS服務(wù)器自動(dòng)創(chuàng)建持久卷,也就是自動(dòng)幫我們創(chuàng)建PV。說(shuō)明:
- 自動(dòng)創(chuàng)建的PV會(huì)以{pvcName}-${pvName}的目錄格式放到NFS服務(wù)器上;
- 如果這個(gè)PV被回收,則會(huì)以archieved-{pvcName}-${pvName}這樣的格式存放到NFS服務(wù)器上;
安裝NFS Provisioner
(1)創(chuàng)建ServiceAccount,為NFS Provisioner授權(quán)
--- apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: nfs-client-provisioner-clusterrole 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: ["list", "watch", "create", "update", "patch"] - apiGroups: [""] resources: ["endpoints"] verbs: ["create", "delete", "get", "list", "watch", "patch", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: nfs-client-provisioner-clusterrolebinding subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: ClusterRole name: nfs-client-provisioner-clusterrole apiGroup: rbac.authorization.k8s.io
(2)創(chuàng)建NFS Provisioner
--- apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-prosioner spec: replicas: 1 strategy: type: Recreate selector: matchLabels: app: nfs-client-prosioner template: metadata: labels: app: nfs-client-prosioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-prosioner image: registry.cn-hangzhou.aliyuncs.com/rookieops/nfs-client-provisioner:4.0 imagePullPolicy: IfNotPresent volumeMounts: - name: nfs-client-root mountPath: /data/pv env: - name: PROVISIONER_NAME value: rookieops/nfs - name: NFS_SERVER value: 192.168.205.128 - name: NFS_PATH value: /data/k8s volumes: - name: nfs-client-root nfs: server: 192.168.205.128 path: /data/k8s
執(zhí)行完成后,查看NFS Provisioner的狀態(tài),如下:
$ kubectl get po NAME READY STATUS RESTARTS AGE nfs-client-prosioner-54d64dfc85-b4ht4 1/1 Running 0 10s
使用StorageClass
上面已經(jīng)創(chuàng)建好NFS Provisioner,現(xiàn)在我們可以直接創(chuàng)建StroageClass,如下:
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs provisioner: rookieops/nfs
每個(gè) StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 這些字段會(huì)在 StorageClass 需要?jiǎng)討B(tài)分配 PersistentVolume 時(shí)會(huì)使用到。
在配置StorageClass的時(shí)候,如果沒(méi)有指定reclaimPolicy,則默認(rèn)是Delete,除此之外,還有Retain。
StorageClass 對(duì)象的命名很重要,用戶(hù)使用這個(gè)命名來(lái)請(qǐng)求生成一個(gè)特定的類(lèi)。當(dāng)創(chuàng)建 StorageClass 對(duì)象時(shí),管理員設(shè)置 StorageClass 對(duì)象的命名和其他參數(shù),一旦創(chuàng)建了對(duì)象就不能再對(duì)其更新。
使用kubectl apply -f sc.yaml
創(chuàng)建StorageClass,創(chuàng)建完成過(guò)后如下:
$ kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE nfs rookieops/nfs Delete Immediate false 9m41s
現(xiàn)在,我們就可以使用動(dòng)態(tài)存儲(chǔ)申領(lǐng)PVC,如下:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: pvc-from-sc spec: accessModes: - ReadWriteOnce storageClassName: nfs resources: requests: storage: 1Gi
使用kubectl apply -f pvc-from-sc.yaml
,查看PVC創(chuàng)建情況,如下:
$ kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE pvc-from-sc Bound pvc-a4a71b8c-5664-4d1a-b286-9e4adcf6f96a 1Gi RWO nfs 8s $ kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-a4a71b8c-5664-4d1a-b286-9e4adcf6f96a 1Gi RWO Delete Bound default/pvc-from-sc nfs 86s
可以看到自動(dòng)創(chuàng)建了一個(gè)PV,然后和PVC進(jìn)行綁定。
為了方便使用,有時(shí)候會(huì)給集群默認(rèn)設(shè)置一個(gè)StorageClass,以便在需要使用動(dòng)態(tài)存儲(chǔ),但是未聲明的情況下使用默認(rèn)的動(dòng)態(tài)存儲(chǔ)。設(shè)置方式如下:
$ kubectl patch storageclass nfs -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
通過(guò)向其添加 storageclass.kubernetes.io/is-default-class 注解來(lái)將特定的 StorageClass 標(biāo)記為默認(rèn)。當(dāng)集群中存在默認(rèn)的 StorageClass 并且用戶(hù)創(chuàng)建了一個(gè)未指定 storageClassName 的 PersistentVolumeClaim 時(shí), DefaultStorageClass 準(zhǔn)入控制器會(huì)自動(dòng)向其中添加指向默認(rèn)存儲(chǔ)類(lèi)的 storageClassName 字段。
請(qǐng)注意,集群上最多只能有一個(gè) 默認(rèn) 存儲(chǔ)類(lèi),否則無(wú)法創(chuàng)建沒(méi)有明確指定 storageClassName 的 PersistentVolumeClaim。
如果要取消默認(rèn)StorageClass,只需要把注解設(shè)置為flase即可,如下:
$ kubectl patch storageclass nfs -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"false"}}}'
如果我們要在Pod中使用PVC,則直接如下聲明:
apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: nfs-pvc mountPath: /mnt restartPolicy: Never volumes: - name: nfs-pvc persistentVolumeClaim: claimName: pvc-from-sc
可以進(jìn)入容器,到掛載目錄輸出,例如:
$ kubectl exec -it nginx -- /bin/bash root@nginx:/mnt# echo "test" > /mnt/text.txt
然后到NFS對(duì)應(yīng)的目錄查看是否一致。
$ cd /data/k8s/default-pvc-from-sc-pvc-a4a71b8c-5664-4d1a-b286-9e4adcf6f96a $ cat text.txt test
這表示Pod使用持久化成功。
總結(jié)
在Kubernetes中,雖然我們建議使用無(wú)狀態(tài)應(yīng)用,但是對(duì)于有些特殊應(yīng)用,數(shù)據(jù)持久化還是必不可少的。數(shù)據(jù)持久化的難度不在于創(chuàng)建幾個(gè)PV或者PVC,而是后端的存儲(chǔ)系統(tǒng),比如Ceph,如果使用它作為后端存儲(chǔ),你必須對(duì)其非常熟悉,方便在出問(wèn)題的時(shí)候好排查,如果你對(duì)這些存儲(chǔ)系統(tǒng)都不熟悉,在使用的時(shí)候可能會(huì)出現(xiàn)很多問(wèn)題。
原文鏈接:https://juejin.cn/post/7143076394799464478
相關(guān)推薦
- 2023-03-03 AJAX亂碼與異步同步以及封裝jQuery庫(kù)實(shí)現(xiàn)步驟詳解_AJAX相關(guān)
- 2022-12-04 淺析Go語(yǔ)言容器之?dāng)?shù)組和切片的使用_Golang
- 2022-10-11 兩臺(tái)主機(jī)的vmware虛擬機(jī)相互連通的實(shí)現(xiàn)步驟_VMware
- 2022-01-29 fastadmin uniapp跨域的問(wèn)題
- 2022-05-19 C#?漢字與拼音互轉(zhuǎn)的實(shí)現(xiàn)示例_C#教程
- 2022-09-23 Pandas多列值合并成一列的實(shí)現(xiàn)_python
- 2023-04-18 Python中selenium獲取token的方法_python
- 2022-11-01 PyTorch實(shí)現(xiàn)MNIST數(shù)據(jù)集手寫(xiě)數(shù)字識(shí)別詳情_(kāi)python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支