k3s 中 selflink 问题排查解决

2022-02-14
1分钟阅读时长

问题描述

在部署 statefulset 类型的工作负载时,动态创建 PV/PVC 是一种比较常用的配置方式,动态创建 PV/PVC 的方法基本如下:

  • 1、创建自己的 StorageClass 备用。
  • 2、创建 statefulset ,在 yaml 文件的 volumeClaimTemplates 块,添加 StorageClass 的名字。

说回今天遇到的问题,在部署 VictoriaMetric 时,想使用阿里云的 nfs 做为外部存储,以进一步提高可用性。先使用 mysql 的 demo 案例(yaml 示例见这里 k8s-yaml-hub),来测试下 statefulset 的在使用 nfs 时的分部情况。

一直启动不动来,查看 pvc 和 pods 信息如下:

  • 1、PVC 一直处于 pending 状态;
  • 2、mysql pods 显示:0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims. QQ20220215-092444@2x

原因分析

从上边的现象来看,是 PVC 没有创建成功,动态 PVC 中,是 provisioner 中来负责创建,查看其日志,看到如下错误信息:

I0214 10:22:35.436913 1 controller.go:1068] scheduleOperation[provision-mysql-sts/mysql-pvc-mysql-0[ac333031-e705-48d9-8180-4d2d583bb559]]
E0214 10:22:35.444757 1 controller.go:766] Unexpected error getting claim reference to claim "mysql-sts/mysql-pvc-mysql-0": selfLink was empty, can't make reference

Google 之后,很多人遇到了同样的问题,主要原因是,官方在 k8s 1.20 中基于对性能和统一apiserver调用方式的初衷,移除了对 SelfLink 的支持,而 nfs-provisioner 需要 SelfLink 该项功能。具体计划和原因可查看这个issueKEP

K3S 为兼容 K8S 应该也继承了该项修改,按 K8S 的方式修改测试了下,完美解决。

解决方案

解决问题主要有下边两种方式:

1、修改 apiserver 的配置文件,重新启用 SelfLink 功能。针对 K8S,可添加如下配置:

# /etc/kubernetes/manifests/kube-apiserver.yaml

spec:
  containers:
  - command:
    - kube-apiserver
    ...
    - --feature-gates=RemoveSelfLink=false # 增加

K3S 中没有 apiserver 的配置文件,可通过 systemd 的启动文件添加该参数,如下:

# /etc/systemd/system/k3s.service

ExecStart=/usr/local/bin/k3s \
    server \
        ...
        '--kube-apiserver-arg' \   # 新增
        'feature-gates=RemoveSelfLink=false' \  # 新增

若为新安装,可如下启用:

$ curl -sfL https://get.k3s.io | sh -s - --kube-apiserver-arg "feature-gates=RemoveSelfLink=false"

2、使用新的不基于 SelfLink 功能的 provisioner 镜像,重新创建 provisioner 容器。

若你能科学上网,可使用这个镜像:

gcr.io/k8s-staging-sig-storage/nfs-subdir-external-provisioner:v4.0.0

国内可使用这个镜像:

registry.cn-beijing.aliyuncs.com/pylixm/nfs-subdir-external-provisioner:v4.0.0

记录备查,希望对你有帮助。

Avatar
DeanWu 大家好,我是 DeanWu,一个努力成为「真正」 SRE 的人。