千家信息网

如何使用Storage Class?

发表于:2024-11-24 作者:千家信息网编辑
千家信息网最后更新 2024年11月24日,搭建NFS底层存储-->创建PV-->创建PVC-->创建pod最终将pod中的container实现数据的持久化!从上述流程中,看似没有什么问题,但是仔细研究就会发现:PVC在向PV申请存储空间时,
千家信息网最后更新 2024年11月24日如何使用Storage Class?

搭建NFS底层存储-->创建PV-->创建PVC-->创建pod
最终将pod中的container实现数据的持久化!

从上述流程中,看似没有什么问题,但是仔细研究就会发现:PVC在向PV申请存储空间时,是根据指定PV的名称、访问模式、容量大小来决定具体向哪个PV申请空间的。

打比方说:如果PV的容量是20G,定义的访问模式是WRO(只允许以读写的方式挂载到单个节点),而PVC申请的存储空间为10G,那么一旦这个PVC是向上述的PV申请的空间,也就是说,那么PV有10G的空间被白白浪费了,因为其只允许单个节点挂载。这是一个非常严重的问题。就算不考虑这个问题,我们每次手动去创建PV也是比较麻烦的事情,这是就需要使用一个自动化的方案来替我们创建PV。这个自动化的方案就是--Storage Class(存储类)!

Storage class(存储类)概述

Storage class(存储类)是Kubernetes资源类型的一种,它是由管理员为管理PV更加方便而创建的一个逻辑组,可以按照存储系统的性能高低、综合服务质量、备份策略等分类。不过Kubernetes本身并不知道类别到底是什么,这是一个简单的描述而已!

存储类的好处之一就是支持PV的动态创建,当用户用到持久化存储时,不必再去提前创建PV,而是直接创建PVC就可以了,非常的方便。同时也避免了空间的浪费!

Storage class(存储类)三个重要的概念:
1)Provisioner(供给方、提供者):提供了存储资源的存储系统。Kubernetes内部多重供给方,这些供给方的名字都以"kubernetes.io"为前缀。并且还可以自定义;
2)Parameters(参数):存储类使用参数描述要关联到的存储卷,注意不同的供给方参数也不同;
3)ReclaimPlicy:pv的回收策略,可用的值有Delete(默认)和Retain;

下面通过一个nginx基于自动创建PV实现数据持久化的案例进一步的了解Storage Class的具体使用!

1)搭建NFS共享存储

为了方便,就直接在master节点上部署NFS存储了!

[root@master ~]# yum -y install nfs-utils rpcbind[root@master ~]# vim /etc/exports/nfsdata *(rw,sync,no_root_squash)[root@master ~]# systemctl start nfs-server[root@master ~]# systemctl start rpcbind[root@master ~]# showmount -eExport list for master:/nfsdata *

2)创建rbac授权

这种自动创建PV的方式涉及到了rbac授权机制,关于rbac授权机制这里先不详细介绍,随后再更新说明。

[root@master ~]# vim rbac-rolebind.yamlkind: Namespace              #创建一个名称空间,名称为xiaojiang-testapiVersion: v1metadata:  name: xiaojiang-test---apiVersion: v1                            #创建一个用于认证的服务账号kind: ServiceAccountmetadata:  name: nfs-provisioner  namespace: xiaojiang-test---apiVersion: rbac.authorization.k8s.io/v1        #创建群集规则kind: ClusterRolemetadata:  name: nfs-provisioner-runner  namespace: xiaojiang-testrules:   -  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/v1metadata:  name: run-nfs-provisionersubjects:  - kind: ServiceAccount    name: nfs-provisioner    namespace: xiaojiang-testroleRef:  kind: ClusterRole  name: nfs-provisioner-runner  apiGroup: rbac.authorization.k8s.io[root@master ~]# kubectl apply -f rbac-rolebind.yaml     #执行yaml文件

3)创建nfs-deployment.资源

nfs-deployment的作用:其实它是一个NFS客户端。但它通过K8S的内置的NFS驱动挂载远端的NFS服务器到(容器内)本地目录;然后将自身作为storage provider,关联storage class。

[root@master ~]# vim nfs-deployment.yaml  apiVersion: extensions/v1beta1kind: Deploymentmetadata:  name: nfs-client-provisioner  namespace: xiaojiang-testspec:  replicas: 1                              #指定副本数量为1  strategy:    type: Recreate                      #指定策略类型为重置  template:    metadata:      labels:        app: nfs-client-provisioner    spec:      serviceAccount: nfs-provisioner            #指定rbac yanl文件中创建的认证用户账号      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: lzj-test             - name: NFS_SERVER                      #容器内的变量用于指定nfs服务的IP地址              value: 192.168.1.1            - name: NFS_PATH                       #容器内的变量指定nfs服务器对应的目录              value: /nfsdata      volumes:                                                #指定挂载到容器内的nfs的路径及IP        - name: nfs-client-root          nfs:            server: 192.168.1.1            path: /nfsdata[root@master ~]# kubectl apply -f nfs-deployment.yaml                   #执行yaml文件[root@master ~]# kubectl get pod -n xiaojiang-test NAME                                      READY   STATUS    RESTARTS   AGEnfs-client-provisioner-7cf975c58b-sc2qc   1/1     Running   0          6s

4)创建SC(Storage Class)

[root@master ~]# vim test-storageclass.yamlapiVersion: storage.k8s.io/v1kind: StorageClassmetadata:  name: stateful-nfs  namespace: xiaojiang-testprovisioner: lzj-test                  #这个要和nfs-client-provisioner的env环境变量中的PROVISIONER_NAME的value值对应。reclaimPolicy: Retain               #指定回收策略为Retain(手动释放)[root@master ~]# kubectl apply -f test-storageclass.yaml

5)创建PVC

[root@master ~]# vim test-pvc.yamlapiVersion: v1kind: PersistentVolumeClaimmetadata:  name: test-claim  namespace: xiaojiang-testspec:  storageClassName: stateful-nfs              #定义存储类的名称,需与SC的名称对应  accessModes:    - ReadWriteMany                        #访问模式为RWM  resources:    requests:      storage: 100Mi[root@master ~]# kubectl apply -f test-pvc.yaml[root@master ~]# kubectl get pvc -n xiaojiang-testNAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGEtest-claim   Bound    pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb   100Mi      RWX            stateful-nfs   14s#保证pvc的状态为Bound,表示关联成功[root@master ~]# ls /nfsdata/             #可以看出用于nfs存储的目录下生成了一个对应的目录xiaojiang-test-test-claim-pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb

至此位置,我们已经实现了根据PVC的申请存储空间去自动创建PV(本地的nfs共享目录下已经生成了一个目录,名字挺长的,是pv+pvc名字定义的目录名),至于这个PVC申请的空间是给哪个pod使用,这已经无所谓了!

6)创建基于nginx镜像的Pod

[root@master ~]# vim nginx-pod.yamlapiVersion: v1kind: Podmetadata:  name: myweb  namespace: xiaojiang-testspec:  containers:  - name: myweb    image: nginx:latest    volumeMounts:    - name: myweb-persistent-storage      mountPath: /usr/share/nginx/html/  volumes:  - name: myweb-persistent-storage    persistentVolumeClaim:      claimName: test-claim                  #指定使用的PVC名称[root@master ~]# kubectl apply -f nginx-pod.yaml            [root@master ~]# kubectl get pod -n xiaojiang-test NAME                                      READY   STATUS    RESTARTS   AGEmyweb                                     1/1     Running   0          38snfs-client-provisioner-7cf975c58b-sc2qc   1/1     Running   0          60m

7)测试验证

[root@master ~]# kubectl exec -it myweb -n xiaojiang-test /bin/bashroot@myweb:/# cd /usr/share/nginx/html/root@myweb:/usr/share/nginx/html# echo "hello world" > index.html#进入容器插入数据进行测试[root@master ~]# cat /nfsdata/xiaojiang-test-test-claim-pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb/index.html hello world#本地目录测试没有问题[root@master ~]# kubectl exec -it nfs-client-provisioner-7cf975c58b-sc2qc -n xiaojiang-test /bin/sh/ # ls nfs-client-provisioner nfs-client-provisioner                        #自动创建pv的可执行程序/ # cat /persistentvolumes/xiaojiang-test-test-claim-pvc-267b880d-5e0a-4e8e-aaff-3af46f21c6eb/index.html hello world#nfs-client容器对应的目录数据也是存在的

从以上测试就可以看出:nginx容器内的网页目录就、本地的nfs共享目录、nfs-client容器中的目录就全部关联起来了。

0