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
創建NFS共享目錄:mkdir -p /data/k8snfs
編輯NFS配置文件:vim /etc/exports
重啟服務:
檢查服務器端是否正常加載 了/etc/exports的配置:
注意:如果使用雲服務器,需要開放一下端口,否則客戶端連接不上。使用:rpcinfo -p 查看需要開放的端口。注意有tcp和udp:
安裝NFS客戶端
注意:每台需要使用NFS的Node都需要安裝NFS
安裝客戶端:yum install -y nfs-utils
檢查是否能訪問遠端的NFS服務器:sudo showmount -e {NFS服務器IP地址}
如果出現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時,它寫入具體存儲資源中的數據可以根據回收策略自動清理。
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
第二步:安裝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共享目錄
第三步: 創建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不會刪除
創建PVC
StorageClass 創建完成後就可以創建 PVC 了。
創建:testpvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: testpvc
spec:
accessModes:
- ReadWriteMany
storageClassName: "managed-nfs-storage"
resources:
requests:
storage: 500Mi
此時發現,pvc一直是pending狀態,並沒有默認分配PV。 分析,可能是存儲分配器除了問題
selfLink was empty 在k8s集群 v1.20之前都存在,在v1.20之後被刪除,需要在/etc/kubernetes/manifests/kube-apiserver.yaml
添加參數 - --feature-gates=RemoveSelfLink=false
如下所示:
稍等一會,再進行查看PV和PVC
可以看到PV已經被自動創建,且PV,PVC的狀態已經均為綁定狀態。
NFS和PV,PVC關係圖:
本文參考博客://blog.csdn.net/zhang19903848257/article/details/125887017