k8s 網絡持久化存儲之StorageClass(如何一步步實現動態持久化存儲)

StorageClass的作用:

創建pv時,先要創建各種固定大小的PV,而這些PV都是手動創建的,當業務量上來時,需要創建很多的PV,過程非常麻煩。
而且開發人員在申請PVC資源時,還不一定有匹配條件的PV可用,這又帶來了新的問題。
於是Kubernetes提供了StorageClass來動態創建PV,StorageClass大大簡化了PV的創建過程。
當申請PVC資源時, 如果匹配到滿足條件的StorageClass,還會自動為PVC創建對應大小的 PV並進行綁定。

下面就來仔細講講現在如何一步步的通過創建StorageClass動態創建PV從而實現持久化存儲的。

網絡存儲卷

Kubernetes是分佈式容器集群,如何在多個Pod之間或多 個Node之間進行數據存儲和共享是非常重要的問題。

Kubernetes引入了網絡存儲卷,它支持為數眾多的雲提供商的產品和網絡存儲方案,如 NFS/iSCSI/GlusterFS/RDB/azureDisk/flocker等

網絡存儲卷還能夠 滿足持久化數據的要求,這些數據將永久保存。

網絡存儲卷是集成各種第三方的存儲系統,不同的服務商提供的配置有一些不同,NFS只是其中一種。

一. 安裝NFS

安裝NFS服務器

資源有限,此處我選擇了master作為NFS服務器

安裝NFS服務器應用:yum install -y nfs-utils rpcbind

image

創建NFS共享目錄:mkdir -p /data/k8snfs

編輯NFS配置文件:vim /etc/exports

image
image

重啟服務:

image

檢查服務器端是否正常加載 了/etc/exports的配置:

image
注意:如果使用雲服務器,需要開放一下端口,否則客戶端連接不上。使用:rpcinfo -p 查看需要開放的端口。注意有tcp和udp:
image

安裝NFS客戶端

注意:每台需要使用NFS的Node都需要安裝NFS

安裝客戶端:yum install -y nfs-utils

檢查是否能訪問遠端的NFS服務器:sudo showmount -e {NFS服務器IP地址}

image
如果出現clnt_create: RPC: Port mapper failure – Timed out,使用雲服務的話大概率是接口沒開放。

持久存儲卷

Kubernetes支持為數眾多的 雲提供商和網絡存儲方案,如 NFS/iSCSI/GlusterFS/RDB/azureDisk/flocker等。但因為網絡存儲卷 通常是集成各種第三方的存儲系統,所以在配置上各有差別。

不同的存儲的配置參數不太一樣,這些參數應該是存儲管理員關注的,而非開發人員,Kubernetes提供了3種基於存儲的抽象對象—— PersistentVolume(PV)、StorageClass和 PersistentVolumeClaim(PVC),以支持基礎設施和應用之間的分離。

存儲管理人員設置 PV或StorageClass,並在裏面配置存儲系統和參數

開發人員只 需要創建PVC來申請指定空間的資源以存儲與共享數據即可,無須再關 注存儲的具體實現和操作。

當刪除PVC時,它寫入具體存儲資源中的數據可以根據回收策略自動清理。
image

PV和PVC

PV表示持久存儲卷,定義了Kubernetes集群中可用的存儲資源, 其中包含存儲資源實現的細節,如包含如何使用 NFS/iSCSI/GlusterFS/RDB/azureDisk/flocker 等資源的具體設置。

PVC表示持久存儲卷的申請,是由用戶發起的對存儲資源的請求。 申請中只包含請求資源的大小和讀寫訪問模式,無須關注具體的資源 實現細節,Kubernetes會自動為其綁定符合條件的PV

二.部署StorageClass

StorageClass是通過存儲分配器(provisioner)來動態分配PV 的,但是Kubernetes官方內置的存儲分配器並不支持NFS,所以需要額外安裝NFS存儲分配器。

1. 安裝NFS存儲分配器

第一步:設置存儲分配器的權限

因為storage自動創建pv需要經過kube-apiserver,所以要進行授權

在node節點創建nfs-client-provisioner-authority.yaml文件

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  namespace: default
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: default
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  namespace: default
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io

image

第二步:安裝NFS存儲分配器

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  namespace: default
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME  # 存儲分配器的默認名稱
              value: fuseim.pri/ifs  
            - name: NFS_SERVER    # NFS服務器地址
              value: xx.xx.236.113
            - name: NFS_PATH       # NFS共享目錄地址
              value: /data/k8snfs
      volumes:
        - name: nfs-client-root
          nfs:
            server: xx.xx.236.113  # NFS服務器地址
            path: /data/k8snfs     # NFS共享目錄

image

image

第三步: 創建StorageClass

創建nfs-storage-class.yml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage   # StorageClass名稱

  # 存儲分配器名稱
provisioner: fuseim.pri/ifs  # 對應「nfs-client-provisioner.yaml」文件中env.PROVISIONER_NAME.value

  # 允許pvc創建後擴容
allowVolumeExpansion: True

parameters:
  archiveOnDelete: "false"  # 資源刪除策略,「true」表示刪除PVC時,同時刪除綁定的PV,false刪除PVC時,對應的PV不會刪除

image

創建PVC

StorageClass 創建完成後就可以創建 PVC 了。
創建:testpvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: testpvc
spec:
  accessModes:
    - ReadWriteMany
  storageClassName: "managed-nfs-storage"
  resources:
    requests:
      storage: 500Mi

image
此時發現,pvc一直是pending狀態,並沒有默認分配PV。 分析,可能是存儲分配器除了問題
image
selfLink was empty 在k8s集群 v1.20之前都存在,在v1.20之後被刪除,需要在/etc/kubernetes/manifests/kube-apiserver.yaml 添加參數 - --feature-gates=RemoveSelfLink=false
如下所示:
image
image
稍等一會,再進行查看PV和PVC
image
可以看到PV已經被自動創建,且PV,PVC的狀態已經均為綁定狀態。

NFS和PV,PVC關係圖:

image

本文參考博客://blog.csdn.net/zhang19903848257/article/details/125887017

Tags: