K8s数据持久化之Storage Class自动创建PV
在前两篇实现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容器中的目录就全部关联起来了。
- 【nfs搭建、k8s、StroageClass动态创建PV】K8S通过StroageClass完成动态的PV创建
- class_create(),class_device_create()或device_create()自动创建设备文件结点
- Kubernetes系列之基于NFS的PV动态供给(StorageClass)
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),class_device_create()或device_create()自动创建设备节点
- Linux下使用class_create,device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点【转】
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- class_create(),device_create自动创建设备文件结点
- device_create device_destroy 使用==mknod及通过class_create自动创建设备节点
- class_create(),class_device_create()或device_create()自动创建设备文件结点
- class_create(),class_device_create()或device_create()自动创建设备文件结点
- (一)小记——驱动中使用class_device_create()报错的原因、自动创建设备节点
- kubernetes持久化存储,静态存储【pv】,动态存储【StorageClass】(5)