k8s 之storageclass存储类
1.storageclass(存储类)概念
storageclass是一个存储类,k8s集群管理员通过创建storageclass可以动态生成一个存储卷供k8s用户使用。
2.storageclass资源定义
每个StorageClass都包含字段provisioner,parameters和reclaimPolicy,当需要动态配置属于该类的PersistentVolume时使用这些字段。
StorageClass对象的名称很重要,是用户可以请求特定类的方式。 管理员在首次创建StorageClass对象时设置类的名称和其他参数,并且在创建对象后无法更新这些对象。
管理员可以为不请求任何特定类绑定的PVC指定默认的StorageClass
1 2 3 4 5 6 7 8 9 10 11 | apiVersion: storage.k8s.io /v1 kind: StorageClass metadata: name: standard provisioner: kubernetes.io /aws-ebs parameters: type : gp2 reclaimPolicy: Retain mountOptions: - debug volumeBindingMode: Immediate |
provisioner 指定支持的存储供应商
provisioner既可以是内部供应程序,也可以由外部供应商提供,如果是外部供应商可以参考https://github.com/kubernetes-incubator/external-storage/下提供的方法创建storageclass的provisioner,例如,NFS不提供内部配置程序,但可以使用外部配置程序。 一些外部供应商列在存储库https://github.com/kubernetes-incubator/external-storage下。
- Reclaim Policy(回收策略)
由存储类动态创建持久化存储卷(pv)时可以指定reclaimPolicy字段,这个字段中指定的回收策略可以是Delete或Retain(回收)。 如果在创建StorageClass对象时未指定reclaimPolicy,则默认为Delete。
- Mount Options(挂载选项)
如果Volume Plugin不支持这个挂载选项,但是指定了,就会使provisioner创建失败
- Volume Binding Mode(卷绑定模式)
这个字段用来说明什么时候进行卷绑定和动态配置;
默认情况下,立即模式表示一旦创建了PersistentVolumeClaim,就会发生卷绑定和动态配置。对于受拓扑约束且无法从群集中的所有节点全局访问的存储后端,将在不知道Pod的调度要求的情况下绑定或配置PersistentVolumes。这可能导致不可调度的Pod。
集群管理员可以通过指定WaitForFirstConsumer模式来解决此问题,该模式将延迟绑定和配置PersistentVolume,直到创建使用PersistentVolumeClaim的Pod。将根据Pod的调度约束指定的拓扑选择或配置PersistentVolumes。这些包括但不限于资源需求,节点选择器,pod亲和力和反亲和力,以及污点和容忍度。
安装配置nfs 服务
1 2 3 4 5 6 7 8 9 10 | yum install nfs-utils rpcbind -y vim /etc/exports /data/kubernetes/pv1 192.168.10.0 /24 (rw, sync ,no_root_squash,no_all_squash) /data/kubernetes/pv2 192.168.10.0 /24 (rw, sync ,no_root_squash,no_all_squash) /data/kubernetes/pv3 192.168.10.0 /24 (rw, sync ,no_root_squash,no_all_squash) /data/kubernetes/pv4 192.168.10.0 /24 (rw, sync ,no_root_squash,no_all_squash) /data/kubernetes/pv5 192.168.10.0 /24 (rw, sync ,no_root_squash,no_all_squash) /data/kubernetes/pv6 192.168.10.0 /24 (rw, sync ,no_root_squash,no_all_squash) systemctl restart nfs systemctl enable nfs |
github 地址:https://github.com/amitpawarcbg/NFS-storageclass
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 | git clone https: //github .com /amitpawarcbg/NFS-storageclass .git rbac 授权文件 [root@master-1 Storageclass] # cat rbac.yaml apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner # replace with namespace where provisioner is deployed 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 # replace with namespace where provisioner is deployed 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 # replace with namespace where provisioner is deployed namespace: default subjects: - kind: ServiceAccount name: nfs-client-provisioner # replace with namespace where provisioner is deployed namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io #文件class.yaml [root@master-1 Storageclass] # cat class.yaml apiVersion: storage.k8s.io /v1 kind: StorageClass metadata: name: managed-nfs-storage annotations: storageclass.kubernetes.io /is-default-class : "true" provisioner: k8s-sigs.io /nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME' parameters: archiveOnDelete: "false" #文件deployment.yaml [root@master-1 Storageclass] # cat deployment.yaml apiVersion: apps /v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner # replace with namespace where provisioner is deployed 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: gcr.io /k8s-staging-sig-storage/nfs-subdir-external-provisioner :v4.0.1 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env : - name: PROVISIONER_NAME value: k8s-sigs.io /nfs-subdir-external-provisioner - name: NFS_SERVER value: 192.168.10.29 - name: NFS_PATH value: /data/kubernetes/pv1 volumes: - name: nfs-client-root nfs: server: 192.168.10.29 # nfs 主机 path: /data/kubernetes/pv1 #nfs 共享的目录 |
运行相关yaml 文件
1 2 3 4 5 6 7 8 | kubectl apply -f rbac.yaml kubectl apply -f class.yaml kubectl apply -f deployment.yaml [root@master-1 Storageclass] # kubectl get pods | grep nfs-client-provisioner nfs-client-provisioner-69fb9f7874-7fzm4 1 /1 Running 0 24m [root@master-1 Storageclass] # kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage (default) k8s-sigs.io /nfs-subdir-external-provisioner Delete Immediate false 40m |
申请pvc 的测试yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | [root@master-1 Storageclass] # cat test-claim.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test -claim spec: storageClassName: managed-nfs-storage accessModes: - ReadWriteMany resources: requests: storage: 1Mi [root@master-1 Storageclass] # kubectl apply -f test-claim.yaml persistentvolumeclaim /test-claim created [root@master-1 Storageclass] # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test -claim Bound pvc-964237a2-75cd-4397-9c20-6dc2916b164d 1Mi RWX managed-nfs-storage 56s [root@master-1 Storageclass] # kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-964237a2-75cd-4397-9c20-6dc2916b164d 1Mi RWX Delete Bound default /test-claim managed-nfs-storage 59s |
创建pvc存储
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | [root@master-1 Storageclass] # [root@master-1 Storageclass] # cat class.yaml apiVersion: storage.k8s.io /v1 kind: StorageClass metadata: name: managed-nfs-storage annotations: storageclass.kubernetes.io /is-default-class : "true" provisioner: k8s-sigs.io /nfs-subdir-external-provisioner # or choose another name, must match deployment'里面 env PROVISIONER_NAME的值一致' parameters: archiveOnDelete: "false" [root@master-1 Storageclass] # cat pvc.yaml kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test -claim1-1 #pvc 名字 spec: accessModes: [ "ReadWriteMany" ] #读写权限设置 resources: requests: storage: 1Gi #空间大小限制 storageClassName: managed-nfs-storage # StorageClass的名字一致才能找到 [root@master-1 Storageclass] # kubectl apply -f pvc.yaml persistentvolumeclaim /test-claim1-1 created [root@master-1 Storageclass] # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test -claim Bound pvc-014f93a3-c32a-4a67-8d89-5601c4ebc85c 1Gi RWX managed-nfs-storage 112s test -claim1-1 Bound pvc-4a77164b-ec51-4a0f-8070-4fc4721288c5 1Gi RWX managed-nfs-storage 3s [root@master-1 Storageclass] # kubectl get pvc |
测试pvc
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | [root@master-1 Storageclass] # cat pod-pvc.yaml kind: Pod apiVersion: v1 metadata: name: read -pod spec: containers: - name: read -pod image: nginx imagePullPolicy: IfNotPresent volumeMounts: - name: nfs-pvc mountPath: /usr/share/nginx/html restartPolicy: "Never" volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test -claim #pvc 名字 [root@master-1 Storageclass] # kubectl apply -f pod-pvc.yaml pod /read-pod created [root@master-1 Storageclass] # kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-7c7bf9f6bd-dp5h8 1 /1 Running 0 33m nginx- test 1 /1 Running 4 105d read -pod 1 /1 Running 0 33s |
动态存储的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | [root@master-1 Storageclass] # cat statefulset-storageclass1.yaml apiVersion: v1 kind: Service metadata: name: storage labels: app: storage spec: ports: - name: web port: 80 clusterIP: None selector: #service 定义绑定拥有一下标签的pod app: storage --- apiVersion: apps /v1 kind: StatefulSet metadata: name: storage spec: selector: #service 定义绑定拥有一下标签的pod matchLabels: app: storage serviceName: "storage" #指定service名字 replicas: 2 template: # pod属性定义 metadata: labels: #打标签 app: storage spec: #pod期望运行状态定义 containers: # 容器运行状态定义 - name: web # 容器名字 image: nginx # 运行的镜像 imagePullPolicy: IfNotPresent # 镜像获取策略 ports: #暴漏端口设置 - name: web containerPort: 80 #容器暴漏端口 protocol: TCP # 端口协议;默认TCP volumeMounts: - name: www #这个文件里指的动态申请的名字,也可指定现有的pvc mountPath: /usr/share/nginx/html #挂载的指定目录 volumeClaimTemplates: # 存储申请模板 - metadata: name: www #动态申请的名字 annotations: volume.beat.kubernetes.io /storage-class : "managed-nfs-storage" #注解建议与动态存储类名字一致· spec: accessModes: [ "ReadWriteOnce" ] resources: requests: storage: 2Gi [root@master-1 Storageclass] # kubectl apply -f statefulset-storageclass1.yaml service /storage created statefulset.apps /storage created [root@master-1 Storageclass] # kubectl get pod NAME READY STATUS RESTARTS AGE nfs-client-provisioner-7c7bf9f6bd-dp5h8 1 /1 Running 0 130m nginx- test 1 /1 Running 4 105d read -pod 1 /1 Running 0 98m storage-0 1 /1 Running 0 4s storage-1 1 /1 Running 0 3s [root@master-1 Storageclass] # kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test -claim Bound pvc-014f93a3-c32a-4a67-8d89-5601c4ebc85c 1Gi RWX managed-nfs-storage 108m test -claim1-1 Bound pvc-4a77164b-ec51-4a0f-8070-4fc4721288c5 1Gi RWX managed-nfs-storage 106m www-storage-0 Bound pvc-4a8303f8-38fe-42f2-994b-ed4626d9ac5e 2Gi RWO managed-nfs-storage 10m www-storage-1 Bound pvc-2f3fd42e-20bf-45a2-a743-36995db15701 2Gi RWO managed-nfs-storage 10m [root@master-1 Storageclass] # kubectl get pv NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE pvc-014f93a3-c32a-4a67-8d89-5601c4ebc85c 1Gi RWX Delete Bound default /test-claim managed-nfs-storage 111m pvc-2f3fd42e-20bf-45a2-a743-36995db15701 2Gi RWO Delete Bound default /www-storage-1 managed-nfs-storage 13m pvc-4a77164b-ec51-4a0f-8070-4fc4721288c5 1Gi RWX Delete Bound default /test-claim1-1 managed-nfs-storage 109m pvc-4a8303f8-38fe-42f2-994b-ed4626d9ac5e 2Gi RWO Delete Bound default /www-storage-0 managed-nfs-storage 13m |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)