1. 程式人生 > >k8s(十一)、分散式儲存Cephfs使用

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項