1.20版本TKE集群使用nfs-subdir-external-provisioner挂载nfs

使用tke的时候,很多时候会用到共享存储,tke默认支持的共享存储有cos和cfs(类似于nfs),一般使用cfs的比较多,但是现在tke的cfs组件现在还不支持共享cfs实例,也就是说你自动创建pvc,每个pvc就会用到一个共享文件系统,这样比较浪费资源,其实我们可以在tke上使用自建nfs来进行存储,k8s的1.20之前版本都是推荐使用K8S NFS Provisioner,但是现在这个组件不维护了,并且不兼容1.20以后版本的k8s集群。

官方推荐使用NFS Subdir External Provisioner来作为动态分配组件,下面我们来介绍下如何在tke的1.20版本上部署使用nfs-subdir-external-provisioner,这里的部署方式同样适用于自建的k8s。

nfs-subdir-external-provisioner的github地址:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

1. 搭建nfs服务器

搭建nfs服务器,这里就不说明了,可以参考之前的文档的第一步来进行部署。
https://cloud.tencent.com/developer/article/1699864

2. 部署nfs-subdir-external-provisioner

部署nfs-subdir-external-provisioner有2种方式,一种是helm,还有一种是直接用原生的yaml部署。

2.1 helm部署

helm部署,可以参考如下命令进行部署

$ helm repo add nfs-subdir-external-provisioner https://kubernetes-sigs.github.io/nfs-subdir-external-provisioner/
$ helm install nfs-subdir-external-provisioner nfs-subdir-external-provisioner/nfs-subdir-external-provisioner \\
    --set nfs.server=x.x.x.x \\
    --set nfs.path=/nfs/data

nfs.server是nfs的的服务器地址
nfs.path是存储目录

2.2 yaml部署

这里我们默认将组件部署在default命名空间下,如果需要部署到其他ns,需要修改yaml的命名空间配置,这里首先部署下rbac文件

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

然后我们部署下NFS-Subdir-External-Provisioner的deployment

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/niewx-k8s/nfs-subdir-external-provisioner:v4.0.2
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner  ## Provisioner的名称,以后设置的storageclass要和这个保持一致
            - name: NFS_SERVER  ## NFS服务器地址,需和valumes参数中配置的保持一致
              value: 10.0.8.6
            - name: NFS_PATH  ## NFS服务器数据存储目录,需和valumes参数中配置的保持一致
              value: /nfs/data
      volumes:
        - name: nfs-client-root
          nfs:
            server: 10.0.8.6 ## NFS服务器地址
            path: /nfs/data ## NFS服务器数据存储目录

接下来我们创建下StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client
  annotations:
    storageclass.kubernetes.io/is-default-class: "false" # 是否设置为默认的storageclass
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "false" # 设置为"false"时删除PVC不会保留数据,"true"则保留数据
mountOptions:
  - hard # 指定为硬挂载方式
  - nfsvers=4 # 指定NFS版本,这个需要根据NFS Server版本号设置,可以nfsstat -m查看

3. 测试创建pod通过pvc挂载

首先创建下pvc

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
spec:
  storageClassName: nfs-client
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Mi

创建deploy挂载这个pvc

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    k8s-app: nfs-volume-test
    qcloud-app: nfs-volume-test
  name: nfs-volume-test
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: nfs-volume-test
      qcloud-app: nfs-volume-test
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: nfs-volume-test
        qcloud-app: nfs-volume-test
    spec:
      containers:
      - image: nginx:latest
        imagePullPolicy: Always
        name: nfs-volume-test
        resources: {}
        securityContext:
          privileged: false
        volumeMounts:
        - mountPath: /tmp
          name: vol
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
      volumes:
      - name: vol
        persistentVolumeClaim:
          claimName: test-claim

我们测试下在容器内创建一个文件

然后看下是否会在nfs服务器的存储目录找到,可以发下已经同步过来的,nfs的存储目录默认会生成和pvc对应的子目录挂载

创建StatefulSet通过自动生成pvc的方式挂载下看看

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
  labels:
    app: centos
    qcloud: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 2
  volumeClaimTemplates:
  - metadata:
      name: test
      annotations:
        volume.beta.kubernetes.io/storage-class: "nfs-client"
    spec:
      accessModes: [ "ReadWriteMany" ]
      resources:
        requests:
          storage: 1Mi
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
      - name: nginx
        image: nginx
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - mountPath: "/etc/nginx/conf.d"
          name: test

创建后,会自动生成2个pvc,然后nfs上也会生成对应的存储目录

版权声明:
作者:聂伟星
链接:https://jkboy.com/archives/18002.html
来源:随风的博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
海报
1.20版本TKE集群使用nfs-subdir-external-provisioner挂载nfs
使用tke的时候,很多时候会用到共享存储,tke默认支持的共享存储有cos和cfs(类似于nfs),一般使用cfs的比较多,但是现在tke的cfs组件现在还不支...
<<上一篇
下一篇>>