Kubernetes數據持久化之Storage Class(自動創建PV)

通過博文Kubernetes的存儲之Volume可以瞭解到Kubernets實現數據持久化的流程爲:
搭建NFS底層存儲——>創建PV——>創建PVC——>創建pod
最終將pod中的container實現數據的持久化!

從上述流程中,看似沒有什麼問題,但是仔細研究就會發現:PVC在向PV申請存儲空間時,是根據指定PV的名稱、訪問模式、容量大小來決定具體向哪個PV申請空間的。

打比方說:如果PV的容量是20G,定義的訪問模式是WRO(只允許以讀寫的方式掛載到單個節點),而PVC申請的存儲空間爲10G,那麼一旦這個PVC是向上述的PV申請的空間,也就是說,那麼PV有10G的空間被白白浪費了,因爲其只允許單個節點掛載。這是一個非常嚴重的問題。就算不考慮這個問題,我們每次手動去創建PV也是比較麻煩的事情,這是就需要使用一個自動化的方案來替我們創建PV。這個自動化的方案就是——Storage Class(存儲類)!

Storage class(存儲類)概述

Storage class(存儲類)是Kubernetes資源類型的一種,它是由管理員爲管理PV更加方便而創建的一個邏輯組,可以按照存儲系統的性能高低、綜合服務質量、備份策略等分類。不過Kubernetes本身並不知道類別到底是什麼,這是一個簡單的描述而已!

存儲類的好處之一就是支持PV的動態創建,當用戶用到持久化存儲時,不必再去提前創建PV,而是直接創建PVC就可以了,非常的方便。同時也避免了空間的浪費!

Storage class(存儲類)三個重要的概念:
1)Provisioner(供給方、提供者):提供了存儲資源的存儲系統。Kubernetes內部多重供給方,這些供給方的名字都以“kubernetes.io”爲前綴。並且還可以自定義;
2)Parameters(參數):存儲類使用參數描述要關聯到的存儲卷,注意不同的供給方參數也不同;
3)ReclaimPlicy:pv的回收策略,可用的值有Delete(默認)和Retain;

下面通過一個nginx基於自動創建PV實現數據持久化的案例進一步的瞭解Storage Class的具體使用!

1)搭建NFS共享存儲

爲了方便,就直接在master節點上部署NFS存儲了!

[root@master ~]# yum -y install nfs-utils rpcbind
[root@master ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl start rpcbind
[root@master ~]# showmount -e
Export list for master:
/nfsdata *

2)創建rbac授權

這種自動創建PV的方式涉及到了rbac授權機制,關於rbac授權機制這裏先不詳細介紹,隨後再更新說明。

[root@master ~]# vim rbac-rolebind.yaml
kind: Namespace              #創建一個名稱空間,名稱爲xiaojiang-test
apiVersion: v1
metadata:
  name: xiaojiang-test
---
apiVersion: v1                            #創建一個用於認證的服務賬號
kind: ServiceAccount
metadata:
  name: nfs-provisioner
  namespace: xiaojiang-test
---
apiVersion: rbac.authorization.k8s.io/v1        #創建羣集規則
kind: ClusterRole
metadata:
  name: nfs-provisioner-runner
  namespace: xiaojiang-test
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: ["watch", "create", "update", "patch"]
   -  apiGroups: [""]
      resources: ["services", "endpoints"]
      verbs: ["get","create","list", "watch","update"]
   -  apiGroups: ["extensions"]
      resources: ["podsecuritypolicies"]
      resourceNames: ["nfs-provisioner"]
      verbs: ["use"]
---
kind: ClusterRoleBinding                #將服務認證用戶與羣集規則進行綁定
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-provisioner
    namespace: xiaojiang-test
roleRef:
  kind: ClusterRole
  name: nfs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
[root@master ~]# kubectl apply -f rbac-rolebind.yaml     #執行yaml文件

3)創建nfs-deployment.資源

nfs-deployment的作用:其實它是一個NFS客戶端。但它通過K8S的內置的NFS驅動掛載遠端的NFS服務器到(容器內)本地目錄;然後將自身作爲storage provider,關聯storage class。

[root@master ~]# vim nfs-deployment.yaml  
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  namespace: xiaojiang-test
spec:
  replicas: 1                              #指定副本數量爲1
  strategy:
    type: Recreate                      #指定策略類型爲重置
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccount: nfs-provisioner            #指定rbac yanl文件中創建的認證用戶賬號
      containers:
        - name: nfs-client-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner     #使用的鏡像 
          volumeMounts:
            - name: nfs-client-root
              mountPath:  /persistentvolumes             #指定容器內掛載的目錄
          env:
            - name: PROVISIONER_NAME           #容器內的變量用於指定提供存儲的名稱
              value: lzj-test 
            - name: NFS_SERVER                      #容器內的變量用於指定nfs服務的IP地址
              value: 192.168.1.1
            - name: NFS_PATH                       #容器內的變量指定nfs服務器對應的目錄
              value: /nfsdata
      volumes:                                                #指定掛載到容器內的nfs的路徑及IP
        - name: nfs-client-root
          nfs:
            server: 192.168.1.1
            path: /nfsdata
[root@master ~]# kubectl apply -f nfs-deployment.yaml                   #執行yaml文件
[root@master ~]# kubectl get pod -n xiaojiang-test 
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-7cf975c58b-sc2qc   1/1     Running   0          6s

4)創建SC(Storage Class)

[root@master ~]# vim test-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: stateful-nfs
  namespace: xiaojiang-test
provisioner: lzj-test                  #這個要和nfs-client-provisioner的env環境變量中的PROVISIONER_NAME的value值對應。
reclaimPolicy: Retain               #指定回收策略爲Retain(手動釋放)
[root@master ~]# kubectl apply -f test-storageclass.yaml

5)創建PVC

[root@master ~]# vim test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-claim
  namespace: xiaojiang-test
spec:
  storageClassName: stateful-nfs              #定義存儲類的名稱,需與SC的名稱對應
  accessModes:
    - ReadWriteMany                        #訪問模式爲RWM
  resources:
    requests:
      storage: 100Mi
[root@master ~]# kubectl apply -f test-pvc.yaml
[root@master ~]# kubectl get pvc -n xiaojiang-test
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim   Bound    pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb   100Mi      RWX            stateful-nfs   14s
#保證pvc的狀態爲Bound,表示關聯成功
[root@master ~]# ls /nfsdata/             #可以看出用於nfs存儲的目錄下生成了一個對應的目錄
xiaojiang-test-test-claim-pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb

至此位置,我們已經實現了根據PVC的申請存儲空間去自動創建PV(本地的nfs共享目錄下已經生成了一個目錄,名字挺長的,是pv+pvc名字定義的目錄名),至於這個PVC申請的空間是給哪個pod使用,這已經無所謂了!

6)創建基於nginx鏡像的Pod

[root@master ~]# vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: myweb
  namespace: xiaojiang-test
spec:
  containers:
  - name: myweb
    image: nginx:latest
    volumeMounts:
    - name: myweb-persistent-storage
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: myweb-persistent-storage
    persistentVolumeClaim:
      claimName: test-claim                  #指定使用的PVC名稱
[root@master ~]# kubectl apply -f nginx-pod.yaml            
[root@master ~]# kubectl get pod -n xiaojiang-test 
NAME                                      READY   STATUS    RESTARTS   AGE
myweb                                     1/1     Running   0          38s
nfs-client-provisioner-7cf975c58b-sc2qc   1/1     Running   0          60m

7)測試驗證

[root@master ~]# kubectl exec -it myweb -n xiaojiang-test /bin/bash
root@myweb:/# cd /usr/share/nginx/html/
root@myweb:/usr/share/nginx/html# echo "hello world" > index.html
#進入容器插入數據進行測試
[root@master ~]# cat /nfsdata/xiaojiang-test-test-claim-pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb/index.html 
hello world
#本地目錄測試沒有問題
[root@master ~]# kubectl exec -it nfs-client-provisioner-7cf975c58b-sc2qc -n xiaojiang-test /bin/sh
/ # ls nfs-client-provisioner 
nfs-client-provisioner                        #自動創建pv的可執行程序
/ # cat /persistentvolumes/xiaojiang-test-test-claim-pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb/index.html 
hello world
#nfs-client容器對應的目錄數據也是存在的

從以上測試就可以看出:nginx容器內的網頁目錄就、本地的nfs共享目錄、nfs-client容器中的目錄就全部關聯起來了。

————————————本文到此結束,感謝閱讀————————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章