您的位置:首页 > 其它

K8s数据持久化之Storage Class自动创建PV

2020-08-21 14:34 573 查看

在前两篇实现k8s的数据持久化的流程为:搭建nfs底层存储===》创建PV====》创建PVC===》创建pod。最终pod中的container实现数据的持久化。

上述流程中,看似没什么问题,但细想一下,PVC在向PV申请存储空间的时候,是根据指定的pv名称、访问模式、容量大小来决定具体向哪个PV来申请空间的,如果PV的容量为20G,定义的访问模式是WRO(只允许以读写的方式挂载到单个节点),而PVC申请的存储空间为10G,那么一旦这个PVC是向上面的PV申请的空间,也就是说,那个PV有10个G的空间被浪费了,因为其只允许被单个节点挂载。就算不考虑这个问题,我们每次手动去创建PV也就比较麻烦的事情,这时,我们就需要一个自动化的工具来替我们创建PV。

这个东西就是阿里提供的一个开源镜像“nfs-client-provisioner”,这个东西是通过k8s内置的NFS驱动挂载远端的NFS服务器到本地目录,然后自身作为storage(存储)。

当然,PVC是无法直接去向nfs-client-provisioner申请使用的存储空间的,这时,就需要通过SC(storageClass)这个资源对象去申请了,SC的根本作用就是根据PVC定义的值去自动创建PV。

下面是一个Nginx基于自动创建PV实现数据持久化的示例:

1、搭建nfs服务
为了方便,我这里直接在master上做nfs。

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

2、创建rbac授权
这种自动创建pv的方式涉及到了rbac授权。

kind: Namespace              //创建一个名称空间,名称为bjq-test
apiVersion: v1
metadata:
name: bjq-test
---
apiVersion: v1                            //创建一个用于认证的服务账号
kind: ServiceAccount
metadata:
name: nfs-provisioner
namespace: bjq-test
---
apiVersion: rbac.authorization.k8s.io/v1        //创建群集规则
kind: ClusterRole
metadata:
name: nfs-provisioner-runner
namespace: bjq-test
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: ["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/v1
metadata:
name: run-nfs-provisioner
subjects:
- kind: ServiceAccount
name: nfs-provisioner
namespace: bjq-test
roleRef:
kind: ClusterRole
name: nfs-provisioner-runner
apiGroup: rbac.authorization.k8s.io

[root@master ~]# kubectl apply -f rbac-rolebind.yaml     //执行yaml文件

3、创建nfs-client-provisioner容器

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nfs-client-provisioner
namespace: bjq-test
spec:
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: jq-test
- name: NFS_SERVER                      //容器内的变量用于指定nfs服务的IP地址
value: 192.168.45.129
- name: NFS_PATH                       //容器内的变量指定nfs服务器对应的目录
value: /nfsdata
volumes:                                                //指定挂载到容器内的nfs的路径及IP
- name: nfs-client-root
nfs:
server: 192.168.45.129
path: /nfsdata

[root@master ~]# kubectl apply -f nfs-deployment.yaml                   //执行yaml文件
[root@master ~]# kubectl  get pod -n bjq-test
NAME                                     READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-f7d5b544f-h6nps   1/1     Running   0          89s

4、创建SC(StorageClass)

[root@master ~]# vim test-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: stateful-nfs
namespace: bjq-test
provisioner: jq-test                  //这个要和nfs-client-provisioner的env环境变量中的PROVISIONER_NAME的value值对应。
reclaimPolicy: Retain               //指定回收策略为Retain(手动释放)

[root@master ~]# kubectl apply -f test-storageclass.yaml  //执行yaml文件

5、创建PVC

[root@master ~]#vim test-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-claim
namespace: bjq-test
spec:
storageClassName: statefu-nfs   //定义存储类的名称,需与SC的名称对应
accessModes:
- ReadWriteMany         // 访问模式为RWM
resources:
requests:
storage: 500Mi

[root@master ~]# kubectl apply -f test-pvc.yaml  //执行yaml文件
[root@master ~]# kubectl  get  pvc -n bjq-test    //保证pvc的状态为Bound,表示关联成功
NAME         STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim   Bound    pvc-c886284a-18c7-4583-81a3-3f759c1c97fc   500Mi      RWX            statefu-nfs    5m52s

[root@master ~]# ls /nfsdata/   //可以看出用于nfs存储的目录下生成了一个对应的目录
bjq-test-test-claim-pvc-c886284a-18c7-4583-81a3-3f759c1c97fc

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

6、创建基于nginx镜像的Pod

[root@master ~]# vim nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: myweb
namespace: bjq-test
spec:
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     //执行yaml文件
[root@master ~]# kubectl  get  pod -n bjq-test
NAME                                     READY   STATUS    RESTARTS   AGE
myweb                                    1/1     Running   0          65s
nfs-client-provisioner-f7d5b544f-h6nps   1/1     Running   0          29m

7、测试验证

[root@master ~]# kubectl exec -it myweb -n bjq-test /bin/bash  //进入容器插入数据进行测试
root@myweb:/# cd /usr/share/nginx/html/
root@myweb:/usr/share/nginx/html# echo "hello world" > index.html

[root@master ~]# cat /nfsdata/bjq-test-test-claim-pvc-c886284a-18c7-4583-81a3-3f759c1c97fc/index.html
hello world
//回到本地查看,可以看见目录测试没有问题

[root@master ~]# kubectl  exec -it nfs-client-provisioner-f7d5b544f-h6nps -n bjq-test /bin/sh
/ # ls nfs-client-provisioner
nfs-client-provisioner                   //自动创建pv的可执行程序
/ # cat /persistentvolumes/bjq-test-test-claim-pvc-c886284a-18c7-4583-81a3-3f759c1c97fc/index.html
hello world
//nfs-client容器对应的目录数据也是存在的

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: