前言
只要用过 Linux,大概 NFS 几乎就会是个必学的服务,因此这边要介绍以 NFS 作为 StorageClass 后端 storage 的设定方式,让 k8s 可以动态的在 NFS share 上产生所需要 volume 来使用。
nfs-client-provisioner 是一个Kubernetes的简易NFS的外部provisioner,本身不提供NFS,需要现有的NFS服务器提供存储。
介绍
Kubernetes 对 Pod 进行调度时,以当时集群中各节点的可用资源作为主要依据,自动选择某一个可用的节点,并将 Pod 分配到该节点上。在这种情况下,Pod 中容器数据的持久化如果存储在所在节点的磁盘上,就会产生不可预知的问题,例如,当 Pod 出现故障,Kubernetes 重新调度之后,Pod 所在的新节点上,并不存在上一次 Pod 运行时所在节点上的数据。
为了使 Pod 在任何节点上都能够使用同一份持久化存储数据,我们需要使用网络存储的解决方案为 Pod 提供数据卷。常用的网络存储方案有:NFS/cephfs/glusterfs。
本文介绍一种使用 centos 搭建 nfs 服务器的方法。此方法仅用于测试目的,请根据您生产环境的实际情况,选择合适的 NFS 服务。
K8s集群主机都安装NFS挂载服务
yum install -y nfs-utils rpcbind systemctl start rpcbind systemctl enable rpcbind systemctl start nfs systemctl enable nfs
首先检查nfs挂载目录是否正常
showmount -e localhost
NFS服务器localhost
[root@k8s-master ~]# showmount -e 192.168.119.2 Export list for 192.168.119.2: /volume1/nfs *
部署 NFS-Subdir-External-Provisioner 提供动态分配卷
NFS-Subdir-External-Provisioner 简介
NFS-Subdir-External-Provisioner
是一个自动配置卷程序,它使用现有的和已配置的 NFS 服务器来支持通过持久卷声明动态配置 Kubernetes 持久卷。
持久卷被配置为:${namespace}-${pvcName}-${pvName}
。
此组件是对 nfs-client-provisioner 的扩展,nfs-client-provisioner 已经不提供更新,且 nfs-client-provisioner 的 Github 仓库已经迁移到 NFS-Subdir-External-Provisioner 的仓库。
GitHub 地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
NFS 服务端
本文是具体介绍如何部署 NFS 动态卷分配应用 “NFS-Subdir-External-Provisioner”,所以部署前请确认已经存在 NFS 服务端,,如果非 Centos 系统,请先自行查找 NFS Server 安装方法。
这里 NFS 服务端环境为:
- IP地址:192.168.119.2
- 存储目录:/volume1/nfs
- 存储目录:/volume1/nfs
部署 NFS Provisioner
创建 ServiceAccount
现在的 Kubernetes 集群大部分是基于 RBAC 的权限控制,所以创建一个一定权限的 ServiceAccount 与后面要创建的 “NFS Provisioner” 绑定,赋予一定的权限。
编辑nfs-rbac.yaml
apiVersion: v1 kind: ServiceAccount metadata: name: nfs-client-provisioner namespace: default # 替换成你要部署的 Namespace --- 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 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 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 namespace: default subjects: - kind: ServiceAccount name: nfs-client-provisioner namespace: default roleRef: kind: Role name: leader-locking-nfs-client-provisioner apiGroup: rbac.authorization.k8s.io
创建 RBAC:
kubectl apply -f nfs-rbac.yaml
部署 NFS-Subdir-External-Provisioner
创建 NFS Provisioner 部署文件,这里将其部署到 “default” Namespace 中。
要注意红色字体部分,否则不会成功
编辑nfs-provisioner-deploy.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-client-provisioner labels: app: nfs-client-provisioner spec: replicas: 1 strategy: type: Recreate ## 设置升级策略为删除再创建(默认为滚动更新) selector: matchLabels: app: nfs-client-provisioner template: metadata: labels: app: nfs-client-provisioner spec: serviceAccountName: nfs-client-provisioner containers: - name: nfs-client-provisioner #image: gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0 image: registry.cn-beijing.aliyuncs.com/xngczl/nfs-subdir-external-provisione:v4.0.0 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME ## Provisioner的名称,以后设置的storageclass要和这个保持一致 value: nfs-client - name: NFS_SERVER ## NFS服务器地址,需和valumes参数中配置的保持一致 value: 192.168.119.2 - name: NFS_PATH ## NFS服务器数据存储目录,需和valumes参数中配置的保持一致 value: /volume1/nfs volumes: - name: nfs-client-root nfs: server: 192.168.119.2 ## NFS服务器地址 path: /volume1/nfs ## NFS服务器数据存储目录
创建 NFS Provisioner:
kubectl apply -f nfs-provisioner-deploy.yaml
创建 NFS SotageClass
创建一个 StoageClass,声明 NFS 动态卷提供者名称为 “nfs-storage”。
编辑nfs-storage.yaml
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs-storage annotations: storageclass.kubernetes.io/is-default-class: "false" ## 是否设置为默认的storageclass provisioner: nfs-client ## 动态卷分配者名称,必须和上面创建的"provisioner"变量中设置的Name一致 parameters: archiveOnDelete: "true" ## 设置为"false"时删除PVC不会保留数据,"true"则保留数据 mountOptions: - hard ## 指定为硬挂载方式 - nfsvers=4 ## 指定NFS版本,这个需要根据NFS Server版本号设置
创建 StorageClass:
kubectl apply -f nfs-storage.yaml
创建 PVC 和 Pod 进行测试
3.4.1、创建测试 PVC
在 Namespace 下创建一个测试用的 PVC 并观察是否自动创建是 PV 与其绑定。
编辑test-pvc.yaml
kind: PersistentVolumeClaim apiVersion: v1 metadata: name: test-pvc spec: storageClassName: nfs-storage #---需要与上面创建的storageclass的名称一致 accessModes: - ReadWriteOnce resources: requests: storage: 1Mi
创建 PVC:
kubectl apply -f test-pvc.yaml
查看 PVC 状态是否与 PV 绑定
利用 Kubectl 命令获取 pvc 资源,查看 STATUS 状态是否为 “Bound”。
[root@k8s-master ~]# kubectl get pvc test-pvc NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE test-pvc Bound pvc-164285a2-8101-4586-a186-e89497bb1b89 1Mi RWO nfs-storage 14h
创建测试 Pod 并绑定 PVC
创建一个测试用的 Pod,指定存储为上面创建的 PVC,然后创建一个文件在挂载的 PVC 目录中,然后进入 NFS 服务器下查看该文件是否存入其中。
编辑test-pod.yaml
kind: Pod apiVersion: v1 metadata: name: test-pod spec: containers: - name: test-pod image: busybox:latest command: - "/bin/sh" args: - "-c" - "touch /mnt/SUCCESS && exit 0 || exit 1" #创建一个名称为"SUCCESS"的文件 volumeMounts: - name: nfs-pvc mountPath: "/mnt" restartPolicy: "Never" volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-pvc
创建 Pod:
kubectl apply -f test-pod.yaml
标签:name,Kubernetes,创建,client,nfs,StorageClass,provisioner,NFS From: https://www.cnblogs.com/im17me/p/17004083.html