当前位置:首页 > 通信资讯 > 正文

k8s安装nfs(k8s使用nfs性能如何)

k8s安装nfs(k8s使用nfs性能如何)

背景

NFS在k8s中作为volume存储已经没有什么新奇的了,这个是最简单也是最容易上手的一种文件存储。最近有一个需求需要在k8s中使用NFS存储,于是记录如下,并且还存在一些骚操作和过程中遇到的坑点,同时记录如下。

访问nfs provisioner的GitHub仓库会发现他提示你该仓库已经被个人归档并且状态已经是只读了。

老的NFS仓库地址:https://github.com/kubernetes-retired/external-storage/tree/master/nfs-client

下面Deprecated表示仓库已经移动到了另外一个GitHub地址了,也就是说他这个仓库已经不在更新了,持续更新的仓库是Moved to 后面指定的仓库了。

新仓库地址:https://github.com/lorenzofaresin/nfs-subdir-external-provisioner

发现更新的仓库中相比老仓库多了一个功能:添加了一个参数pathPattern,实际上也就是通过设置这个参数可以配置PV的子目录。

k8s安装nfs(k8s使用nfs性能如何)

nfs-client-provisioner部署

带着好奇心我们来部署一下新的NFS,以下yaml配置文件可以在项目中的deploy目录中找到。我这里的配置根据我的环境稍微做了更改,比如NFS的服务的IP地址。你们根据实际情况修改成自己的nfs服务器地址和path路径。

「本次实践在k8s 1.19.0上」

class.yaml

  1. $catclass.yaml
  2. apiVersion:storage.k8s.io/v1
  3. kind:StorageClass
  4. metadata:
  5. name:managed-nfs-storage
  6. provisioner:k8s-sigs.io/nfs-subdir-external-provisioner#orchooseanothername,mustmatchdeployment'senvPROVISIONER_NAME'
  7. parameters:
  8. archiveOnDelete:"false"

deployment.yaml

  1. apiVersion:apps/v1
  2. kind:Deployment
  3. metadata:
  4. name:nfs-client-provisioner
  5. labels:
  6. app:nfs-client-provisioner
  7. #replacewithnamespacewhereprovisionerisdeployed
  8. namespace:kube-system
  9. spec:
  10. replicas:1
  11. strategy:
  12. type:Recreate
  13. selector:
  14. matchLabels:
  15. app:nfs-client-provisioner
  16. template:
  17. metadata:
  18. labels:
  19. app:nfs-client-provisioner
  20. spec:
  21. serviceAccountName:nfs-client-provisioner
  22. containers:
  23. -name:nfs-client-provisioner
  24. image:k8s.gcr.io/sig-storage/nfs-subdir-external-provisioner:v4.0.2
  25. volumeMounts:
  26. -name:nfs-client-root
  27. mountPath:/persistentvolumes
  28. env:
  29. -name:PROVISIONER_NAME
  30. value:k8s-sigs.io/nfs-subdir-external-provisioner
  31. -name:NFS_SERVER
  32. value:172.16.33.4
  33. -name:NFS_PATH
  34. value:/
  35. volumes:
  36. -name:nfs-client-root
  37. nfs:
  38. server:172.16.33.4
  39. path:/

rbac.yaml

  1. apiVersion:v1
  2. kind:ServiceAccount
  3. metadata:
  4. name:nfs-client-provisioner
  5. #replacewithnamespacewhereprovisionerisdeployed
  6. namespace:kube-system
  7. ---
  8. kind:ClusterRole
  9. apiVersion:rbac.authorization.k8s.io/v1
  10. metadata:
  11. name:nfs-client-provisioner-runner
  12. rules:
  13. -apiGroups:[""]
  14. resources:["nodes"]
  15. verbs:["get","list","watch"]
  16. -apiGroups:[""]
  17. resources:["persistentvolumes"]
  18. verbs:["get","list","watch","create","delete"]
  19. -apiGroups:[""]
  20. resources:["persistentvolumeclaims"]
  21. verbs:["get","list","watch","update"]
  22. -apiGroups:["storage.k8s.io"]
  23. resources:["storageclasses"]
  24. verbs:["get","list","watch"]
  25. -apiGroups:[""]
  26. resources:["events"]
  27. verbs:["create","update","patch"]
  28. ---
  29. kind:ClusterRoleBinding
  30. apiVersion:rbac.authorization.k8s.io/v1
  31. metadata:
  32. name:run-nfs-client-provisioner
  33. subjects:
  34. -kind:ServiceAccount
  35. name:nfs-client-provisioner
  36. #replacewithnamespacewhereprovisionerisdeployed
  37. namespace:kube-system
  38. roleRef:
  39. kind:ClusterRole
  40. name:nfs-client-provisioner-runner
  41. apiGroup:rbac.authorization.k8s.io
  42. ---
  43. kind:Role
  44. apiVersion:rbac.authorization.k8s.io/v1
  45. metadata:
  46. name:leader-locking-nfs-client-provisioner
  47. #replacewithnamespacewhereprovisionerisdeployed
  48. namespace:kube-system
  49. rules:
  50. -apiGroups:[""]
  51. resources:["endpoints"]
  52. verbs:["get","list","watch","create","update","patch"]
  53. ---
  54. kind:RoleBinding
  55. apiVersion:rbac.authorization.k8s.io/v1
  56. metadata:
  57. name:leader-locking-nfs-client-provisioner
  58. #replacewithnamespacewhereprovisionerisdeployed
  59. namespace:kube-system
  60. subjects:
  61. -kind:ServiceAccount
  62. name:nfs-client-provisioner
  63. #replacewithnamespacewhereprovisionerisdeployed
  64. namespace:kube-system
  65. roleRef:
  66. kind:Role
  67. name:leader-locking-nfs-client-provisioner
  68. apiGroup:rbac.authorization.k8s.io

注意:

  • 镜像无法拉取的话可以从国外机器拉取镜像然后再导入
  • rbac基本无需更改,配置子目录的时候需要更改class.yaml文件,后面会说

创建所有资源文件

  1. kubectlapply-fclass.yaml-fdeployment.yaml-frbac.yaml

通过一个简单的例子来创建pvc

  1. $cattest-pvc-2.yaml
  2. kind:PersistentVolumeClaim
  3. apiVersion:v1
  4. metadata:
  5. name:test-pvc-2
  6. namespace:nacos
  7. spec:
  8. storageClassName:"managed-nfs-storage"
  9. accessModes:
  10. -ReadWriteMany
  11. resources:
  12. requests:
  13. storage:10Gi
  14. $cattest-nacos-pod-2.yaml
  15. apiVersion:apps/v1
  16. kind:StatefulSet
  17. metadata:
  18. name:nacos-c1-sit-tmp-1
  19. labels:
  20. appEnv:sit
  21. appName:nacos-c1-sit-tmp-1
  22. namespace:nacos
  23. spec:
  24. serviceName:nacos-c1-sit-tmp-1
  25. replicas:3
  26. selector:
  27. matchLabels:
  28. appEnv:sit
  29. appName:nacos-c1-sit-tmp-1
  30. template:
  31. metadata:
  32. labels:
  33. appEnv:sit
  34. appName:nacos-c1-sit-tmp-1
  35. spec:
  36. dnsPolicy:ClusterFirst
  37. containers:
  38. -name:nacos
  39. image:www.ayunw.cn/library/nacos/nacos-server:1.4.1
  40. ports:
  41. -containerPort:8848
  42. env:
  43. -name:NACOS_REPLICAS
  44. value:"1"
  45. -name:MYSQL_SERVICE_HOST
  46. value:mysql.ayunw.cn
  47. -name:MYSQL_SERVICE_DB_NAME
  48. value:nacos_c1_sit
  49. -name:MYSQL_SERVICE_PORT
  50. value:"3306"
  51. -name:MYSQL_SERVICE_USER
  52. value:nacos
  53. -name:MYSQL_SERVICE_PASSWORD
  54. value:xxxxxxxxx
  55. -name:MODE
  56. value:cluster
  57. -name:NACOS_SERVER_PORT
  58. value:"8848"
  59. -name:PREFER_HOST_MODE
  60. value:hostname
  61. -name:SPRING_DATASOURCE_PLATFORM
  62. value:mysql
  63. -name:TOMCAT_ACCESSLOG_ENABLED
  64. value:"true"
  65. -name:NACOS_AUTH_ENABLE
  66. value:"true"
  67. -name:NACOS_SERVERS
  68. value:nacos-c1-sit-0.nacos-c1-sit-tmp-1.nacos.svc.cluster.local:8848nacos-c1-sit-1.nacos-c1-sit-tmp-1.nacos.svc.cluster.local:8848nacos-c1-sit-2.nacos-c1-sit-tmp-1.nacos.svc.cluster.local:8848
  69. imagePullPolicy:IfNotPresent
  70. resources:
  71. limits:
  72. cpu:500m
  73. memory:5Gi
  74. requests:
  75. cpu:100m
  76. memory:512Mi
  77. volumeMounts:
  78. -name:data
  79. mountPath:/home/nacos/plugins/peer-finder
  80. subPath:peer-finder
  81. -name:data
  82. mountPath:/home/nacos/data
  83. subPath:data
  84. volumeClaimTemplates:
  85. -metadata:
  86. name:data
  87. spec:
  88. storageClassName:"managed-nfs-storage"
  89. accessModes:
  90. -"ReadWriteMany"
  91. resources:
  92. requests:
  93. storage:10Gi

查看pvc以及nfs存储中的数据

  1. #ll
  2. total12
  3. drwxr-xr-x4rootroot4096Aug313:30nacos-data-nacos-c1-sit-tmp-1-0-pvc-90d74547-0c71-4799-9b1c-58d80da51973
  4. drwxr-xr-x4rootroot4096Aug313:30nacos-data-nacos-c1-sit-tmp-1-1-pvc-18b3e220-d7e5-4129-89c4-159d9d9f243b
  5. drwxr-xr-x4rootroot4096Aug313:31nacos-data-nacos-c1-sit-tmp-1-2-pvc-26737f88-35cd-42dc-87b6-3b3c78d823da
  6. #llnacos-data-nacos-c1-sit-tmp-1-0-pvc-90d74547-0c71-4799-9b1c-58d80da51973
  7. total8
  8. drwxr-xr-x2rootroot4096Aug313:30data
  9. drwxr-xr-x2rootroot4096Aug313:30peer-finder

可以发现手动创建了一个PVC,并且创建一个nacos的deployment使用这个PVC后已经自动创建出相应的PV并且与之绑定,且挂载了数据。

配置子目录

删除之前创建的class.yaml,添加pathPattern参数,然后重新生成sc

  1. $kubectldelete-fclass.yaml
  2. $viclass.yaml
  3. apiVersion:storage.k8s.io/v1
  4. kind:StorageClass
  5. metadata:
  6. name:managed-nfs-storage
  7. provisioner:k8s-sigs.io/nfs-subdir-external-provisioner#orchooseanothername,mustmatchdeployment'senvPROVISIONER_NAME'
  8. parameters:
  9. archiveOnDelete:"false"
  10. #添加以下参数
  11. pathPattern:"${.PVC.namespace}/${.PVC.annotations.nfs.io/storage-path}"

创建pvc来测试生成的PV目录是否生成了子目录

  1. $cattest-pvc.yaml
  2. kind:PersistentVolumeClaim
  3. apiVersion:v1
  4. metadata:
  5. name:test-pvc-2
  6. namespace:nacos
  7. annotations:
  8. nfs.io/storage-path:"test-path-two"#notrequired,dependingonwhetherthisannotationwasshowninthestorageclassdescription
  9. spec:
  10. storageClassName:"managed-nfs-storage"
  11. accessModes:
  12. -ReadWriteMany
  13. resources:
  14. requests:
  15. storage:100Mi

创建资源

  1. kubectlapply-fclass.yaml-ftest-pvc.yaml

查看结果

  1. #pwd
  2. /data/nfs#llnacos/
  3. total4
  4. drwxr-xr-x2rootroot4096Aug310:21nacos-pvc-c1-pro
  5. #tree-L2.
  6. .
  7. └──nacos
  8. └──nacos-pvc-c1-pro
  9. 2directories,0files

在mount了nfs的机器上查看生成的目录,发现子目录的确已经生成,并且子目录的层级是以"命名空间/注解名称"为规则的。刚好符合了上面StorageClass中定义的pathPattern规则。

provisioner高可用

生产环境中应该尽可能的避免单点故障,因此此处考虑provisioner的高可用架构 更新后的provisioner配置如下:

  1. $catnfs-deployment.yaml
  2. apiVersion:apps/v1
  3. kind:Deployment
  4. metadata:
  5. name:nfs-client-provisioner
  6. labels:
  7. app:nfs-client-provisioner
  8. #replacewithnamespacewhereprovisionerisdeployed
  9. namespace:kube-system
  10. spec:
  11. #因为要实现高可用,所以配置3个pod副本
  12. replicas:3
  13. strategy:
  14. type:Recreate
  15. selector:
  16. matchLabels:
  17. app:nfs-client-provisioner
  18. template:
  19. metadata:
  20. labels:
  21. app:nfs-client-provisioner
  22. spec:
  23. serviceAccountName:nfs-client-provisioner
  24. imagePullSecrets:
  25. -name:registry-auth-paas
  26. containers:
  27. -name:nfs-client-provisioner
  28. image:www.ayunw.cn/nfs-subdir-external-provisioner:v4.0.2-31-gcb203b4
  29. imagePullPolicy:IfNotPresent
  30. volumeMounts:
  31. -name:nfs-client-root
  32. mountPath:/persistentvolumes
  33. env:
  34. -name:PROVISIONER_NAME
  35. value:k8s-sigs.io/nfs-subdir-external-provisioner
  36. #设置高可用允许选举
  37. -name:ENABLE_LEADER_ELECTION
  38. value:"True"
  39. -name:NFS_SERVER
  40. value:172.16.33.4
  41. -name:NFS_PATH
  42. value:/
  43. volumes:
  44. -name:nfs-client-root
  45. nfs:
  46. server:172.16.33.4
  47. path:/

重建资源

  1. kubectldelete-fnfs-class.yaml-fnfs-deployment.yaml
  2. kubectlapply-fnfs-class.yaml-fnfs-deployment.yaml

查看provisioner高可用是否生效

  1. #kubectlgetpo-nkube-system|grepnfs
  2. nfs-client-provisioner-666df4d979-fdl8l1/1Running020s
  3. nfs-client-provisioner-666df4d979-n54ps1/1Running020s
  4. nfs-client-provisioner-666df4d979-s4cql1/1Running020s
  5. #kubectllogs-f--tail=20nfs-client-provisioner-666df4d979-fdl8l-nkube-system
  6. I080306:04:41.4064411leaderelection.go:242]attemptingtoacquireleaderleasekube-system/nfs-provisioner-baiducfs...
  7. ^C
  8. #kubectllogs-f--tail=20-nkube-systemnfs-client-provisioner-666df4d979-n54ps
  9. I080306:04:41.9616171leaderelection.go:242]attemptingtoacquireleaderleasekube-system/nfs-provisioner-baiducfs...
  10. ^C
  11. [root@qing-core-kube-master-srv1nfs-storage]#kubectllogs-f--tail=20-nkube-systemnfs-client-provisioner-666df4d979-s4cql
  12. I080306:04:39.5742581leaderelection.go:242]attemptingtoacquireleaderleasekube-system/nfs-provisioner-baiducfs...
  13. I080306:04:39.5933881leaderelection.go:252]successfullyacquiredleasekube-system/nfs-provisioner-baiducfs
  14. I080306:04:39.5935191event.go:278]Event(v1.ObjectReference{Kind:"Endpoints",Namespace:"kube-system",Name:"nfs-provisioner-baiducfs",UID:"3d5cdef6-57da-445e-bcd4-b82d0181fee4",APIVersion:"v1",ResourceVersion:"1471379708",FieldPath:""}):type:'Normal'reason:'LeaderElection'nfs-client-provisioner-666df4d979-s4cql_590ac6eb-ccfd-4653-9de5-57015f820b84becameleader
  15. I080306:04:39.5935591controller.go:820]Startingprovisionercontrollernfs-provisioner-baiducfs_nfs-client-provisioner-666df4d979-s4cql_590ac6eb-ccfd-4653-9de5-57015f820b84!
  16. I080306:04:39.6945051controller.go:869]Startedprovisionercontrollernfs-provisioner-baiducfs_nfs-client-provisioner-666df4d979-s4cql_590ac6eb-ccfd-4653-9de5-57015f820b84!

通过successfully acquired lease kube-system/nfs-provisioner-baiducfs可以看到第三个pod成功被选举为leader节点了,高可用生效。

报错

在操作过程中遇到describe pod发现报错如下:

  1. Mountingarguments:--description=Kubernetestransientmountfor/data/kubernetes/kubelet/pods/2ca70aa9-433c-4d10-8f87-154ec9569504/volumes/kubernetes.io~nfs/nfs-client-root--scope--mount-tnfs172.16.41.7:/data/nfs_storage/data/kubernetes/kubelet/pods/2ca70aa9-433c-4d10-8f87-154ec9569504/volumes/kubernetes.io~nfs/nfs-client-root
  2. Output:Runningscopeasunit:run-rdcc7cfa6560845969628fc551606e69d.scope
  3. mount:/data/kubernetes/kubelet/pods/2ca70aa9-433c-4d10-8f87-154ec9569504/volumes/kubernetes.io~nfs/nfs-client-root:badoption;forseveralfilesystems(e.g.nfs,cifs)youmightneeda/sbin/mount.<type>helperprogram.
  4. WarningFailedMount10skubelet,node1.ayunw.cnMountVolume.SetUpfailedforvolume"nfs-client-root":mountfailed:exitstatus32
  5. Mountingcommand:systemd-run

解决方式:经排查原因是pod被调度到的节点上没有安装nfs客户端,只需要安装一下nfs客户端nfs-utils即可。

原文链接:https://mp.weixin.qq.com/s/3Oo_bSg5umu2vdH8XgsGQA

如果您对该产品感兴趣,请填写办理(客服微信:xiaoxiongyidong)

为您推荐:

发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。