k8s(十一)、分散式儲存Cephfs使用
前言
在前篇部署測試完cephfs的基礎上: Ceph叢集生產環境安裝部署 cephfs調優 & 效能測試 & 常用命令 本篇介紹k8s使用 pv/pvc的方式使用cephfs分散式檔案系統
使用
首先解釋一下pv/pvc的相關概念: PV: PersistentVolumes,是k8s抽象化的儲存資源,主要包括儲存能力、訪問模式、儲存型別、回收策略等關鍵資訊 [Access Mode] (接入模式): ReadWriteOnce(RWO):讀寫許可權,但是隻能被單個節點掛載 ReadOnlyMany(ROX):只讀許可權,可以被多個節點掛載 ReadWriteMany(RWX):讀寫許可權,可以被多個節點掛載
[persistentVolumeReclaimPolicy](回收策略): Retain(保留)- 保留資料,不會再分配給pvc,需要管理員手工清理資料 Recycle(回收)- 清除 PV 中的資料,保留pv資源,可以留供其他pvc使用 Delete(刪除)- 刪除整個pv資源及內部的資料。
PVC: PersistentVolumeClaims,是對PV資源的一種宣告,pvc繫結實體資源pv後,pod通過繫結pvc來使用pv資源.
依賴安裝: 每個node需要安裝ceph-common包,才能正常使用cephfs:
yum -y install ceph-common
建立secret: 在建立pv前,由於ceph是開啟了cephx認證的,於是首先需要建立secret資源,k8s的secret資源採用的是base64加密 在ceph monitor上提取key:
# ceph auth get-key client.admin |base64
QVFCL3E1ZGIvWFdxS1JBQTUyV0ZCUkxldnRjQzNidTFHZXlVYnc9PQ==
# cat ceph-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: ceph-secret
data:
key: QVFCL3E1ZGIvWFdxS1JBQTUyV0ZCUkxldnRjQzNidTFHZXlVYnc9PQ==
~/ceph# kubectl apply -f ceph-secret.yaml
建立測試pv:
# cat cephfs-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: cephfs-pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
cephfs:
monitors:
- 192.168.20.112:6789
- 192.168.20.113:6789
- 192.168.20.114:6789
user: admin
secretRef:
name: ceph-secret
readOnly: false
persistentVolumeReclaimPolicy: Delete
檢視:
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
cephfs-pv 1Gi RWX Delete Available 6s
現在pvc是空閒Available狀態
建立測試pvc:
# cat cephfs-pvc.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: cephfs-pvc
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
檢視:
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
cephfs-pvc Bound cephfs-pv 1Gi RWX 24s
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
cephfs-pv 1Gi RWX Delete Bound default/cephfs-pvc 8m
可以看到pv和pvc都已經自動變為Bound狀態,但是我們這裡沒有使用任何關聯標籤,使它們兩者進行關聯,pvc是怎麼自動繫結到pv的呢?其實pvc在建立伊始就會主動去尋找符合requets條件的pv資源,如果尋找到了,便會自動進行繫結,無需做標籤匹配.
小Tips: 1.當pv的容量大於pvc的需求時,pvc可以成功自動繫結pv; 2.當pv的容量小於pvc的需求時,pvc無法繫結該pv; 3.pv和pvc的繫結關係是一一對應的. 4.pv/pvc的建立順序是:pv -> pvc -> pod 5.pv/pvc的銷燬順序是:pod -> pvc -> pv,順序一定不要錯 例如: 2G的pv可以被1G的pvc繫結,並且繫結成功後,pvc的實際空間也是2G而不是1G; 1G的pv無法被2G的pvc繫結
建立pod例項 將pod排程到某一個node上,掛載pvc
[email protected]:~/ceph# cat testpod1-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: testpod1
name: testpod1
namespace: default
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/amazondev
spec:
replicas: 1
selector:
matchLabels:
app: testpod1
template:
metadata:
labels:
app: testpod1
spec:
containers:
- args:
- /bin/bash
- -c
- /run.sh
image: registry.youkeshu.com:5000/nginx:php7.1v1
imagePullPolicy: Always
name: testpod1
ports:
- containerPort: 80
protocol: TCP
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/www
name: cephfs-testpod1
dnsPolicy: ClusterFirst
nodeSelector:
DEVNODE: ""
restartPolicy: Always
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: cephfs-testpod1
persistentVolumeClaim:
claimName: cephfs-pvc
檢視pod:
~# kubectl get pods | grep testpod1
testpod1-7847858587-2rbsq 1/1 Running 0 10s
進入pod並給nginx新增一個主頁index.html:
~# kubectl exec -it testpod1-7847858587-2rbsq bash
~# echo "Just for pv/pvc test" > /var/www/index.html
獲取pod ip開啟瀏覽器測試: (本篇測試場景外部與叢集內部網段路由都已互通,如果pod內部路由未通,需要使用svc的方式暴露服務,可檢視此前文章,這裡不再贅述):
到這裡,檔案系統掛載已經測試完畢,但選用cephfs作k8s分散式檔案系統的最大優勢是因為其支援ReadWriteMany多節點掛載的靈活性,非常符合k8s**像管理牲口一樣管理你的容器**的理念,下面開始跨節點測試
跨節點測試
再建立一個部署檔案,讓其在另外的node上執行,與上方pod共用一個pvc:
~/ceph# cat testpod2-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: testpod2
name: testpod2
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: testpod2
template:
metadata:
labels:
app: testpod2
spec:
containers:
- args:
- /bin/bash
- -c
- /run.sh
image: registry.youkeshu.com:5000/nginx:php7.1v1
imagePullPolicy: Always
name: testpod2
ports:
- containerPort: 80
protocol: TCP
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/www
name: cephfs-testpod2
dnsPolicy: ClusterFirst
nodeSelector:
PRODNODE: ""
restartPolicy: Always
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: cephfs-testpod2
persistentVolumeClaim:
claimName: cephfs-pvc
檢視pod:
~/ceph# kubectl get pods -o wide | grep testpod
testpod1-7847858587-2rbsq 1/1 Running 0 17m 172.26.2.172 yksp009029
testpod2-6d4b8d5db9-wkpx6 1/1 Running 0 9s 172.26.0.52 yksp009028
瀏覽器開啟testpod2主頁:
結論: cephfs可以很好的實現k8s多節點排程容器時對持久化檔案的掛載支援
注意
以上方式使用時,會將容器內的指定路徑直接掛載到cephfs的根目錄下,前往上篇文章中掛載mount cephfs的節點掛載目錄就可以發現此問題:
[root@yksp020112 cephfs]# ls
index.html testfile
[root@yksp020112 cephfs]# cat index.html
Just for pv/pvc test
如果所有的檔案都這樣直接放在整個cephfs檔案系統的根目錄裡,無疑是極不好管理的,這個時候我們可以在 Pod 中使用一個新的屬性: subPath,該屬性可以來解決這個問題,我們只需要更改上面的 Pod 的 YAML 檔案即可
修改後的yaml檔案:
[email protected]:~/ceph# cat testpod1-deploy.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: testpod1
name: testpod1
namespace: default
selfLink: /apis/extensions/v1beta1/namespaces/default/deployments/amazondev
spec:
replicas: 1
selector:
matchLabels:
app: testpod1
template:
metadata:
labels:
app: testpod1
spec:
containers:
- args:
- /bin/bash
- -c
- /run.sh
image: registry.youkeshu.com:5000/nginx:php7.1v1
imagePullPolicy: Always
name: testpod1
ports:
- containerPort: 80
protocol: TCP
terminationMessagePath: /dev/termination-log
volumeMounts:
- mountPath: /var/www
name: cephfs-testpod1
# 僅新增這一行即可
subPath: testpod1
dnsPolicy: ClusterFirst
nodeSelector:
DEVNODE: ""
restartPolicy: Always
securityContext: {}
terminationGracePeriodSeconds: 30
volumes:
- name: cephfs-testpod1
persistentVolumeClaim:
claimName: cephfs-pvc
重新部署後,再回到掛載點檢視:
[root@yksp020112 cephfs]# ls
index.html testfile testpod1
[root@yksp020112 cephfs]# ls testpod1/
[root@yksp020112 cephfs]#
[root@yksp020112 cephfs]# ll testpod1/
total 0
可以看到,這裡建立了一個subPath名的目錄,但是目錄裡面是空的,也即是說,通過k8s的抽象層pvc,容器對cephfs的根目錄擁有了指定容量的使用許可權,subPath僅僅是在cephfs根目錄下建立了一個子目錄,無論是否建立子目錄,容器對cephfs的根目錄都擁有使用許可權,因此,為了避免多個容器同名檔案衝突,便於管理維護,請在實際使用中一定不要忘記在部署檔案中新增subPath項