k8s nfs-client-provisioner异常
k8s集群升级(v1.19.x——>v1.20.x)后,nfs-client-provisioner工作异常:
pod状态:0/6 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.
动态PVC:一直生于pending状态
查看nfs-client-provisioner日志:
Could not construct reference to: '&v1.Endpoints{TypeMeta:v1.TypeMeta{Kind:"", APIVersion:""}, ObjectMeta:v1.ObjectMeta{Name:"", GenerateName:"", Namespace:"", SelfLink:"", UID:"", ResourceVersion:"", Generation:0, CreationTimestamp:v1.Time{Time:time.Time{wall:0x0, ext:0, loc:(*time.Location)(nil)}}, DeletionTimestamp:(*v1.Time)(nil), DeletionGracePeriodSeconds:(*int64)(nil), Labels:map[string]string(nil), Annotations:map[string]string(nil), OwnerReferences:[]v1.OwnerReference(nil), Initializers:(*v1.Initializers)(nil), Finalizers:[]string(nil), ClusterName:""}, Subsets:[]v1.EndpointSubset(nil)}' due to: 'selfLink was empty, can't make reference'. Will not report event: 'Normal' 'LeaderElection' 'nfs-client-provisioner-657d5d96c4-5g5h5_688b72ec-2dc3-11ed-a04a-06ad70053f24 stopped leading'
查资料发现,官方在k8s 1.20版本中基于对性能和统一API调用方式的初衷,移除了对SelfLink 的支持,而 nfs-provisioner 需要使用 SelfLink 特性。具体计划和原因可查看这个issue[2] 和 KEP[3]。
解决办法1:
修改apiserver配置文件,启动SelfLink功能。具体操作方法如下:
编辑文件</etc/kubernetes/manifests/kube-apiserver.yaml>,增加:- --feature-gates=RemoveSelfLink=false
apiVersion: v1 kind: Pod metadata: annotations: kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 172.26.1.2:6443 creationTimestamp: null labels: component: kube-apiserver tier: control-plane name: kube-apiserver namespace: kube-system spec: containers: - command: - kube-apiserver - --feature-gates=RemoveSelfLink=false #增加 - --advertise-address=172.26.1.2 - --allow-privileged=true - --authorization-mode=Node,RBAC - --client-ca-file=/etc/kubernetes/pki/ca.crt - --enable-admission-plugins=NodeRestriction
配置重启完成后,重启apiserver.
kubectl apply -f /etc/kubernetes/manifests/kube-apiserver.yaml
解决办法2:
使用新的不基于SelfLink 功能的 provisioner 镜像,重新创建 nfs-provisioner.
操作参考:https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner/tree/master/deploy
注:NFS相关错误处理
使用NFSv4.0挂载时报错信息:mount.nfs: Operation not permitted或mount.nfs: an incorrect mount option was specified,但是使用NFSv3却可以挂载成功。
修改StorageClass,增加连接参数:nfsvers=3
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: creationTimestamp: "2020-12-04T11:40:13Z" name: managed-nfs-storage resourceVersion: "189571112" selfLink: /apis/storage.k8s.io/v1/storageclasses/managed-nfs-storage uid: 8c3960c2-70a0-4524-b701-9fce3a7268d8 mountOptions: - nfsvers=3 - hard - nolock - noresvport parameters: archiveOnDelete: "false" provisioner: fuseim.pri/ifs reclaimPolicy: Delete volumeBindingMode: Immediate
报错信息:Output: mount.nfs: access denied by server while mounting
修改NFS Server配置,增加:insecure
[root@nfs-master ~]# cat /etc/exports /data/k8s-nfs *(insecure,rw,async,no_root_squash)
NFS常见参数说明: ro: 默认选项,以只读的方式共享。 rw: 以读写的方式共享。 root_squash: 将客户端使用的是root用户时,则映射到NFS服务器的用户为NFS的匿名用户(nfsnobody)。 no_root_squash: 将客户端使用的是root用户时,则映射到NFS服务器的用户依然为root用户。 all_squash: 默认选项,将所有访问NFS服务器的客户端的用户都映射为匿名用户,不管客户端使用的是什么用户。 anonuid: 设置映射到本地的匿名用户的UID anongid: 设置映射到本地的匿名用户的GID sync: 默认选项,保持数据同步,数据同步写入到内存和硬盘。 sync: 异步,先将数据写入到内存,在将数据写入到硬盘。 secure: 限制客户端只能从小于1024的tcp/ip端口连接nfs服务器(默认设置); insecure: 允许客户端从大于1024的tcp/ip端口连接服务器 subtree_check: 如果共享/usr/bin之类的子目录时,强制NFS检查父目录的权限(默认) no_subtree_check:和上面相对,不检查父目录权限 wdelay: 如果多个用户要写入NFS目录,则归组写入(默认) no_wdelay: 如果多个用户要写入NFS目录,则立即写入,当使用async时,无需此设置。 Hide: 在NFS共享目录中不共享其子目录 no_hide: 共享NFS目录的子目录