三、Storageclass存储类动态生成存储
- 上面介绍的PV和PVC模式都需要先创建号PV,然后定义好PVC和PV进行一对一的Bond(绑定),但是如果PVC请求成千上万,那么就需要创建成千上万的PV,对于运维人员来说维护成本很高,Kubernetes提供了一种自动创建PV的机制,叫StorageClass,它的作用就是创建PV的模板。K8S集群管理员通过创建Storageclass可以动态生成一个存储卷PV供K8S PVC使用
3.1、StorageClass介绍
- 每个StorageClass都包含字段provisioner,parameters和reclaimPolicy
- 具体来说,StorageClass会定义以下两部分:
PV的属性,比如存储的大小、类型等
创建这种PV需要使用到的存储插件,比如Ceph、NFS等
- 有了这两部分信息,Kubernetes就能够根据用户提交的PVC,找到对应的StorageClass,然后Kubernetes就会调用StorageClass声明的存储插件,创建出需要的PV
3.2、StorageClass示例
3.2.1、资源列表
操作系统 | 主机名 | 配置 | IP |
---|---|---|---|
CentOS 7.9 | master | 2C4G | 192.168.93.101 |
CentOS 7.9 | node1 | 2C4G | 192.168.93.102 |
CentOS 7.9 | node2 | 2C4G | 192.168.93.103 |
CentOS 7.9 | nfs | 2C4G | 192.168.93.104 |
3.2.2、准备NFS
- NFS节点操作
3.2.2.1、关闭防火墙
bash
systemctl stop firewalld
systemctl disable firewalld
3.2.2.2、关闭内核安全机制
bash
setenforce 0
sed -i "s/.*SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
3.2.2.3、安装
bash
[root@nfs ~]# yum -y install nfs-utils rpcbind
[root@nfs ~]# mkdir -p /data/nfs_pro
[root@nfs ~]# cat >> /etc/exports << EOF
/data/nfs_pro 192.168.93.0/24(rw,no_root_squash)
EOF
[root@nfs ~]# systemctl restart nfs
bash
# 所有Kubernetes集群中的节点需要安装以下软件包用以支持NFS
yum -y install nfs-utils rpcbind
3.2.3、部署供应商
- 该yaml文件里面指定了NFS节点的地址,以及使用NFS节点的哪个目录。需要替换成自己的
bash
[root@master ~]# cat nfs-provisioner.yaml
# 表示使用Kubernetes核心API的v1版本
apiVersion: v1
# ServiceAccount表示这是一个服务账户资源,用于定义运行在Pod中的进程可以访问权限
kind: ServiceAccount
metadata:
# 服务账户的名称
name: nfs-provisioner
---
# 表示使用基于角色的访问控制(RBAC)的v1版本
apiVersion: rbac.authorization.k8s.io/v1
# 表示这是一个集群角色绑定资源,用于将角色(CLusterRole)绑定到一个或多个用户或组
kind: ClusterRoleBinding
# 这是集群角色绑定的名称
metadata:
name: nfs-provisioner-clusterrolebinding
# 指定了要绑定的角色
roleRef:
# rbac.authorization.k8s.io是角色所在的API组
apiGroup: rbac.authorization.k8s.io
# 表示这是一个集群级别的角色
kind: ClusterRole
# cluster-admin是要绑定的角色,这里给予了nfs-provisioner服务账户非常高的权限
name: cluster-admin
# 指定了绑定到这个角色用户或组
subjects:
# ServiceAccount表示这是一个服务账户
- kind: ServiceAccount
# 服务账号的名称
name: nfs-provisioner
# 指定了服务账户所在的命名空间,这里是默认的命名空间
namespace: default
---
# 表示这是一个部署资源,用于管理无状态应用的Pod
kind: Deployment
# apps/v1表示使用应用工作负载API的v1版本
apiVersion: apps/v1
metadata:
# Deployment的名字
name: nfs-provisioner
# 定义了部署的规格
spec:
# 定义了如何识别由这个部署管理的Pod
selector:
# 指定了Pod必须具有的标签
matchLabels:
app: nfs-provisioner
# 表示Deployment将运行一个Pod副本
replicas: 1
# 定义了Pod的更新策略
strategy:
# 表示在更新时先删除除旧的Pod,然后创建新的Pod
type: Recreate
template:
metadata:
labels:
app: nfs-provisioner
# 定义Pod的规格
spec:
# nfs-provisioner指定了Pod将使用的账户
serviceAccount: nfs-provisioner
containers:
- name: nfs-provisioner
# 指定了容器的镜像,这里是一个NFS外部卷预配器的镜像
image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
# 定义了容器内部的挂载点
volumeMounts:
# nfs-client-root挂载卷的名字
- name: nfs-client-root
# 将卷挂载到容器内部的目录/persistentvolumes
mountPath: /persistentvolumes
# 定义了容器的环境变量
env:
# 定义了预配器的名称,这是动态卷预配的关键
- name: PROVISIONER_NAME
value: example.com/nfs
# NFS_SERVER和NFS_PATH定义了NFS服务器的地址和路径,预配器将从中创建新的NFS持久化
- name: NFS_SERVER
value: 192.168.93.104
- name: NFS_PATH
value: /data/nfs_pro
# 定义Pod中的挂载卷
volumes:
# 卷的名字,与容器挂载点中的名字相匹配
- name: nfs-client-root
# 定义了NFS卷的类型和配置
nfs:
# server和path分别是NFS服务器的地址和路径,与环境变量中的值相同
server: 192.168.93.104
path: /data/nfs_pro
bash
[root@master ~]# kubectl apply -f nfs-provisioner.yaml
serviceaccount/nfs-provisioner created
clusterrolebinding.rbac.authorization.k8s.io/nfs-provisioner-clusterrolebinding created
deployment.apps/nfs-provisioner created
3.2.4、创建StorageClass
bash
[root@master ~]# cat StorageClass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: nfs
# 注意:provisioner处写的example.com/nfs应该跟安装nfs provisioner时候的env下的PROVISIONER_NAME的value值保持一致,如下
provisioner: example.com/nfs
allowVolumeExpansion: true # 允许动态扩容
bash
[root@master ~]# kubectl apply -f StorageClass.yaml
storageclass.storage.k8s.io/nfs created
3.2.5、创建PVC
bash
[root@master ~]# cat pvc.yaml
# 定义一个PVC资源对象
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
# 访问模式ReadWriteMany表示这个卷可以被多个节点以读写的模式挂载。这是NFS存储的一个常见特性
accessModes: ["ReadWriteMany"]
resources:
requests:
# storage: 1G表示指定了这个PVC请求的存储量大小为1G
storage: 1G
# nfs指定了这个PVC应用使用的存储类(StorageClass)的名称
storageClassName: nfs
bash
[root@master ~]# kubectl apply -f pvc.yaml
persistentvolumeclaim/test-claim1 created
3.2.6、Pod使用PVC
bash
[root@master ~]# cat test-pvc-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: test-pvc-pod
labels:
app: busybox
spec:
containers:
- name: busybox
image: busybox:1.28
imagePullPolicy: IfNotPresent
command: ["sh","-c","sleep 3600"]
volumeMounts:
- name: data
mountPath: /opt
volumes:
- name: data
persistentVolumeClaim:
# test-claim1是这个卷将要使用的PVC的名字,这告诉Kubernetes,当Pod被调度到某个节点上时,它应该使用名为test-claim1的PVC来挂在一个持久化到Pod中的/opt目录
claimName: test-claim1
bash
[root@master ~]# kubectl apply -f test-pvc-pod.yaml
pod/test-pvc-pod created
bash
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-provisioner-77cdc7f549-z8csl 1/1 Running 0 31m
test-pvc-pod 1/1 Running 0 46s
bash
# pv和pvc将会自动绑定
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-5c73d02d-1083-4d2c-85c7-85c5645c6087 1G RWX Delete Bound default/test-claim1 nfs 14m
[root@master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
test-claim1 Bound pvc-5c73d02d-1083-4d2c-85c7-85c5645c6087 1G RWX nfs 14m
bash
# 在容器里面写个文件,NFS服务器的指定目录下就会有这个
[root@master ~]# kubectl exec -it test-pvc-pod -- sh -c 'date > /opt/time.txt'
[root@master ~]# kubectl exec -it test-pvc-pod -- cat /opt/time.txt
Fri Jul 5 03:15:59 UTC 2024
# 登录到NFS服务器查看
[root@nfs ~]# cat /data/nfs_pro/default-test-claim1-pvc-5c73d02d-1083-4d2c-85c7-85c5645c6087/time.txt
Fri Jul 5 03:15:59 UTC 2024