1 volume
1.1 介紹
在容器中的磁盤文件是短暫的,當(dāng)容器崩潰時(shí),Kubelet會(huì)重新啟動(dòng)容器,但容器運(yùn)行時(shí)產(chǎn)生的數(shù)據(jù)文件都將會(huì)丟失,之后容器會(huì)以最干凈的狀態(tài)啟動(dòng)。另外,當(dāng)一個(gè)Pod運(yùn)行多個(gè)容器時(shí),各個(gè)容器可能需要共享一些文件,諸如此類的需求都可以使用Volume解決。Pod只需要通過.spec.volumes字段指定為Pod提供的卷,然后在容器中配置塊,使用.spec.containers.volumeMounts字段指定卷掛載的目錄即可。
在Kubernetes中,Volume也支持配置許多常用的存儲(chǔ),用于掛載到Pod中實(shí)現(xiàn)數(shù)據(jù)的持久化。
Kubernetes Volume支持的卷的類型有很多,以下為常用的卷:
- CephFS
- GlusterFS
- ISCSI
- Cinder
- NFS
- RBD
- HostPath
當(dāng)然,也支持一些Kubernetes獨(dú)有的類型:
- ConfigMap:用于存儲(chǔ)配置文件
- Secret:用于存儲(chǔ)敏感數(shù)據(jù)
- EmptyDir:用于一個(gè)Pod內(nèi)多個(gè)容器的數(shù)據(jù)共享
- PersistentVolumeClaim:對(duì)PersistentVolume的申請(qǐng)
以上列舉的是一些比較常用的類型,其他支持的類型可以查看Volume的官方文檔
https://kubernetes.io/docs/concepts/storage/volumes/
下面介紹集中常見的volume卷。
1.2 emptyDir
EmptyDir是一個(gè)特殊的Volume類型,與上述Volume不同的是,如果刪除Pod,emptyDir卷中的數(shù)據(jù)也將被刪除,所以一般emptyDir用于Pod中的不同Container共享數(shù)據(jù),比如一個(gè)Pod存在兩個(gè)容器A和B,容器A需要使用容器B產(chǎn)生的數(shù)據(jù),此時(shí)可以采用emptyDir共享數(shù)據(jù),類似的使用如Filebeat收集容器內(nèi)程序產(chǎn)生的日志。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir:
sizeLimit: 500Mi
1.3 HostPath
HostPath卷可將節(jié)點(diǎn)上的文件或目錄掛載到Pod上,用于實(shí)現(xiàn)Pod和宿主機(jī)之間的數(shù)據(jù)共享,常用的示例有掛載宿主機(jī)的時(shí)區(qū)至Pod,或者將Pod的日志文件掛載到宿主機(jī)等。
在配置HostPath時(shí),有一個(gè)type的參數(shù),用于表達(dá)不同的掛載類型,HostPath卷常用的type(類型)如下:
- type為空字符串:默認(rèn)選項(xiàng),意味著掛載hostPath卷之前不會(huì)執(zhí)行任何檢查
- DirectoryOrCreate:如果給定的path不存在任何東西,那么將根據(jù)需要?jiǎng)?chuàng)建一個(gè)權(quán)限為0755的空目錄,和Kubelet具有相同的組和權(quán)限
- Directory:目錄必須存在于給定的路徑下
- FileOrCreate:如果給定的路徑不存儲(chǔ)任何內(nèi)容,則會(huì)根據(jù)需要?jiǎng)?chuàng)建一個(gè)空文件,權(quán)限設(shè)置為0644,和Kubelet具有相同的組和所有權(quán)
- File:文件,必須存在于給定路徑中
- Socket:UNIX套接字,必須存在于給定路徑中
- CharDevice:字符設(shè)備,必須存在于給定路徑中
- BlockDevice:塊設(shè)備,必須存在于給定路徑中。
apiVersion: v1
kind: Pod
metadata:
name: hostpath-example-linux
spec:
os: { name: linux }
nodeSelector:
kubernetes.io/os: linux
containers:
- name: example-container
image: registry.k8s.io/test-webserver
volumeMounts:
- mountPath: /foo
name: example-volume
readOnly: true
volumes:
- name: example-volume
# mount /data/foo, but only if that directory already exists
hostPath:
path: /data/foo # directory location on host
type: Directory # this field is optional
1.4 nfs
和emptyDir、HostPath的配置方法類似,NFS的Volume配置也是在Volumes字段中配置的,和emptyDir不同的是,NFS屬于持久化存儲(chǔ)的一種,在Pod刪除或者重啟后,數(shù)據(jù)依舊會(huì)存儲(chǔ)在NFS節(jié)點(diǎn)上。要使用nfs,k8s的node節(jié)點(diǎn)上需要安裝好nfs客戶端軟件。
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: registry.k8s.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /my-nfs-data
name: test-volume
volumes:
- name: test-volume
nfs:
server: my-nfs-server.example.com
path: /my-nfs-volume
readOnly: true
2 PersistentVolume
2.1 介紹
雖然volume實(shí)現(xiàn)了持久化存儲(chǔ),但是諸多高級(jí)特性還是無法實(shí)現(xiàn)。且沒有生命周期的管理。在實(shí)際使用中volume面臨的問題如下:
- 當(dāng)某個(gè)數(shù)據(jù)卷不再被掛載使用時(shí),里面的數(shù)據(jù)如何處理?
- 如果想要實(shí)現(xiàn)只讀掛載如何處理?
- 如果想要只能有一個(gè)Pod掛載如何處理?
為此k8s引入了兩個(gè)新的API資源:PersistentVolume和PersistentVolumeClaim。
- PersistentVolume(簡稱PV)是由Kubernetes管理員設(shè)置的存儲(chǔ)
- PersistentVolumeClaim(簡稱PVC)是對(duì)PV的請(qǐng)求,表示需要什么類型的PV。
和單獨(dú)配置Volume類似,PV也可以使用NFS、GFS、CEPH等常用的存儲(chǔ)后端,并且可以提供更加高級(jí)的配置,比如訪問模式、空間大小以及回收策略等。
目前PV的提供方式有兩種:靜態(tài)或動(dòng)態(tài)。
- 靜態(tài)PV由管理員提前創(chuàng)建
- 動(dòng)態(tài)PV無須提前創(chuàng)建,由storageclass創(chuàng)建
pv屬于集群資源,沒有namespace隔離性。同一個(gè)pv可以被不同namespace中的資源訪問。
pvc有namespace隔離性,只能被同一namespace中的資源使用,創(chuàng)建pvc時(shí)如果不指定namespace,則默認(rèn)創(chuàng)建在default命名空間中
2.2 pv回收策略
當(dāng)用戶使用完volume(pv本質(zhì)上也是volume)時(shí),可以刪除PVC對(duì)象,從而通過回收策略回收pv資源。目前回收策略有以下三種。
- Retain:保留,該策略允許手動(dòng)回收資源,當(dāng)刪除PVC時(shí),PV仍然存在,Volume被視為已釋放,管理員可以手動(dòng)回收卷。不指定回收策略默認(rèn)為retain。
- Recycle(k8s1.14版本開始已廢棄):回收,如果Volume插件支持,Recycle策略會(huì)對(duì)卷執(zhí)行rm -rf清理該P(yáng)V,并使其可用于下一個(gè)新的PVC,目前只有NFS和HostPath支持該策略。
- Delete:刪除,如果Volume插件支持,刪除PVC時(shí)會(huì)同時(shí)刪除PV,動(dòng)態(tài)卷默認(rèn)為Delete,目前支持Delete的存儲(chǔ)后端包括AWS EBS、GCE PD、Azure Disk、OpenStack Cinder等。
對(duì)于 Kubernetes 1.29,僅nfs和hostPath卷類型支持回收。
2.3 pv訪問策略
在實(shí)際使用PV時(shí),可能針對(duì)不同的應(yīng)用會(huì)有不同的訪問策略,比如某類Pod可以讀寫,某類Pod只能讀,或者需要配置是否可以被多個(gè)不同的Pod同時(shí)讀寫等,此時(shí)可以使用PV的訪問策略進(jìn)行簡單控制,目前支持的訪問策略如下:
- ReadWriteOnce:可以被單節(jié)點(diǎn)以讀寫模式掛載,命令行中可以被縮寫為RWO。
- ReadOnlyMany:可以被多個(gè)節(jié)點(diǎn)以只讀模式掛載,命令行中可以被縮寫為ROX。
- ReadWriteMany:可以被多個(gè)節(jié)點(diǎn)以讀寫模式掛載,命令行中可以被縮寫為RWX。
- ReadWriteOncePod:只能被一個(gè)Pod以讀寫的模式掛載,命令中可以被縮寫為RWOP(1.22以上版本)。
雖然PV在創(chuàng)建時(shí)可以指定不同的訪問策略,但是也要后端的存儲(chǔ)支持才行。比如一般情況下大部分塊存儲(chǔ)是不支持ReadWriteMany的,具體后端存儲(chǔ)支持的訪問模式可以參考
https://kubernetes.io/docs/concepts/storage/persistent-volumes/#access-modes。
2.4 基于nfs或nas創(chuàng)建pv
[root@k8s-master01 ~]# cat pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs ##pv名
spec:
capacity:
storage: 5Gi ##pv的容量
volumeMode: Filesystem ##卷的模式,目前支持Filesystem(文件系統(tǒng)) 和 Block(塊),其中Block類型需要后端存儲(chǔ)支持,默認(rèn)為文件系統(tǒng)
accessModes:
- ReadWriteOnce ##pv的訪問模式
persistentVolumeReclaimPolicy: Recycle ##pv的回收策略
storageClassName: nfs-slow ##存儲(chǔ)類型的名稱,pvc通過該名字訪問到pv
nfs: ##pv的類型
path: /data/nfs ##nfs服務(wù)器共享的目錄
server: 172.18.102.233 ##nfs服務(wù)器ip地址
[root@k8s-master01 ~]# kubectl create -f pv-nfs.yaml
persistentvolume/pv-nfs created
[root@k8s-master01 ~]# kubectl get persistentvolume
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pv-nfs 5Gi RWO Recycle Available nfs-slow 14s
2.5 創(chuàng)建hostpath類型的pv
一般不推薦使用該類型的pv,因?yàn)檫@種情況下使用的是宿主機(jī)的一個(gè)目錄,pod和宿主機(jī)強(qiáng)綁定,不再具備高可用性。這種情況下需要利用污點(diǎn),讓pod和宿主機(jī)強(qiáng)綁定。
kind: PersistentVolume
apiVersion: v1
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: hostpath
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
2.6 創(chuàng)建cephrbd類型的pv
需要提前在ceph側(cè)創(chuàng)建好密鑰,具體配置可參考我的另一篇文章
K8S使用開源CEPH作為后端StorageClass
apiVersion: v1
kind: PersistentVolume
metadata:
name: ceph-rbd-pv
spec:
capacity:
storage: 1Gi
storageClassName: ceph-fast
accessModes:
- ReadWriteOnce
rbd:
monitors: ##cephmon節(jié)點(diǎn)的ip,端口通常為6789
- 192.168.1.123:6789
- 192.168.1.124:6789
- 192.168.1.125:6789
pool: rbd ##rbd存儲(chǔ)池的名稱,可以使用ceph osd pool ls查看
image: ceph-rbd-pv-test ##rbd塊名稱,可以使用rbd create POOL_NAME/IMAGE_NAME --size 1024創(chuàng)建,使用rbd list POOL_NAME查看
user: admin #Rados的用戶名,默認(rèn)是admin
secretRef: #用于驗(yàn)證Ceph身份的密鑰
name: ceph-secret
fsType: ext4 #文件類型,可以是ext4、XFS等
readOnly: false #是否是只讀掛載
2.7 pv的狀態(tài)
- Available:可用,沒有被PVC綁定的空閑資源。
- Bound:已綁定,已經(jīng)被PVC綁定。
- Released:已釋放,PVC被刪除,但是資源還未被重新使用。
- Failed:失敗,自動(dòng)回收失敗。
3 PersistentVolumeClaim
pv創(chuàng)建好了,如何使用呢,這時(shí)就需要用到pvc,pvc可以去申請(qǐng)pv資源。
pvc中定義了要使用的存儲(chǔ)類型,存儲(chǔ)空間大小以及存儲(chǔ)的訪問模式,例如申請(qǐng)一個(gè)大小為5Gi且只能被一個(gè)Pod只讀訪問的nfs存儲(chǔ)。
下圖是一個(gè)典型的pod使用pv作為volume的流程。
管理員創(chuàng)建pv,用戶創(chuàng)建pvc和pv進(jìn)行綁定,pod使用pvc申請(qǐng)到的pv資源作為volume來持久化存儲(chǔ)數(shù)據(jù)。
那么pvc和pv是如何進(jìn)行綁定的呢,主要依賴以下參數(shù)
參數(shù) | 描述 |
---|---|
Storageclass | PV 與 PVC 的 storageclass 類名必須相同(或同時(shí)為空)。 |
AccessMode | 主要定義 volume 的訪問模式,PV 與 PVC 的 AccessMode 必須相同。 |
Size | 主要定義 volume 的存儲(chǔ)容量,PVC 中聲明的容量必須小于等于 PV,如果存在多個(gè)滿足條件的 PV,則選擇最小的 PV 與 PVC 綁定。 |
pvc和pv綁定后,我們就可以通過在pod中使用pvc來申請(qǐng)pv資源了。只需要在pod的yaml文件中配置一個(gè)persistentVolumeClaim類型的volumes,claimName配置為PVC的名稱即可
下面詳細(xì)介紹下如何創(chuàng)建和使用pvc
3.1 創(chuàng)建pvc與pv進(jìn)行綁定
3.1.1 創(chuàng)建pv
[root@k8s-master01 ~]# cat pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-nfs
spec:
capacity:
storage: 5Gi #pv的容量
volumeMode: Filesystem
accessModes:
- ReadWriteOnce ##pv的訪問模式
persistentVolumeReclaimPolicy: Recycle
storageClassName: nfs-slow ##存儲(chǔ)類型的名稱,pvc通過該名字訪問到pv
nfs:
path: /data/nfs
server: 172.18.102.233
3.1.2 創(chuàng)建pvc
[root@k8s-master01 ~]# cat nfs-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: nfs-pvc-claim ##pvc名
spec:
storageClassName: nfs-slow ##pv的類名
accessModes:
- ReadWriteOnce ##訪問模式,和pv要一致
resources:
requests:
storage: 3Gi ##請(qǐng)求的容量大小,不能超過pv的大小
檢查是否成功綁定
[root@k8s-master01 ~]# kubectl create -f pv-nfs.yaml
[root@k8s-master01 ~]# kubectl create -f nfs-pvc.yaml
persistentvolumeclaim/nfs-pvc-claim created
[root@k8s-master01 ~]#
[root@k8s-master01 ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nfs-pvc-claim Bound pv-nfs 5Gi RWO nfs-slow 6s
3.2 使用pvc
pod綁定pvc,創(chuàng)建pod時(shí)pvc會(huì)自動(dòng)去pv處申請(qǐng)資源作為pod的volume
[root@k8s-master01 ~]# cat pod-nfs-pvc.yaml
kind: Pod
apiVersion: v1
metadata:
name: nfs-pv-pod
spec:
volumes:
- name: nfs-pv-storage
persistentVolumeClaim:
claimName: nfs-pvc-claim ##和pvc的名稱一致
containers:
- name: nfs-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: nfs-pv-storage
檢查pod是否成功掛載volume資源
[root@k8s-master01 ~]# kubectl create -f pod-nfs-pvc.yaml
pod/nfs-pv-pod created
[root@k8s-master01 ~]# kubectl exec -it nfs-pv-pod -- bash
root@nfs-pv-pod:/# ls /usr/share/nginx/html/
root@nfs-pv-pod:/# df -h
Filesystem Size Used Avail Use% Mounted on
overlay 39G 22G 18G 57% /
tmpfs 64M 0 64M 0% /dev
tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup
shm 64M 0 64M 0% /dev/shm
/dev/vda2 39G 22G 18G 57% /etc/hosts
172.18.102.233:/data/nfs 39G 22G 18G 57% /usr/share/nginx/html
tmpfs 3.8G 12K 3.8G 1% /run/secrets/kubernetes.io/serviceaccount
tmpfs 2.0G 0 2.0G 0% /proc/acpi
tmpfs 2.0G 0 2.0G 0% /proc/scsi
tmpfs 2.0G 0 2.0G 0% /sys/firmware
4 動(dòng)態(tài)存儲(chǔ)storageclass
在介紹pv那一節(jié)我們就提到,創(chuàng)建pv有靜態(tài)和動(dòng)態(tài)兩種方式。前面提到的一直是靜態(tài)創(chuàng)建pv的方式,即管理員手動(dòng)創(chuàng)建pv。這一節(jié)介紹動(dòng)態(tài)創(chuàng)建的方式,即通過storageclass動(dòng)態(tài)創(chuàng)建pv,有了storageclass,我們不需要在手動(dòng)創(chuàng)建pv,只需要?jiǎng)?chuàng)建好storageclass,再將pvs和storageclass綁定,即可通過storageclass動(dòng)態(tài)的創(chuàng)建pv。
每個(gè)storageclass都包含下面幾個(gè)參數(shù)
- provisioner:提供pv卷的存儲(chǔ)類型
- parameters:與后端存儲(chǔ)對(duì)接時(shí)使用的參數(shù),取決于provisioner中指定的存儲(chǔ)。如ceph存儲(chǔ)可以指定cluster id和pool id等。
- reclaimPolicy:指定通過storageclass創(chuàng)建出來的pv的回收策略??梢允?Delete 或者 Retain。如果 StorageClass 對(duì)象被創(chuàng)建時(shí)沒有指定 reclaimPolicy,它將默認(rèn)為 Delete。
- mountOptions:指定掛載選項(xiàng),當(dāng) PV 不支持指定的選項(xiàng)時(shí)會(huì)直接失敗。比如 NFS 支持 hard 和 nfsvers=4.1 等選項(xiàng)。
4.1 創(chuàng)建storageclass
本例使用ceph類型的storageclass
[root@k8s-master02 kubernetes]# cat storageclass.yaml
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-rbd-sc
provisioner: rbd.csi.ceph.com
parameters:
clusterID: 395b7a30-eb33-460d-8e38-524fc48c58cb ##ceph集群ID
pool: k8s ##ceph集群的pool名
imageFeatures: layering ##定義創(chuàng)建的rbd features
csi.storage.k8s.io/provisioner-secret-name: csi-rbd-secret
csi.storage.k8s.io/provisioner-secret-namespace: ceph-csi
csi.storage.k8s.io/controller-expand-secret-name: csi-rbd-secret
csi.storage.k8s.io/controller-expand-secret-namespace: ceph-csi
csi.storage.k8s.io/node-stage-secret-name: csi-rbd-secret
csi.storage.k8s.io/node-stage-secret-namespace: ceph-csi
csi.storage.k8s/fstype: ext4
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard
4.2 創(chuàng)建pvc綁定storageclass
在pvc聲明中指定storageclass的名稱即可綁定
[root@k8s-master01 ~]# cat ceph-csi-release-v3.9/examples/rbd/pvc.yaml
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: rbd-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: csi-rbd-sc ##要與storageclass的名稱一致
創(chuàng)建完成之后,StorageClass會(huì)自動(dòng)創(chuàng)建PV,然后與PVC進(jìn)行綁定。此時(shí)pod和pvc綁定即可使用pv資源作為volume來持久化存儲(chǔ)數(shù)據(jù)。
最后來一張圖解釋storageclass、pvc、pv之間的關(guān)系
前面我們了解到pv的創(chuàng)建有靜態(tài)和動(dòng)態(tài)兩種方式,靜態(tài)即管理員手動(dòng)創(chuàng)建。動(dòng)態(tài)即通過storageclass創(chuàng)建。在動(dòng)態(tài)創(chuàng)建的場景下。我們不需要手動(dòng)創(chuàng)建pv,只需要?jiǎng)?chuàng)建storageclass,storageclass會(huì)和后端存儲(chǔ)綁定。同時(shí)創(chuàng)建pvc和storageclass綁定。在pod的yaml文件中,我們聲明好要使用哪個(gè)pvc。聲明好后,在創(chuàng)建pod時(shí),storageclass會(huì)自動(dòng)根據(jù)pvc里的定義自動(dòng)創(chuàng)建pv,同時(shí)pv和pvc會(huì)自動(dòng)綁定,pv作為存儲(chǔ)資源提供給pod使用。
5 pod刪除后pv中的數(shù)據(jù)會(huì)怎么樣
pod刪除后pv中的數(shù)據(jù)不會(huì)受到影響。只有在pv綁定的pvc被刪除,即pv和pvc的綁定被解除時(shí)。pv中的數(shù)據(jù)可能會(huì)根據(jù)其根據(jù)設(shè)置的回收策略被刪除。
當(dāng)pv的回收策略為retain:pvc刪除后,pv不會(huì)被刪除。如果手動(dòng)將pv刪除,pv對(duì)應(yīng)的后端存儲(chǔ)中的空間也不會(huì)被刪除。如果使用相同的參數(shù)再次創(chuàng)建pv,依然會(huì)使用這段存儲(chǔ)空間。文章來源:http://www.zghlxwxcb.cn/news/detail-840824.html
當(dāng)pv的回收策略為delete時(shí):pvc刪除后,pv會(huì)被刪除。pv中的數(shù)據(jù)是否會(huì)被刪除取決于后端存儲(chǔ)類型,比如測試發(fā)現(xiàn)hostpath類型的pv使用delete回收策略。pv被刪除后,pv中的數(shù)據(jù)不會(huì)被刪除。文章來源地址http://www.zghlxwxcb.cn/news/detail-840824.html
5.1 修改pv的回收策略
[root@k8s-master01 ~]# kubectl patch pv task-pv-volume -p '{"spec":{"persistentVolumeReclaimPolicy":"Delete"}}' ##task-pv-volume為pv名
到了這里,關(guān)于Kubernetes基礎(chǔ)(二十三)-k8s持久化存儲(chǔ)詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!