K3s 默认自签 CA 到期前如何用 rotate-default-ca-certs.sh 轮换集群 CA 证书
2026/9/12 17:20:52 网站建设 项目流程

K3s 默认自签 CA 到期前如何用 rotate-default-ca-certs.sh 轮换集群 CA 证书

【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3s

K3s 在集群首次启动时会自动生成一套自签 CA——Server CA、Client CA、Request Header CA、etcd Peer CA、etcd Client CA,外加 ServiceAccount Token 签名密钥。这些 CA 证书有效期为 3650 天(约 10 年),且不会自动续期;一旦任何一张 CA 过期,由它签发的证书都会失效,导致集群大范围故障。这篇文章给出在默认自签 CA 到期前完成轮换的完整路径:用仓库提供的示例脚本 rotate-default-ca-certs.sh 生成新的交叉签名 CA 证书,再用k3s certificate rotate-ca写入集群数据。

需要说明的前提:这是针对首次启动时自动生成自签 CA的集群的轮换流程。按 ca-cert-rotation ADR 的定义,它属于“disruptive(有中断)”的更新——必须在重启服务前修改节点的 CLI flag、配置文件或环境变量(主要是 token),且配置应用到所有节点的过程中,集群节点可能因暂时不共享同一信任根而出现短暂不可用。

轮换前:确认 CA 证书的到期状态

先运行证书检查命令,确认当前 CA 还剩多久到期:

k3s certificate check

该命令输出每个证书文件的文件名、Subject、用途、过期时间和状态,状态取值为OKWARNINGEXPIREDNOT YET VALID,也可以用-o table-o json-o yaml切换输出格式。对比轮换前后的 CA 到期时间、以及轮换后各证书状态回到OK,是本文验证步骤的核心手段。作为对照,叶子证书(客户端/服务端证书)有效期为 365 天,会在 K3s 启动时若距过期不足 90 天自动续期,不需要手动处理;需要人工介入的只有 CA。

准备条件

  • 在运行 k3s server 的节点上操作。脚本默认数据目录DATA_DIR=/var/lib/rancher/k3s,如果你的 k3s 使用了-data-dir指定其他目录,运行时通过环境变量DATA_DIR覆盖。
  • 节点上需要有带椭圆曲线(ecparam)支持的 openssl。脚本启动时会自检,缺失时报错openssl not found or missing Elliptic Curve (ecparam) support.并退出;如果系统里有openssl-3命令,会优先使用它。
  • 脚本会检查数据目录下 5 个 CA 证书文件是否存在:client-ca.crtserver-ca.crtrequest-header-ca.crtetcd/peer-ca.crtetcd/server-ca.crt(位于${DATA_DIR}/server/tls/)。任何一个缺失都会输出Current <type> CA cert does not exist; cannot continue并退出。
  • 脚本的副作用范围:在${DATA_DIR}/server/rotate-ca下创建新的证书和密钥文件,以及一个脚本退出时自动清理的临时.ca工作目录。它不会修改数据目录中已有的证书,是否生效取决于后续rotate-ca步骤。

把脚本从 k3s 源码树中取出放到 server 节点上(仓库内路径为 contrib/util/rotate-default-ca-certs.sh),例如放到节点上的/tmp,与 e2e 测试中的用法一致。

步骤一:生成新的交叉签名 CA

执行脚本(使用默认数据目录时直接运行即可;数据目录不同则加DATA_DIR):

bash /tmp/rotate-default-ca-certs.sh
# 数据目录不是 /var/lib/rancher/k3s 时: DATA_DIR=/你的k3s数据目录 bash /tmp/rotate-default-ca-certs.sh

脚本对每种 CA 类型执行三步:生成新的自签根 CA(有效期 7300 天)、用当前旧根 CA 对新根做交叉签名、再由新根签发新的叶子 CA。最终生成的 CA bundle 会依次包含:新叶子 CA、新自签根、交叉签名根、旧根。保留旧根意味着已签发的现有证书在原始根 CA 过期之前仍然被信任,这是交叉签名流程的核心目的。

脚本还会生成新的 ServiceAccount 签名密钥:一个新的 RSA 2048 密钥加上旧service.key的内容。服务端写入时会校验新密钥 bundle 中仍包含当前生效的签名密钥,旧 token 的验签不受影响。

脚本正常结束后会打印类似如下内容(文档示例,具体哈希值以你的集群为准):

Cross-signed CA certs and keys now available in /var/lib/rancher/k3s/server/rotate-ca Updated server token: K10<新server-ca哈希>::<原token第二部分> Updated agent token: K10<新server-ca哈希>::<原token第二部分> To update certificates, you may now run: k3s certificate rotate-ca --path=/var/lib/rancher/k3s/server/rotate-ca

这里的更新 token 必须记下来:完整K10格式的 token 中包含 Server CA 文件的 SHA256 哈希,CA 更换后哈希随之变化,旧 token 将不再通过节点加入时的 CA 哈希校验(见 ca-cert-rotation ADR 中 “Server CA Pinning” 一节)。

步骤二:把新 CA 写入集群数据

按脚本提示执行:

k3s certificate rotate-ca --path=/var/lib/rancher/k3s/server/rotate-ca

参数说明:

  • --path为必填项,指向步骤一生成的目录。
  • 命令使用数据目录下的 server token 向 API server 的/v1-k3s/cert/cacerts端点 PUT 新证书,--server默认为https://127.0.0.1:6443
  • 服务端写入前会做一致性校验:新的叶子 CA 必须能用旧 CA 链验证(即共享同一信任根),新的 ServiceAccount 签名密钥 bundle 必须包含当前生效密钥。校验失败时命令报错failed to validate new CA certificates and keys,并提示see server log for details
  • 如果确实需要在一致性检查失败时强行写入,可加--force(用法说明为 “Force certificate replacement, even if consistency checks fail”),仅在明确理解后果时使用。

成功时命令输出certificates saved to datastore,同时 server 日志会记录:certificate: Cluster Certificate Authority data has been updated, k3s must be restarted.——即证书已落库,但节点必须重启才会加载。

步骤三:更新 agent token 并重启节点

  1. 把每个 agent 节点使用的 token(通过配置文件、环境变量或 CLI flag 提供的那份)更新为脚本输出的 “Updated agent token”。这是 disruptive 更新要求的配置变更:必须在重启服务之前完成。
  2. 重启所有 k3s server 节点,再重启 agent 节点。集成测试与 e2e 测试均采用“先停 server、再启动、随后重启其余节点”的顺序(见 cacertrotation 集成测试 和 rotateca e2e 测试)。
  3. 重启窗口内集群可能出现短暂不可用,属于该流程的预期现象,不是故障。

验证轮换结果

  1. 检查 CA 到期时间是否更新。在 server 节点上运行k3s certificate check,确认 CA 证书条目显示新的过期时间、状态为OK

  2. 确认 CA 文件确实被替换。集成测试的做法是轮换前后各取一次哈希并比较:

    md5sum /var/lib/rancher/k3s/server/tls/client-ca.crt md5sum /var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt

    测试断言轮换并重启 server 后,client-ca.crt(CA 被替换)和serving-kube-apiserver.crt(用新 CA 链重新签发)的哈希都与轮换前不同。

  3. 确认集群功能恢复:各节点进入 Ready 状态、kube-system命名空间中的 Pod 全部 running。这是 e2e 测试在重启 server 和 agent 之后的验证方式。

限制与注意

  • 该流程只适用于默认自签 CA 的集群。如果集群启动时使用了外部 CA 签发的用户自定义证书,非中断式更新(只需重启服务、无需改节点配置)即可,仓库另提供了 generate-custom-ca-certs.sh 作为对应工具。
  • 步骤一脚本要求 5 张 CA 证书齐全,任何一张缺失都会直接终止,不会做部分轮换。
  • 新 CA bundle 中包含旧根,现有证书的可信状态延续到旧根过期为止;不要手动编辑server/rotate-ca目录下的文件后再执行rotate-ca,否则可能触发一致性校验失败。
  • 更多背景(hash 钉扎、bootstrap 数据不可重写等问题)可参考 docs/adrs/ca-cert-rotation.md,证书到期检查机制参考 docs/adrs/cert-expiry-checks.md。

【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3s

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询