背景

NFS subdir external provisioner组件是使用现有的和已配置的NFS服务器来支持通过持久卷声明动态分发Kubernetes持久卷。持久化卷按以下方式命名${namespace}-${pvcName}-${pvName},在Kubernetes 环境中我们经常遇到是一个PV对应一个NFS实例场景,针对这种场景如果需要多个PVC&PV使用一个NFS实例,就需要提前根据NFS不同子目录创建大量的PV等待PVC去绑定,不太好维护,可以使用nfs-subdir-external-provisioner插件来实现动态创建子目录的需求,下面主要来介绍下

部署安装

环境准备:

  • kubernetes集群一个,我这里是使用的是腾讯云TKE集群
  • NFS服务器实例,或者使用云厂商提供的NFS产品
  • helm客户端,并且能够正常链接到集群

Helm方式安装

可以根据需求修改指定参数后部署

确保您的NFS服务器可以从您的Kubernetes集群访问,并获取连接到它所需的信息。至少需要它的主机名和共享路径。

$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/

# helm repo list  #查看添加helm repo仓库情况
NAME                            URL                                                               
tcr-chen-helm                   https://tcr-chen.tencentcloudcr.com/chartrepo/helm                
nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/

# 【可选步骤,可以将helm chart 包下载下来 上传到自己的镜像仓库,方便后续其他集群安装】
# 下载 helm chart 文件至本地目录,查看可以指定的 values 选项(可选)
$ helm pull nfs-subdir-external-provisioner/nfs-subdir-external-provisioner --untar
$ tar  zcvf nfs-subdir-external-provisioner-1.0.0.tgz nfs-subdir-external-provisioner/
$ helm cm-push nfs-subdir-external-provisioner-1.0.0.tgz  tcr-chen-helm
# 默认镜像是国外镜像,可以下载下来上传到自己的镜像仓库里面
$ docker pull k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
$ docker tag 932b0bface75 ccr.ccs.tencentyun.com/chenjingwei/nfs-subdir-external-provisioner:v4.0.2
$ docker push ccr.ccs.tencentyun.com/chenjingwei/nfs-subdir-external-provisioner:v4.0.2



# 使用类似下面命令安装 nfs-subdir-external-provisioner 资源
#  helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner  \
--set nfs.server=172.16.0.33  \
--set nfs.path=/nfs  \
--set image.repository=ccr.ccs.tencentyun.com/chenjingwei/nfs-subdir-external-provisioner \
--set image.tag=v4.0.2

#出现如下提示 表示安装成功
NAME: nfs-subdir-external-provisioner
LAST DEPLOYED: Tue Feb 15 13:22:03 2022
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: Non

手动YAML安装

1,创建账号ServiceAccount

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: ["nodes"]
    verbs: ["get", "list", "watch"]
  - 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

2,部署应用

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: default
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: ccr.ccs.tencentyun.com/chenjingwei/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: cluster.local/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 172.16.0.33              #替换成自己的NFS服务器地址
            - name: NFS_PATH
              value: /nfs                     #NFS上面的目录
      volumes:
        - name: nfs-client-root
          nfs:
            server: 172.16.0.33
            path: /nfs

3,创建storageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
provisioner: cluster.local/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false"

基本使用

前提是nfs-subdir-external-provisioner组件已经正常运行

1,配置使用 CFS 文件系统子目录的 PVC

使用上一步部署的nfs-subdir-external-provisioner动态创建存储卷。

部署后会默认生成一个StorageClass,默认存储类名是"nfs-client"(也可以在部署时自定义指定),如下:

# kubectl  get StorageClass | grep nfs-client
nfs-client          cluster.local/nfs-subdir-external-provisioner   4m8s

2,使用上面的StorageClass创建PVC

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: nfs-subdir-pvc
  namespace: cjweichen
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 10Gi
# kubectl  get pvc
NAME              STATUS   VOLUME                                   CAPACITY   ACCESS MODES   STORAGECLASS    AGE
nfs-subdir-pvc    Bound    pvc-5fdb9f45-6e98-4a9b-b6e0-920a6c7a6edc   10Gi       RWX           nfs-client    76s

会自动创建命令,命令命名方式是${namespace}-${pvcName}-${pvName}

3,查看自动创建的PV配置

image-20220919135239146

4,创建workload 挂载对应PVC

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: centos
  name: centos
  namespace: cjweichen
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: centos
  template:
    metadata:
      labels:
        k8s-app: centos
    spec:
      containers:
      - args:
        - -c
        - sleep 360000
        command:
        - /bin/sh
        image: centos:latest
        imagePullPolicy: IfNotPresent
        name: centos
        volumeMounts:
        - mountPath: /mnt
          name: nfs
      volumes:
      - name: nfs
        persistentVolumeClaim:
          claimName: nfs-subdir-pvc
# pwd
/nfs/cjweichen-nfs-subdir-pvc-pvc-5fdb9f45-6e98-4a9b-b6e0-920a6c7a6edc

image-20220919135928232

results matching ""

    No results matching ""