本文永久链接: https://www.xtplayer.cn/rke2/rke2-waiting-for-probes-kube-controller-manager-kube-scheduler/

问题背景

在使用 rancher 部署的自定义 rke2 集群时,可能会出现如下图的状态。即使更新集群配置触发集群更新,此状态也无法消失。

问题分析

在 rke2 架构中,每个节点会运行一个 rancher-system-agent 服务。可执行 systemctl status rancher-system-agent.service 查看服务状态,也可以执行 journalctl -xef -u rancher-system-agent.service 查看服务日志。

默认 rancher-system-agent 服务日志等级为 info,可以通过添加环境变量来提高日志等级。

cat >>/etc/systemd/system/rancher-system-agent.env<<EOF
RANCHER_DEBUG=true
CATTLE_DEBUG=true
CATTLE_LOGLEVEL=debug
EOF
systemctl restart rancher-system-agent.service
journalctl -xef -u rancher-system-agent.service

恢复默认日志等级:

echo '' > etc/systemd/system/rancher-system-agent.env
systemctl restart rancher-system-agent.service
journalctl -xef -u rancher-system-agent.service

在开启 debug 日志后,执行 journalctl -xef -u rancher-system-agent.service 可能会看到如下日志,或者带有 x509 字样的日志。


Sep 01 14:25:24 ZSMESP1PM3 rancher-system-agent[2958205]: time="2023-09-01T14:25:24+08:00" level=debug msg="[Probe: kube-scheduler] output was Get \"https://127.0.0.1:10259/healthz\": x509: certificate has expired or is not yet valid: current time 2023-09-01T14:25:24+08:00 is after 2023-08-29T00:38:57Z"
Sep 01 14:25:24 ZSMESP1PM3 rancher-system-agent[2958205]: time="2023-09-01T14:25:24+08:00" level=debug msg="[Probe: kube-scheduler] failed"
Sep 01 14:25:24 ZSMESP1PM3 rancher-system-agent[2958205]: time="2023-09-01T14:25:24+08:00" level=debug msg="[Probe: kube-controller-manager] output was Get \"https://127.0.0.1:10257/healthz\": x509: certificate has expired or is not yet valid: current time 2023-09-01T14:25:24+08:00 is after 2023-08-29T00:38:57Z"

证书更新

根据文档 https://docs.rke2.io/zh/advanced#%E8%AF%81%E4%B9%A6%E8%BD%AE%E6%8D%A2 说明,从 rke2 v1.21.8+rke2r1 开始支持证书更新。因此如果你的 rke2 版本低于 v1.21.8+rke2r1,建议先进行 rke2 版本升级。当 rke2 版本升级后,在 rancher ui 上执行集群证书更新。

其他关联问题

1,如果你当前 rke2 集群节点的 /var/lib/rancher/rke2/server/tls 目录下可以看到 kube-controller-manager/ 和 kube-scheduler/ 两个目录,在 rancher ui 进行证书更新后,这两个目录下的证书可能不会自动更新。截止此文档发布时,此问题依旧存在,相关 issue:https://github.com/cnrancher/pandaria/issues/2829

2,有可能因为证书已经过期,或者因为 rke2 版本低于 v1.21.8+rke2r1 不支持更新证书,最后导致证书更新失败。并且 rancher ui 会一直卡在 waiting for certificate rotation 状态,如下图。

关联问题解决思路

1,如果 rke2 版本低于 v1.21.8+rke2r1,那么在 rancher ui 上强制升级 rke2 版本到 v1.21.8+rke2r1+ 。如果当前 rancher 不支持部署 rke2 v1.21.8+rke2r1 ,则需要先升级 rancher 版本。

2,进入 /var/lib/rancher/rke2/server/tls 目录,把 kube-controller-manager/ 和 kube-scheduler/ 子目录删除。然后执行 systemctl stop rancher-system-agent.service; systemctl stop rke2-server.service; rke2 certificate rotate,最后再运行 systemctl start rke2-server.service; systemctl start rancher-system-agent.service

3,在主机上使用 crictl 工具删除与 k8s 系统相关的 pods 和容器

export CRI_CONFIG_FILE=/var/lib/rancher/rke2/agent/etc/crictl.yaml
# 查询 pods
/var/lib/rancher/rke2/bin/crictl pods
# 删除 pods
/var/lib/rancher/rke2/bin/crictl rmp <pod id>
# 删除容器
crictl rm -f $(crictl ps -q --name kube-controller-manager)
crictl rm -f $(crictl ps -q --name kube-scheduler)

4,在 rancher ui 或者使用 kubectl 命令行工具,删除下游集群 kube-system 命名空间下与 k8s 系统相关的 pod。删除 pod 后会自动重新创建。

5,如下图,如果存在异常节点,建议在 rancher ui 上进行删除。如果 rancher ui 上无法删除,那么在 local 集群 shell 命令中,执行 kubectl -n fleet-default edit machine custom-cfxxxxxxxx ,将 finalizers 下的内容全部删除然后保存。

6,在 local 集群|密文 中,找到与下游集群名称相关的 kubeconfig 密文,密文名称以 kubeconfig 结尾。将密文的 yaml 下载下来进行备份,然后将其删除。删除后正常情况会自动重新创建,如果没有重新创建,则尝试重启一下 rancher pod。如果重启 rancher pod 后还是没有重新创建,则将备份的文件重新导入集群(注意:重新导入前,需要删除 yaml 中的 uid 和 resourceVersion 字段)。

7,以上步骤执行完后,重新在 rancher ui 执行证书更新操作。

8,如果以上步骤操作完,集群状态或者某一个 master 节点状态依旧卡在 rke2 Waiting for probes: kube-controller-manager, kube-scheduler 状态,

  • 通过以下的脚本查询 rancher-system-agent.service 日志中是否还存在 x509 相关的证书错误。
cat >>/etc/systemd/system/rancher-system-agent.env<<EOF
RANCHER_DEBUG=true
CATTLE_DEBUG=true
CATTLE_LOGLEVEL=debug
EOF
systemctl restart rancher-system-agent.service
journalctl -xef -u rancher-system-agent.service
  • 通过以下脚本查询证书有效期是否都已经更新。
for crt in /var/lib/rancher/rke2/server/tls/*.crt; do
printf '%s: %s\n' \
"$(date --date="$(openssl x509 -enddate -noout -in "$crt"|cut -d= -f 2)" --iso-8601)" \
"$crt"
done | sort
for crt in /var/lib/rancher/rke2/server/tls/kube-controller-manager/*.crt; do
printf '%s: %s\n' \
"$(date --date="$(openssl x509 -enddate -noout -in "$crt"|cut -d= -f 2)" --iso-8601)" \
"$crt"
done | sort
for crt in /var/lib/rancher/rke2/server/tls/kube-scheduler/*.crt; do
printf '%s: %s\n' \
"$(date --date="$(openssl x509 -enddate -noout -in "$crt"|cut -d= -f 2)" --iso-8601)" \
"$crt"
done | sort
  • 通过以下命令模拟检测 kube-scheduler 和 kube-controller-manager 的健康检查是否正常。

(
curl --cacert /var/lib/rancher/rke2/server/tls/kube-controller-manager/kube-controller-manager.crt \
https://127.0.0.1:10257/healthz >/dev/null 2>&1 \
&& echo "[OK] Kube Controller probe" \
|| echo "[FAIL] Kube Controller probe";

curl --cacert /var/lib/rancher/rke2/server/tls/kube-scheduler/kube-scheduler.crt \
https://127.0.0.1:10259/healthz >/dev/null 2>&1 \
&& echo "[OK] Scheduler probe" \
|| echo "[FAIL] Scheduler probe";
)

以上几个步骤操作查询后,如果 rancher-system-agent.service 日志没有报错,并且证书有效期也成功更新。那么需要尝试执行以下的步骤,以下的命令在任意一个 master 节点上操作即可。

cat /etc/rancher/rke2/rke2.yaml|grep client-key-data|awk -F': ' '{print $2}'|base64 -d > client-key.pem
cat /etc/rancher/rke2/rke2.yaml|grep client-certificate-data|awk -F': ' '{print $2}'|base64 -d > client-cert.pem
cat /etc/rancher/rke2/rke2.yaml|grep certificate-authority-data|awk -F': ' '{print $2}'|base64 -d > cacert.pem

curl -v -XPATCH \
-H "Content-Type: application/merge-patch+json" \
-H "Accept: application/json" \
--key ./client-key.pem \
--cert ./client-cert.pem \
--cacert ./cacert.pem \
-d '{"status":{"conditions":[{"lastTransitionTime":"2023-05-08T04:40:25Z","severity":"Info","type":"Provisioned","status":"True","reason":"","message":""}]}}' \
'https://127.0.0.1:6443/apis/cluster.x-k8s.io/v1beta1/namespaces/fleet-default/machines/custom-cf8e49b18593/status'

注意

  • 需要修改 URL 中的 machine id,比如 custom-cf8e49b18593。

  • kubectl 无法使用 patch/edit 编辑 machine.status,只能通过 api 进行修改。

  • 其中证书信息都是从 kubeconfig 中获取,也可以使用 admin 权限的 token 进行请求。

以上操作执行之后,节点应该跳过 rke2 Waiting for probes: kube-controller-manager, kube-scheduler 状态。