本文永久链接: https://www.xtplayer.cn/rke2/rke2-configuration-update-occurs-when-rancher-changes-the-url-or-ca-certificate/

当 Rancher 的访问 URL 或 CA 证书发生变化时,RKE2 集群中的 Agent 节点(Worker 节点)会因为无法正确连接到 Rancher Server(即 RKE2 的 Server 节点)而失联。你需要更新每个 RKE2 Agent 节点的配置,然后重启服务。

Rancher 全局 server-url 更新

  1. 登录 Rancher UI,在左上角点击下拉菜单,进入 全局设置(Global Settings)。
  2. 在“系统设置”(Advanced/System Settings)选项卡中,找到 server-url 这一项。
  3. 点击编辑,将其值修改为你的新 Rancher Server 地址(例如 https://new-rancher.yourdomain.com),然后保存。

更新下游集群 rancher-system-agent 配置

场景一、rancher-system-agent 和 cluster agent 还可以正常连接到 rancher url

  1. 获取集群 ID

首先,列出 Rancher 管理中的所有集群,记下它们的 ID:

kubectl get clusters.management.cattle.io

你会看到类似这样的输出,记下 NAME 那一列的所有 ID(例如 c-m-abcdelocal)。

  1. 为每个集群打上“强制更新”的标记

    对上面列表中的每一个集群 ID(包括 local),执行以下命令之一:

    • 如果你的 Rancher 版本 >= v2.7.x,使用 annotate 命令

      kubectl annotate clusters.management.cattle.io <集群ID> io.cattle.agent.force.deploy=true
    • 如果你的 Rancher 版本 <= v2.6.x,使用 patch 命令

      kubectl patch clusters.management.cattle.io <集群ID> -p '{"status":{"agentImage":"dummy"}}' --type merge
    1. 执行以上操作后,Agent 会收到信号并开始自我重建。这个过程通常需要几分钟。

场景二、rancher-system-agent 和 cluster agent 已无法连接到 rancher url

这种情况下,即使通过场景一的方法配置,因为无法连接下游集群,配置无法进行下发。这种情况只能手动去更新相关配置。

方案一,通过 rancher api 接口去获取新的 rancher-system-agent 配置

拷贝以下内容并保存为脚本文件,修改其中的 CATTLE_SERVER_URL 和 CATTLE_TOKEN 。

  • CATTLE_SERVER_URL:rancher 的访问地址
  • CATTLE_TOKEN:这个 token 非用户的 API KEY。需要进入集群管理,点击目标集群,点击节点注册,在节点注册命令中获取此 token。如果设置用户 API KEY 会报 500 错误。
#!/bin/bash
set -e # 遇到错误立即退出
CATTLE_SERVER_URL=https://10.201.170.123:8443
# 注意: 需要进入集群管理,点击目标集群,点击节点注册,在节点注册命令中获取此 token。如果设置用户 API KEY 会报 500 错误。
CATTLE_TOKEN=hlqb8jsw4xdx6pfz8xxxxxmlmhpsx9jfbnzlctvvqbx8b8x

CATTLE_AGENT_VAR_DIR=/var/lib/rancher/agent
# 如果启用 debug, 添加 -v 参数
CURL_LOG="-sS"

# 创建目录
mkdir -p ${CATTLE_AGENT_VAR_DIR}

# 检查 cattle-id 文件是否存在
if [ ! -f "/etc/rancher/agent/cattle-id" ]; then
echo "Error: /etc/rancher/agent/cattle-id not found" >&2
exit 1
fi

# 备份现有配置
if [ -f ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json ]; then
BACKUP_FILE="${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info-$(date +%Y%m%d_%H%M%S).json"
cp ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json ${BACKUP_FILE}
echo "Backup created: ${BACKUP_FILE}"
fi

# 获取新的连接信息
CATTLE_ID=$(cat /etc/rancher/agent/cattle-id)
echo "Using cattle-id: ${CATTLE_ID}"

# 执行 curl 请求
HTTP_CODE=$(curl -kL --connect-timeout 60 --max-time 60 --write-out "%{http_code}\n" ${CURL_LOG} \
-H "Authorization: Bearer ${CATTLE_TOKEN}" \
-H "X-Cattle-Id: ${CATTLE_ID}" \
"${CATTLE_SERVER_URL}/v3/connect/agent" \
-o ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp)

# 检查 HTTP 状态码
case $HTTP_CODE in
200|201|204)
# 检查文件是否为空或无效 JSON
if [ ! -s ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp ]; then
echo "Error: Downloaded file is empty" >&2
exit 1
fi

# 验证是否为有效 JSON
if ! jq . ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp > /dev/null 2>&1; then
echo "Error: Downloaded file is not valid JSON" >&2
cat ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp
exit 1
fi

# 移动文件到最终位置
mv ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json
chmod 600 ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json
echo "Connection info updated successfully"

# 重启 rancher-system-agent 服务
echo "Restarting rancher-system-agent service..."
if systemctl restart rancher-system-agent; then
echo "Service restarted successfully"

# 可选:等待服务启动并检查状态
sleep 3
if systemctl is-active --quiet rancher-system-agent; then
echo "rancher-system-agent is running"
# 显示最近的日志
echo "Recent logs:"
journalctl -u rancher-system-agent.service --since "1 minute ago" --no-pager --lines=10
else
echo "Warning: rancher-system-agent service is not running" >&2
exit 1
fi
else
echo "Error: Failed to restart rancher-system-agent service" >&2
exit 1
fi
;;
*)
echo "Error: Failed to update connection info, HTTP code: ${HTTP_CODE}" >&2
# 显示错误响应内容
if [ -f ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp ]; then
echo "Error response:" >&2
cat ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp >&2
rm -f ${CATTLE_AGENT_VAR_DIR}/rancher2_connection_info.json.tmp
fi
exit 1
;;
esac

方案二、在 local 集群中使用 kubectl 恢复 rancher-system-agent 配置

  • KUBECONFIG: local k8s 集群的 kubeconfig 配置文件
  • RANCHER_URL:rancher 的访问地址
  • NODE_NAME:节点名称,在集群管理中获取,以 custom 开头
export KUBECONFIG=/home/hxl/local-kubeconfig.yaml
export RANCHER_URL=https://10.201.170.123:8443
export NODE_NAME=custom-b087403164cd

export NAMESPACE=fleet-default
export RANCHER_CACERT=$( kubectl get settings.management.cattle.io cacerts -o jsonpath='{.value}' | base64 -w 0 )
export TOKEN=$( kubectl -n fleet-default get secrets -l cattle.io/service-account.name=${NODE_NAME}-machine-plan -o jsonpath='{.items[0].data.token}' | base64 -d )

# Generate the kubeconfig content with expanded variables
KUBE_CONFIG=$(cat <<EOF
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: ${RANCHER_CACERT}
server: ${RANCHER_URL}
name: agent
contexts:
- context:
cluster: agent
user: agent
name: agent
current-context: agent
kind: Config
preferences: {}
users:
- name: agent
user:
token: ${TOKEN}
EOF
)

# Output the JSON
cat > rancher2_connection_info.json.tmp <<EOF
{
"kubeConfig": "$(echo "${KUBE_CONFIG}" | sed 's/"/\\"/g' | awk '{printf "%s\\n", $0}' | sed 's/$/\\n/' | tr -d '\n')",
"namespace": "${NAMESPACE}",
"secretName": "${NODE_NAME}-machine-plan"
}
EOF

最后将生成的 rancher2_connection_info.json.tmp 拷贝到 NODE_NAME 指定的节点, 并重命名为 /var/lib/rancher/agent/rancher2_connection_info.json