如何在k8s中部署nfs-client-provisioner实现nfs共享存储的动态PV创建?
0、背景说明
正常的情况,如果使用nfs的网络共享存储,需要手动的创建pv,然后创建pvc和pv进行绑定。
最后在应用程序的pod中来挂载使用这个pvc,达到挂载外部共享存储的目的。
那么,要实现动态的PV的创建,该怎么做呢?
在今天的内容里面,介绍一个nfs-client-provisoner工具,通过它,就能够基于stroageclass,动态的创建PV,也就是,在创建pvc的时候,自动创建出来pv,无需手动的创建。
接下来的部分,介绍如何在k8s中部署nfs-client-provisioner工具
1、部署过程
1.1、环境依赖
在部署nfs-client-provisioner之前,需要先部署nfs服务。
因为,nfs-client-provisioner创建的pv都是要在nfs服务器中搭建的。
本示例中的nfs server的地址如下:
[root@nccztsjb-node-23 ~]# showmount -e 172.20.58.83 Export list for 172.20.58.83: /data/nfs_data * [root@nccztsjb-node-23 ~]#
1.2、下载nfs-client-provisoner镜像
通过下面的命令下载nfs-client-provisioner的镜像
docker pull quay.io/vbouchaud/nfs-client-provisioner:lates
下载好之后,上传到本地的镜像仓库中
docker tag quay.io/vbouchaud/nfs-client-provisioner:latest \ 172.20.58.152/kubernetes/nfs-client-provisioner:latest docker push 172.20.58.152/kubernetes/nfs-client-provisioner:latest
1.3、在集群的每个节点部署nfs工具
执行以下的命令,在每个节点部署nfs工具,后面pod启动,挂载nfs的存储会使用
yum install nfs-utils -y
1.4、 创建授权账户信息
通过以下yaml文件,创建需要的service account
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
将以上的文件内容,放在rbac.yaml文件中
这里面的对象,是放在默认的命名空间中的。
执行命令,进行创建操作
[root@nccztsjb-node-23 yamls]# kubectl apply -f rbac.yaml serviceaccount/nfs-client-provisioner created clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created [root@nccztsjb-node-23 yamls]#
1.5、部署nfs-client-provisioner服务
使用下面的yaml配置文件,部署nfs-client-provisioner应用
kind: Deployment apiVersion: apps/v1 metadata: name: nfs-client-provisioner spec: replicas: 1 selector: matchLabels: app: nfs-client-provisioner strategy: type: Recreate template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner image: 172.20.58.152/kubernetes/nfs-client-provisioner:latest # 修改为本地镜像地址 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: fuseim.pri/ifs # provisioner的名字,可以修改 - name: NFS_SERVER value: 172.20.58.83 # nfs服务器的地址 - name: NFS_PATH value: /data/nfs_data # nfs服务器共享地址 volumes: - name: nfs-client-root nfs: server: 172.20.58.83 # nfs服务器的地址 path: /data/nfs_data # nfs服务器共享地址
将上面的内容,放在nfs_client_provisioner.yaml文件中
执行以下命令进行创建:
[root@nccztsjb-node-23 yamls]# kubectl apply -f nfs_client_provisioner.yaml deployment.apps/nfs-client-provisioner created
查看nfs-client pod的状态
[root@nccztsjb-node-23 yamls]# kubectl get pod | grep nfs nfs-client-provisioner-68c48f6f9b-rkxhv 1/1 Running 0 5s [root@nccztsjb-node-23 yamls]#
pod状态为Running,正常。
1.6、创建storageclass
动态存储的关联关系,都是通过stroageclass来完成的
通过下面的yaml文件,创建storageclass
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: managed-nfs-storage provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME' parameters: archiveOnDelete: "false" # When set to "false" your PVs will not be archived # by the provisioner upon deletion of the PVC.
执行的过程
[root@nccztsjb-node-23 yamls]# kubectl apply -f nfs-storage-class.yaml storageclass.storage.k8s.io/managed-nfs-storage created [root@nccztsjb-node-23 yamls]# kubectl get sc NAME PROVISIONER RECLAIMPOLICY VOLUMEBINDINGMODE ALLOWVOLUMEEXPANSION AGE managed-nfs-storage fuseim.pri/ifs Delete Immediate false 3s [root@nccztsjb-node-23 yamls]#
1.7、创建pvc
storageclass创建好了之后,需要创建pvc,pvc回去申请nfs的存储
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-claim annotations: volume.beta.kubernetes.io/storage-class: "managed-nfs-storage" spec: accessModes: - ReadWriteMany resources: requests: storage: 1Mi
创建测试pvc,发现已经动态的绑定了pv:pvc-bece47f2-2164-4bfe-bba3-df88e9c75250
这个pv并没有手动的进行创建
[root@nccztsjb-node-23 yamls]# kubectl apply -f nfs-pvc.yaml persistentvolumeclaim/test-claim created [root@nccztsjb-node-23 yamls]# kubectl get pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test-claim Bound pvc-bece47f2-2164-4bfe-bba3-df88e9c75250 1Mi RWX managed-nfs-storage 4s [root@nccztsjb-node-23 yamls]#
在nfs 服务器的目录里面,自动创建出来一个目录,就是这个pv的目录
[root@nccztsjb-node-23 nfs_data]# pwd /data/nfs_data [root@nccztsjb-node-23 nfs_data]# ls default-test-claim-pvc-bece47f2-2164-4bfe-bba3-df88e9c75250 [root@nccztsjb-node-23 nfs_data]#
1.8、创建pod使用pvc
pvc已经创建好了,创建测试pod,使用pvc
kind: Pod apiVersion: v1 metadata: name: test-pod spec: containers: - name: test-pod image: 172.20.58.152/middleware/busybox:1.36 command: - "/bin/sh" args: - "-c" - "touch /mnt/SUCCESS && exit 0 || exit 1" volumeMounts: - name: nfs-pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-claim
正常执行后,退出
[root@nccztsjb-node-23 ~]# kubectl get pod |grep test-pod test-pod 0/1 Completed 0 16s [root@nccztsjb-node-23 ~]#
进入nfs server的目录里,已经创建好了SUCCESS文件
[root@nccztsjb-node-23 data]# cd nfs_data/ [root@nccztsjb-node-23 nfs_data]# ls default-test-claim-pvc-bece47f2-2164-4bfe-bba3-df88e9c75250 [root@nccztsjb-node-23 nfs_data]# cd default-test-claim-pvc-bece47f2-2164-4bfe-bba3-df88e9c75250/ [root@nccztsjb-node-23 default-test-claim-pvc-bece47f2-2164-4bfe-bba3-df88e9c75250]# ls SUCCESS [root@nccztsjb-node-23 default-test-claim-pvc-bece47f2-2164-4bfe-bba3-df88e9c75250]#
OK,到这里nfs-client-provisioner工具部署成功。
部署完成nfs-client-provisioner之后,创建好pvc,就可以动态的创建nfs的pv了,不需要手动的进行创建。
2、工作原理简要说明
基本的工作原理就是,nfs-client-provisioner持续的监控api server,查看创建pvc的请求,如果发现请求的pvc的存储类stroageclass,存储类的提供者和自己的是一致的
就会根据创建的pvc,动态的在nfs中创建pv。
下面是chatGPT中,关于nfs-client-provisioner工作流程的描述:
- 部署 nfs-client-provisioner: 首先,您需要在 Kubernetes 集群中部署 nfs-client-provisioner。您可以通过使用 Kubernetes 配置文件或 Helm Chart 进行部署。这将创建一个运行在集群中的容器,用于监听 PVC 的创建。
- 创建 StorageClass: 您需要创建一个 StorageClass,其中定义了与 nfs-client-provisioner 通信所需的配置信息,如 NFS 服务器地址、共享路径等。
- 创建 PersistentVolumeClaim(PVC): 当您在集群中创建一个 PVC 并引用了之前定义的 StorageClass,nfs-client-provisioner 将监听 PVC 的创建。
- nfs-client-provisioner 的处理: 一旦 PVC 创建,nfs-client-provisioner 会检测到 PVC 的存在。它会解析 PVC 中定义的存储需求和 StorageClass 的配置,然后使用这些信息来与 NFS 服务器交互。
- 创建 PersistentVolume(PV):nfs-client-provisioner 会使用 PVC 请求中的信息,以及 StorageClass 的配置,通过 NFS 协议与 NFS 服务器进行通信,并在 NFS 服务器上创建一个目录以供存储。
- 绑定 PV 和 PVC: 一旦 NFS 服务器上的目录创建成功,nfs-client-provisioner 将创建一个 PV,并将其与创建 PVC 绑定起来,从而使 PVC 获得一个可用的 PV。
- PVC 使用: 现在,PVC 已经与一个动态创建的 PV 绑定。您可以在 Pod 中使用这个 PVC,使 Pod 能够挂载 NFS 存储并访问其中的数据。
通过这个流程,nfs-client-provisioner 实现了动态创建和管理基于 NFS 的 PV,减轻了管理员的工作负担,同时使开发人员能够更轻松地使用动态的存储资源。需要注意的是,确保您在 PVC 和 StorageClass 的定义中提供正确的配置信息,以确保 nfs-client-provisioner 能够与 NFS 服务器正确交互。
你好,
如果你读完了整个技术文章,下面的内容,或许你会更加感兴趣...
在4年多的k8s体系运维时间里,我整理了230个,k8s最常见(最关键)的问题。
这些问题,让我轻松地应对几乎所有的k8s问题,并且,都是基于项目及大量的实验的总结。
如果你能够彻底掌握这些问题,你的知识体系,k8s基本功,就可以轻松超过80%的k8s运维人员。
更重要的是,掌握这些知识非常简单,每天5个问题,2个月后,你就可以打下k8s的见识基础,让你在云原生领域游刃有余。
每个问题,都有对应的答案,以及相关的示例演示(有些还有项目背景说明)
只要,一步一步,跟着做,就可以了。
当然,如果你想要在更短的时间内,成为k8s高手,你只需要多练习几次就可以了。
不过,和你自己从头摸索相比较,大大减少了你的学习时间,同时,大大提升了你的学习效力。
更加重要的是,如果你知道20/80原理,你就会明白,这些都是工作中最常用,最有效的20%的问题。
这个资料是第一次公开,为了了解市场上,有多少人在关注k8s的技术,我决定免费赠送这个问题指南,只当交个朋友。
添加微信:13240133388,备注:k8sa
我将送你一份免费的PDF报告。
你应该知道,一本k8s权威指南(800页,没几个人看得完),要179.90元,这些问题,是在反复阅读和实践了这本书之后,结合项目实践,得出来的精华。
想想看,这将节省你多少时间?而你得到是最精华的部分?
相信你,掌握之后,立马让你的工作的效率大增,你的领导会对你的进步刮目相看。
PS. 行动是一切的开始,现在立马订阅吧。期待你的蜕变。