k8s之StorageClass

Storage Class資源

1,爲何要使用Storage Class?html

  • 以前常規的手動掛載,看似沒有什麼問題,但細想一下,pvc在向pv申請存儲空間時,是根據指定的pv名稱,訪問模式,容量大小來決定具體向那個pv來申請空間的,假設pv的容量爲20G,定義的訪問模式是WRO(只容許以讀寫的方式掛載到單個節點),而pvc申請的存儲空間爲10G,那麼一旦這個pvc是向上面的pv申請的空間,也就是說,那麼pv有10個G的空間被浪費了,由於其只容許被單個節點掛載。就算不考慮這個問題,咱們每次手動去建立pv也就比較麻煩的事情,這時,咱們就須要一個自動化的工具來替咱們建立pv。
  • 這個東西就是阿里提供的一個開源工具「nfs-client-provisioner」,這個東西是經過k8s內置的nfs驅動將遠端的NFS服務器掛載到本地目錄,而後自身做爲storage(存儲)。

2,stroage class在集羣中的做用?node

  • pvc是沒法直接去向nfs-client-provisioner申請使用的存儲空間的,這時,就須要經過SC這個資源對象去申請了,SC的根本做用就是根據pvc定義的來動態建立pv,不只節省了咱們管理員的時間,還能夠封裝不一樣類型的存儲供pvc選用。nginx

  • 每一個sc都包含如下三個重要的字段,這些字段會在sc須要動態分配pv時會使用到:
    Provisioner(供給方):提供了存儲資源的存儲系統。
    ReclaimPolicy:pv的回收策略,可用的值有Delete(默認)和Retiain
    Parameters(參數):存儲類使用參數描述要關聯到存儲卷。

3,下面基於NFS服務來實踐storage class
1)搭建NFS服務(我將master節點做爲nfs server):web

[root@master ~]# yum -y install nfs-utils
[root@master ~]# vim /etc/exports
/nfsdata *(rw,sync,no_root_squash)
[root@master ~]# mkdir /nfsdata    #建立共享目錄
[root@master ~]# systemctl start rpcbind
[root@master ~]# systemctl enable rpcbind
[root@master ~]# systemctl start nfs-server
[root@master ~]# systemctl enable nfs-server
[root@master ~]# showmount -e  #確保成功掛載
Export list for master:
/nfsdata *

2)建立rbac權限:
rbac(基於角色的訪問控制),就是用戶經過角色與權限進行關聯。
是一個從認證-----> 受權-----> 准入機制。docker

[root@master sc]# vim rbac-rolebind.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner
  namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: nfs-provisioner-runner
  namespace: default
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: default
roleRef:
  kind: ClusterRole
  name: nfs-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

//執行yaml文件:vim

[root@master sc]# kubectl apply -f  rbac-rolebind.yaml 
serviceaccount/nfs-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-provisioner created

以上咱們新建的一個名爲nfs-provisioner的ServiceAccount,而後綁定了一個名爲nfs-provisioner-runner的ClusterRole,而該ClusterRole聲明瞭一些權限,其中就包括對pv的增,刪,改,查等權限,因此咱們能夠利用該serviceAccount來自動建立pv。api

3)建立一個nfs的Deployment
將裏面的對應的參數替換成咱們本身的nfs配置。bash

[root@master sc]# vim nfs-deployment.yaml 
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccount: nfs-provisioner
      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: nfs-deploy    #供給方的名稱(自定義)
            - name: NFS_SERVER
              value: 172.16.1.30     #nfs服務器的ip地址
            - name: NFS_PATH
              value: /nfsdata      #nfs共享的目錄
      volumes:  
        - name: nfs-client-root
          nfs:
            server: 172.16.1.30
            path: /nfsdata

//導入nfs-client-provisioner鏡像(集羣中的每一個節點都需導入,包括master)服務器

[root@master sc]# docker load --input  nfs-client-provisioner.tar 
5bef08742407: Loading layer  4.221MB/4.221MB
c21787dcfbf0: Loading layer  2.064MB/2.064MB
00376105a0f3: Loading layer  41.08MB/41.08MB
Loaded image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner:latest

k8s之StorageClass

//執行yaml文件:
[root@master sc]# kubectl apply -f  nfs-deployment.yaml 
deployment.extensions/nfs-client-provisioner created
//確保pod正常運行
[root@master sc]# kubectl  get pod 
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-5457694c8b-k8t4m   1/1     Running   0          23s

nfs-client-provisionser工具的做用:它經過k8s的內置的nfs驅動掛載遠端的nfs服務器到本地目錄,而後將自身做爲storage provide(存儲提供),關聯sc。app

4)建立storage class:

[root@master sc]# vim test-sc.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: statefu-nfs
  namespace: default
provisioner: nfs-deploy  
reclaimPolicy: Retain

咱們聲明瞭一個名爲statefu-nfs的sc對象,注意下面的provisioner字段對應的值必定要和上面的nfs的Deployment下面的PROVISIONER_NAME這個環境變量的值同樣。

//建立該資源對象:

[root@master sc]# kubectl apply -f  test-sc.yaml 
storageclass.storage.k8s.io/statefu-nfs created

5)上面把SC資源對象建立成功了,接下來咱們測試是否可以動態建立pv。
//首先咱們建立一個pvc對象:

[root@master sc]# vim test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: test-claim    
  namespace: default
spec:
  storageClassName: statefu-nfs   #sc必定要指向上面建立的sc名稱
  accessModes:
    - ReadWriteMany   #採用ReadWriteMany的訪問模式
  resources:
    requests:
      storage: 50Mi    #請求50M的空間

//執行yaml文件來建立pvc:

[root@master sc]# kubectl  apply -f  test-pvc.yaml 
persistentvolumeclaim/test-claim created

k8s之StorageClass

咱們能夠看到pvc建立成功,狀態已是Bound了,是否是也生產了一個對應的volume對象,最重要的一欄是STORAGECLASS,如今的值就是咱們剛剛建立的sc對象名稱」statefu-nfs「。

//接下來咱們查看一下pv,驗證是否動態建立:
k8s之StorageClass

咱們能夠看到已經自動生成了一個關聯的pv對象,訪問模式是RWX(在sc中定義的模式),回收策略Delete ,狀態一樣是Bound,是經過sc動態建立的,而並非咱們手動建立的。

4,部署nginx來實踐pv,pvc

咱們經過部署一個nginx服務來測試咱們上面用stroage class方式聲明的pvc對象(實現數據持久化)。

[root@master sc]# vim nginx-pod.yaml
kind: Pod
apiVersion: v1
metadata:
  name: nginx-pod
  namespace: default
spec:
  containers:
    - name: nginx-pod
      image: nginx
      volumeMounts:    #定義數據持久化
        - name: nfs-pvc
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:   #指定pvc,注意下面聲明的pvc指向的是上面定義的pvc名稱
        claimName: test-claim
//運行nginx,並查看pod是否正常運行:
[root@master sc]# kubectl apply -f  nginx-pod.yaml 
pod/nginx-pod created

k8s之StorageClass

//咱們進入pod中,建立測試網頁文件:

[root@master ~]# kubectl  exec  -it nginx-pod /bin/bash
root@nginx-pod:/# cd /usr/share/nginx/html/
root@nginx-pod:/usr/share/nginx/html# echo "<h1>welcome to Storage Class web</h1>" > index.html
root@nginx-pod:/usr/share/nginx/html# cat index.html 
<h1>welcome to Storage Class web</h1>
root@nginx-pod:/usr/share/nginx/html# exit

//咱們回到nfs服務器的共享數據目錄下查看文件是否同步:
k8s之StorageClass

在nfs目錄下咱們能夠能夠看到有名字很很長的文件夾,這個文件夾的命名方式就是咱們上面的規則生成的。

k8s之StorageClass

咱們進入到該目錄下,能夠看到nginx中的數據已經實現同步,且實現了數據持久化(這裏就不作測試了,可自行測試)

最後測試nginx是否可以正常訪問咱們編寫的網頁:
//建立service資源對象,關聯上邊的pod,映射端口號。
一個完整的yaml文件內容以下:

kind: Pod
apiVersion: v1
metadata:
  name: nginx-pod
  namespace: default
  labels:
    app: web
spec:
  containers:
    - name: nginx-pod
      image: nginx
      volumeMounts:
        - name: nfs-pvc
          mountPath: /usr/share/nginx/html
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: test-claim
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
  namespace: default
spec:
  type: NodePort
  selector:
    app: web
  ports:
  - name: nginx
    port: 80
    targetPort: 80
    nodePort: 32134

//從新加載nginx,並訪問網頁:

[root@master sc]# kubectl  apply -f  nginx-pod.yaml 
pod/nginx-pod configured
service/nginx-svc created

k8s之StorageClass

k8s之StorageClass

nginx網頁正常訪問,部署完畢,以上就是Storage Class的使用方法,生產環境中僅有storage class仍是不夠的,其餘的資源對象會在後續中學習到。

相關文章
相關標籤/搜索