本篇文章將介紹如何將cephfs的一個目錄共享給多個pod使用,更進一步,多個pod之間雖共享一個目錄拜秧,但可以隔離使用。
寫這篇文章的起因是業(yè)務部門有多個云原生應用同時產(chǎn)生日志章郁。這些日志放到一個大的目錄下管理比如logs/枉氮,并且不同的應用所產(chǎn)生的日志存放在不同的目錄下志衍。
靜態(tài)方式 VS 動態(tài)方式
k8s訪問cephfs的方式之一便是通過ceph-csi訪問。ceph-csi提供了動態(tài)和靜態(tài)的方式聊替。
靜態(tài)方式由存儲管理員顯式地創(chuàng)建pv楼肪,開發(fā)者通過pvc獲得符合容量要求和訪問模式的pv,并和pod關聯(lián)惹悄,達到使用存儲的要求春叫。但這樣存在一些弊端,比如需要使用不同的pv時泣港,管理員要分別手動構建pv暂殖。
動態(tài)方式存儲管理員不需要顯式地創(chuàng)建pv,而是創(chuàng)建storageClass当纱。由開發(fā)者聲明pvc呛每,由storageClass生成合適的pv。但是pv關聯(lián)的路徑使用uuid規(guī)則創(chuàng)建坡氯,如需將后臺存儲的目錄和pod對應并不是很直觀晨横。
實驗環(huán)境
搭建了一個minikube的k8s系統(tǒng)環(huán)境(版本V1.21.0)和ceph存儲(版本16.2.4),完成ceph-csi的配置箫柳。
一手形、靜態(tài)方式
不需要配置storageClass。只需要配置一個pv悯恍、一個pvc和兩個pod叁幢。
1、創(chuàng)建cephfs的子卷
在cephfs后端創(chuàng)建一個可使用的子卷坪稽,實質上是在cephfs內的/volumes(該目錄是ceph-csi默認使用的目錄)下面創(chuàng)建一系列子目錄用來共享曼玩。
首先創(chuàng)建一個子卷的組(相當于創(chuàng)建一個上層目錄,后面的子卷都是該目錄下的子目錄)窒百。命令如下:
ceph fs subvolumegroup create cephfs data
該命令的源格式為:
ceph fs subvolumegroup create <文件系統(tǒng)名稱> <子卷使用組>
這條命令簡單的效果是在cephfs后臺會創(chuàng)建一個/volumes/data
的路徑黍判。以后所有屬于該組的子卷都在該目錄下。
然后創(chuàng)建一個子卷名稱為data篙梢,該卷的大小為1GB大小顷帖,size的單位是bytes。命令如下:
ceph fs subvolume create cephfs logs data --size=1073741824
該命令的源格式為:
ceph fs subvolume create <文件系統(tǒng)名稱> <子卷名稱> <子卷組> --size=<大小>
文件系統(tǒng)后臺實際創(chuàng)建 /volumes/data/logs/dda798fb-2160-4aca-b810-3bbf7bbdd394
渤滞,即在子卷下面還有一個子目錄贬墩,目錄使用uuid命名。該uuid命名的目錄配置了和size一致的配額妄呕。即pv的大小陶舞。
2、創(chuàng)建pv
該pv文件名稱為cephfs-static-pv1.yaml
绪励。pv里的內容:
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: cephfs-static-pv1
spec:
accessModes:
- ReadWriteMany
capacity:
storage: 1Gi
storageClassName: standard
csi:
driver: cephfs.csi.ceph.com
nodeStageSecretRef:
name: csi-cephfs-secret
namespace: default
volumeAttributes:
"clusterID": "9b5661df-078e-448c-a97a-c8264a595623"
"fsName": "cephfs"
"staticVolume": "true"
"rootPath": /volumes/data/logs/dda798fb-2160-4aca-b810-3bbf7bbdd394
"mounter": fuse
"fuseMountOptions": debug
volumeHandle: cephfs-static-pv1
persistentVolumeReclaimPolicy: Retain
volumeMode: Filesystem
參數(shù)說明
名稱 | 說明 | 一般取值 |
---|---|---|
clusterID | ceph集群的ID | 通過ceph -s獲取 |
fsName | 文件系統(tǒng)名稱 | 通過ceph fs ls獲取 |
staticVolume | 是否為靜態(tài)的卷 | true為是 |
rootPath | ceph集群中的實際路徑 | 通過getpath命令獲取 |
mounter | 使用何種方式掛載 | 有fuse和kernel方式肿孵,對應fuse客戶端和kernel客戶端 |
需要說明的幾點
1唠粥、storageClassName: standard
,如果不加該句停做,pvc在apply之后會一直處于pending狀態(tài)晤愧,通過describe pvc 可以看到“Cannot bind to requested volume storageClassName: does not match”的消息。官方文檔少了這條說明蛉腌。
2官份、persistentVolumeReclaimPolicy: Retain
,當pvc被釋放后烙丛,PV將會被保留(不清理和刪除)贯吓。
3、rootPath可以通過getpath命令獲仁癖洹:ceph fs subvolume getpath cephfs logs data
,源命令格式為ceph fs subvolume getpath <文件系統(tǒng)名稱> <子卷名稱> <子卷組>
介评。獲取命令的結果帶來uuid的子目錄库北,這個uuid目錄是帶配額的,該配額和pv中描述的大小一致们陆。
4寒瓦、刪除pv和pvc不會刪除文件系統(tǒng)后臺的子卷,需要額外執(zhí)行命令刪除坪仇。
應用該靜態(tài)pv
minikube kubectl -- apply -f cephfs-static-pv1.yaml
結果
3杂腰、創(chuàng)建PVC
在pod創(chuàng)建前創(chuàng)建pvc,該pvc名稱為cephfs-static-pvc1.yaml椅文。volumeName和以上創(chuàng)建的pv相對應喂很。
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: cephfs-static-pvc1
namespace: default
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
volumeMode: Filesystem
# volumeName should be same as PV name
volumeName: cephfs-static-pv1
應用該pvc
minikube kubectl -- apply -f cephfs-static-pvc.yaml
查看所創(chuàng)建的pvc
4、創(chuàng)建pod
創(chuàng)建兩個pod分別使用logs/data/dda798fb-2160-4aca-b810-3bbf7bbdd394
目錄下面的dir4
目錄和dir5
目錄皆刺。每次在創(chuàng)建pod的時候需要指定一個subPath少辣。
第一個pod配置,指定使用dir4目錄羡蛾。
---
apiVersion: v1
kind: Pod
metadata:
name: csi-cephfs-demo-pod4
spec:
containers:
- name: web-server1
image: quay.io/jitesoft/nginx:1.20.0
volumeMounts:
- name: myfs1
mountPath: /var/lib/www
subPath: dir4
volumes:
- name: myfs1
persistentVolumeClaim:
claimName: cephfs-static-pvc1
readOnly: false
使用volumeMounts中的參數(shù)subPath
漓帅。subPath
在實際存儲后端會建立一個子目錄,可以使容器在掛載數(shù)據(jù)卷時指向數(shù)據(jù)卷內部的一個子路徑痴怨,而不是直接指向數(shù)據(jù)卷的根路徑忙干。第二個pod配置。指定使用dir5目錄浪藻。
---
apiVersion: v1
kind: Pod
metadata:
name: csi-cephfs-demo-pod5
spec:
containers:
- name: web-server1
image: quay.io/jitesoft/nginx:1.20.0
volumeMounts:
- name: myfs1
mountPath: /var/lib/www
subPath: dir5
volumes:
- name: myfs1
persistentVolumeClaim:
claimName: cephfs-static-pvc1
readOnly: false
兩個pod創(chuàng)建后捐迫,在ceph后臺可以看到路徑如下
查看掛載情況
minikube kubectl -- exec -it csi-cephfs-demo-pod2 -- /bin/sh -c "df"
在兩個pod內各創(chuàng)建一個文件
minikube kubectl -- exec -it csi-cephfs-demo-pod4 -- /bin/sh -c "touch /var/lib/www/a.txt"
minikube kubectl -- exec -it csi-cephfs-demo-pod5 -- /bin/sh -c "touch /var/lib/www/b.txt"
使用查看命令,可以看到每個pod的/var/lib/www
中只有自己創(chuàng)建的內容爱葵。
cephfs文件系統(tǒng)后端也分別在兩個目錄內創(chuàng)建了對應的文件
二弓乙、動態(tài)方式
創(chuàng)建一個storageClass和pvc末融,這里省去兩個pod的創(chuàng)建過程。
1暇韧、storageClass配置
動態(tài)的storageClass配置如下:
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: csi-cephfs-sc
provisioner: cephfs.csi.ceph.com
parameters:
clusterID: 9b5661df-078e-448c-a97a-c8264a595623
fsName: cephfs
pool: cephfs_data
csi.storage.k8s.io/provisioner-secret-name: csi-cephfs-secret
csi.storage.k8s.io/provisioner-secret-namespace: default
csi.storage.k8s.io/controller-expand-secret-name: csi-cephfs-secret
csi.storage.k8s.io/controller-expand-secret-namespace: default
csi.storage.k8s.io/node-stage-secret-name: csi-cephfs-secret
csi.storage.k8s.io/node-stage-secret-namespace: default
reclaimPolicy: Delete
allowVolumeExpansion: true
mountOptions:
- discard
名稱 | 說明 | 一般取值 |
---|---|---|
clusterID | ceph集群的ID | 通過ceph -s獲取 |
fsName | 文件系統(tǒng)名稱 | 通過ceph fs ls獲取 |
pool | 所使用的數(shù)據(jù)池 | 不同的池對應不同的存儲規(guī)則勾习,比如存儲介質或故障域 |
volumeNamePrefix | 動態(tài)卷的前綴 | 一般是csi-開頭 |
mounter | 使用何種方式掛載 | 有fuse和kernel方式,對應fuse客戶端和kernel客戶端 |
kernelMountOptions | 內核掛載的參數(shù) | readdir_max_bytes=1048576,norbytes |
2懈玻、pvc的配置
pvc的配置
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: csi-cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
storageClassName: csi-cephfs-sc
在底層文件系統(tǒng)中展現(xiàn)的結構/volumes/csi/csi-vol-<uuid>/<uuid>
兩次uuid的值不相同巧婶。
3、pod創(chuàng)建
pod創(chuàng)建過程類似涂乌,修改claimName
內的pvc內容艺栈。
三、寫在最后
動態(tài)的方式使用uuid分配湾盒,底層路徑和pod之間的關系不那么明顯湿右,使用靜態(tài)卷+subPath的方式能夠預知到所使用的路徑,也做到了應用之間的隔離罚勾。
目前發(fā)現(xiàn)的一個問題是無論用kernel方式還是fuse方式掛載毅人,在一個Node上對應某個卷的掛載點只有一個,多個pod會同時訪問一個客戶端程序尖殃≌奢海可能造成caps過多,性能競爭的問題送丰。(以下是通過ceph daemon session ls
查看到的結果缔俄。在我的例子中兩個pod共用一個ceph-fuse客戶端)
"client_metadata": {
"features": "0x000000000000ffff",
"ceph_sha1": "3cbe25cde3cfa028984618ad32de9edc4c1eaed0",
"ceph_version": "ceph version 16.2.4 (3cbe25cde3cfa028984618ad32de9edc4c1eaed0) pacific (stable)",
"entity_id": "admin",
"hostname": "minikube",
"mount_point": "/var/lib/kubelet/plugins/kubernetes.io/csi/pv/cephfs-static-pv1/globalmount",
"pid": "24452",
"root": "/volumes/data/logs"
}