干运维这些年,Rancher 证书过期这事儿我前前后后碰到过不少次,每次都是先把浏览器打开看一眼证书错误,然后顺着链路一层层查下去。Rancher 的证书更新之所以总让人头大,是因为它不像普通网站那样换张证书就行,它内部至少有三套证书在同时工作,UI 入口一套、Rancher 自己签发下游集群的 CA 一套、每个下游集群的 kubelet 和 etcd 又是一套,任何一套出了问题,表现症状完全不一样。这篇文章我把 Rancher 证书更新的常见场景、实操步骤和踩坑经验完整整理一遍,主要针对 Rancher v2.6 及以上版本,Helm 部署和 Docker 单容器部署都会覆盖,适合正在维护 Rancher 平台、或者已经被证书问题折磨过的同行参考。
顺便说一句,很多人搜“证书更新”时会把 Rancher 和 esxi 主机证书、vCenter 6.7 证书更新混在一起看,这其实是完全不同的两套体系,vCenter 那套用的是 VMCA 证书结构,Rancher 这边走的是 Kubernetes 的 CSR 和 ingress secret 体系,思路不能通用,我这边只围绕 Rancher 展开。
1. Rancher 证书体系先梳理清楚
1.1 三类主要证书与它们各自的作用
先别急着动手,搞清楚 Rancher 到底有哪些证书在跑,这是所有操作的前提。我从实际维护角度把 Rancher 的证书分成三类。
第一类是 Rancher Server 自己的 HTTPS 证书,也就是你在浏览器里访问https://rancher.example.com时用的那张证书。它由访问入口的 Ingress Controller 加载,Rancher 本身在里面扮演的只是一个后端服务。这张证书可以是 Rancher 安装时自动生成的自签证书,也可以是你自己申请的商业证书或私有 CA 签发的证书。大多数生产环境想换的就是这张,因为它有明确的过期时间,过期后你连管理界面都登不进去,所有业务方都会来催你。
第二类是 Rancher 用来管理下游集群的 CA 证书。Rancher Server 在初始化时会生成一套自己的 CA,用它去签发下游集群 agent 连接时用到的客户端证书。这套 CA 的有效期通常特别长,默认十年,但正因为有效期长,很多人把它给忘了。一旦这套 CA 出问题,所有下游集群的连接都会异常,集群列表里一片红的。
第三类是下游 Kubernetes 集群内部的组件证书,包括 kube-apiserver、etcd、kubelet、controller-manager、scheduler 等组件之间的通信证书,还有你执行kubectl时用的 kubeconfig 里的客户端证书。这类证书的有效期一般是一年或半年,到期后不影响 Rancher 界面本身,但会出现集群状态同步失败、节点 NotReady、执行 kubectl 报 x509 错误等问题。
这三类证书混在一起,症状却完全不同,所以排查的第一步永远是确认“到底是哪一类证书出了问题”,而不是看到一个证书报错就盲目重签。
1.2 为什么“证书更新”不是重新签一个那么简单
刚开始接触 Rancher 的时候我也天真过,以为证书过期就是把新证书传上去、重启一下服务就完事。实际上 Rancher 的证书更新牵扯到一条完整的信任链。
Rancher 在安装的时候,不管是 Helm 还是 Docker 方式,都会把 hostname、证书配置这些参数固化在它的配置里。你更新证书时,不只是替换一个文件,还要保证新证书里的 SAN 包含 hostname,保证私钥格式能被直接加载,保证如果是私有 CA 签发的证书,Rancher 的 agent 在连接时也能信任这个 CA。任何一个环节没对上,就会形成“证书看起来换了,但集群还是报错”的诡异状态。
另外,Rancher 的证书更新有一个很隐蔽的点:如果你用的是 ingress 方式暴露,那么真正终止 TLS 的是 nginx ingress controller,Rancher pod 内部走的反而是 HTTP。这意味着你更新证书后,有时候要等 ingress controller 重新加载才能生效,不是重启一下 Rancher 就万事大吉。
明白了这些,后面每一步操作才有意义。
2. 核心场景:Rancher UI/API 的 HTTPS 证书更新
2.1 先定位证书来源:你是哪种部署方式
处理 HTTPS 证书更新前,先登录到服务器上确认你的 Rancher 是怎么装的,这决定了后面的命令完全不同。
最常见的两种方式是 Helm 方式(Rancher 跑在 Kubernetes 集群里)和 Docker 单容器方式。检查方法很简单:
# Helm 部署方式:能看到 cattle-system 命名空间下的工作负载 kubectl -n cattle-system get svc rancher kubectl -n cattle-system get pods # Docker 部署方式:宿主机上能看到 ranche 容器 docker ps | grep rancher/rancher如果你能看到命名空间和 pod,那就是 Helm 或者 kubectl 方式装的;如果只看到 docker 容器,那就是单容器部署。还有一种更老的方式是 Rancher 跑在 RKE 集群里,但老版本大多已经升级到 Helm 模式了,这里不做展开。
判断出部署方式之后,再看当前的证书来源。Helm 方式下,证书信息都对应在cattle-system命名空间的 secret 中,tls-rancher-ingress这个 secret 就是入口证书,相关内容我在 2.2 小节展开。Docker 方式下,证书直接以文件形式挂载在容器里,路径通常是/etc/rancher/ssl/下的.pem和.key文件。
这一步骤的核心价值在于:别对着错误的路径去操作,否则你会觉得明明改了文件,Rancher 却一点反应都没有。
2.2 Helm 部署下更新自定义证书的完整流程
Helm 模式下,Rancher 的 HTTPS 证书最终由 nginx ingress controller 加载,证书内容存放在tls-rancher-ingress这个 secret 里。更新证书的正确流程是先更新 secret,再让 Rancher 重新加载配置,最后验证生效。
先看看当前证书的过期时间,确认问题:
kubectl -n cattle-system get secret tls-rancher-ingress -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates -subject -issuer看到输出里的notAfter日期之后,准备新的证书文件。我这里建议把你的证书文件整理成三个:fullchain.pem(包含域名证书和中间证书的完整链)、privkey.pem(私钥),以及可选但强烈建议的ca.pem(根 CA 证书,如果用的是私有 CA 签发)。
然后更新 secret,我这里用--dry-run=client -o yaml | kubectl apply -f -的方式,避免直接删除 secret 造成短暂的服务中断:
kubectl -n cattle-system create secret tls tls-rancher-ingress \ --cert=fullchain.pem \ --key=privkey.pem \ --dry-run=client -o yaml | kubectl apply -f -如果证书是由私有 CA 签发的,还需要同步更新 CA 配置,Rancher 管这个 secret 叫做tls-ca,里面的 key 名必须是cacerts.pem:
kubectl -n cattle-system create secret generic tls-ca \ --from-file=cacerts.pem=ca.pem \ --dry-run=client -o yaml | kubectl apply -f -接下来重新应用 Helm 配置。很多人到这里会漏掉一个关键步骤:直接看当前 Rancher 的 Helm values,确保升级时不会把原有的 hostname、复制数、日志级别这些参数冲掉。先执行:
helm -n cattle-system get values rancher把这个输出保存下来,然后在 helm upgrade 的时候把关键参数补全。一个典型命令如下:
helm upgrade rancher rancher-latest/rancher -n cattle-system \ --set hostname=rancher.example.com \ --set ingress.tls.source=secret \ --set ingress.tls.secretName=tls-rancher-ingress \ --set privateCA=true \ --set tlsCaSecretName=tls-ca \ --set replicas=3如果证书是从公开 CA(比如 Let's Encrypt)申请的,就不需要设置privateCA和tlsCaSecretName这两个参数。等 helm upgrade 完成,再重启 Rancher 的 deployment,让进程重新读取证书配置:
kubectl -n cattle-system rollout restart deploy/rancher kubectl -n cattle-system rollout status deploy/rancher这里有个细节很多人不知道:因为证书最终由 nginx ingress controller 加载,Rancher pod 重启后,有时候你打开浏览器还是会看到旧证书,这时候别急,等 nginx controller 重新同步 secret 即可,一般秒级到几十秒不等。你可以看一下 ingress-nginx 所在命名空间的 controller pod 日志,出现updating secret之类的字样说明已经在加载了。
2.3 Docker 单容器部署下的证书替换
Docker 单容器部署的 Rancher 虽然安装方式老,但存量用户并不少,很多小环境还在用它跑。单容器模式下,Rancher 对外服务的证书不是放在 secret 里,而是以挂载卷的形式直接映射到容器内,默认路径是/etc/rancher/ssl/下的.pem和.key文件,文件命名一般跟随 hostname,比如rancher.example.com.pem和rancher.example.com.key。
更换证书的思路是保留数据卷、扔掉容器、换新证书后重新创建容器。先把原容器停掉并改名备份,防止操作失败时连回退的机会都没有:
docker stop rancher docker rename rancher rancher-bak-$(date +%Y%m%d)然后把新证书放到宿主机目录,例如/data/rancher-ssl/,再重新创建容器。这里要注意映射路径必须保持/etc/rancher/ssl/下文件名包含 hostname,Rancher 在启动时是通过 hostname 来找对应证书文件的:
docker run -d --restart=unless-stopped \ --name rancher \ -p 80:80 -p 443:443 \ -v /data/rancher:/var/lib/rancher \ -v /data/rancher-ssl/rancher.example.com.pem:/etc/rancher/ssl/rancher.example.com.pem \ -v /data/rancher-ssl/rancher.example.com.key:/etc/rancher/ssl/rancher.example.com.key \ -v /data/rancher-ssl/ca.pem:/etc/rancher/ssl/cacerts.pem \ rancher/rancher:v2.7.9如果是公开 CA 签发的证书,不需要挂载cacerts.pem。启动后等一两分钟,打开浏览器访问 hostname,确认证书更新成功。如果确认没问题,就可以删掉之前的备份容器;如果新证书有问题,直接改回原命名启动备份容器即可,数据卷没动过,回退很干净。
Docker 模式更新证书的核心经验是:数据卷/var/lib/rancher绝对不能动,一定要原样挂载到新容器上。我之前见过有人图省事,直接把整个 Rancher 目录复制到新机器,结果权限和路径状态不对,Rancher 起来后一堆集群失联,处理起来比证书过期本身还麻烦。
2.4 证书更新后的生效验证
证书换完了,别急着宣布完成,我习惯做三步验证。
第一步,用 openssl 直接验证服务端口上的证书信息,确认线上已经变成新证书:
echo | openssl s_client -connect rancher.example.com:443 -servername rancher.example.com 2>/dev/null | openssl x509 -noout -dates -subject -issuer第二步,打开浏览器访问页面,确认地址栏证书状态正常,F12 看一下页面里的 API 请求没有证书相关的报错。这一步能发现一些 openssl 验证发现不了的问题,比如页面二次加载时内部调用仍然走了旧的 CA。
第三步,检查 Rancher 的 local 集群状态,执行kubectl get nodes,确保 Rancher 管理面本身没有因为证书更换而出现 agent 连接异常。
如果这三步都正常,证书更新才算真正完成。如果第一步能看到新证书,但页面还是报错,十有八九是浏览器缓存了旧的证书连接,换个无痕窗口再试一般能定位出来。
3. Rancher 内部自签 CA 证书的处理
3.1 默认自签证书的有效期与检查
很多生产环境图省事,安装 Rancher 时没配自定义证书,直接用 Rancher 默认生成的自签证书。这个自签证书不是随随便便一签就完事的,Rancher 会生成一套自己的 CA,并用这套 CA 去签发 HTTPS 证书。这套自签 CA 的有效期一般十年起步,很多团队从部署到交接都没人注意过它,等发现问题的时候,往往已经是“页面完全打不开”的状态。
检查自签证书有没有快到期,方法和查自定义证书一样,重点看 secrettls-rancher-ingress里的证书信息:
kubectl -n cattle-system get secret tls-rancher-ingress -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -dates -subject -issuer看输出里的notAfter,如果距离当前时间不足三个月,我建议直接安排更新窗口。自签证书的更新窗口选在业务低峰期就好,处理过程本身不复杂,但不要在业务高峰去抢这个风险。
还有一点容易忽略:Rancher 自签证书对系统时间非常敏感。如果服务器时间漂移了,哪怕证书实际上还有效,浏览器也会报“证书尚未生效”或“证书已过期”,这时候不要急着重签证书,先把系统时间和 NTP 同步修好再说,具体我在 3.3 小节展开。
3.2 自签 CA 证书到期后的重建方案
自签证书如果确认已经到期,最直接的处理办法是让 Rancher 重新生成一套。前提是你确认 ingress 的 tls 来源是rancher(默认自签),而不是secret或letsEncrypt,这个可以从安装时的 Helm values 看出来:
helm -n cattle-system get values rancher | grep -A5 ingress如果tls.source是secret,说明走的是自定义证书,那就参考第 2 章的流程;如果是rancher,就可以用下面的方式重建。
Helm 部署模式下,入口证书 secret 是 Rancher 在安装或启动时自动创建的。你可以把现有的tls-rancher-ingresssecret 删除,然后重启 Rancher,它会在启动时重新生成一套自签证书:
kubectl -n cattle-system delete secret tls-rancher-ingress kubectl -n cattle-system rollout restart deploy/rancherRancher 进程起来后,会自动创建新的 self-signed 证书 secret,有效期从当前时间重新计算。整个过程会短时间造成 UI 不可访问,所以要在维护窗口做。
Docker 单容器部署模式下,自签证书是 Rancher 容器启动时按 hostname 生成的。重建方法是保留数据卷、删掉旧证书文件、删除容器重新运行。运行命令和 2.3 小节类似,区别在于不要挂载任何自定义证书文件,让 Rancher 完全走默认自签逻辑。容器一旦启动,检测到/etc/rancher/ssl下没有对应 hostname 的证书,就会自动生成新的自签证书。
这里必须提醒一件事:删除证书 secret 或证书文件后,Rancher 底层所有关联的 agent 连接都会被重置。下游集群的 agent 会拿着旧 CA 签发的客户端证书来找 Rancher,证书校验失败后会自动重试,通常几分钟内能恢复。但如果你的下游集群数量比较多,恢复时间会拉长,别慌张,耐心等 agent 重连即可。
3.3 系统时间异常触发的“证书未生效”处理
这应该是 Rancher 证书问题里最坑的一类。有次客户报障说 Rancher 页面打不开,浏览器提示证书过期,我远程上去一看,证书的notBefore是三个月后,也就是说证书是未来的,还没生效。再一查服务器时间,系统时间整整快了半年。
时间漂移会让自签证书的校验彻底乱套:Rancher 内部组件之间的证书校验依赖时间窗口,任何一方的时间偏差都会导致 x509 校验失败。这种情况下的正确姿势是先把系统时间校准。
先用 NTP 同步时间,不同发行版命令不同,我这里以常见的 systemd-timesyncd 和 chrony 为例:
# 使用 chrony 的 sudo chronyc makestep # 使用 systemd-timesyncd 或直接 ntpdate sudo timedatectl set-ntp true sudo ntpdate -u ntp.aliyun.com时间恢复正常后,Rancher 的自签证书如果之前生成时处于错误时间窗口,证书本身的notBefore和notAfter可能都是错的,这时候需要按照 3.2 小节的方案删掉 secret 让 Rancher 重新生成。
排查这种问题有个快捷方法:用 openssl 查看证书的validity,再和系统当前时间对比,如果notBefore在未来,就是时间串了。不要先动证书,先调时间,顺序反过来很容易白忙一场。
4. 下游 K8s 集群的证书更新与恢复
4.1 在 Rancher UI 中轮换下游集群组件证书
Rancher 管理的下游集群,Kubernetes 组件之间的证书一样有有效期。kubelet 的证书一般一年一轮,etcd、kube-apiserver 这些证书有效期也不长。这些证书一旦到期,最常见的表现是集群状态变成Unavailable,节点状态异常,或者 Rancher 页面里看不到节点信息。
Rancher 对下游集群提供了证书轮换功能,不过入口藏得比较深,UI 上在集群的编辑配置里,不同 Rancher 版本叫法不太一样,比较新的版本在集群的“高级选项”或者单独的证书管理入口里能找到一个 “Rotate Certificates” 的按钮。点击时可以选择轮换范围:只轮换kubelet、etcd、controller-manager、scheduler,或者全部一起轮换。
轮换kubelet证书是最安全的,基本不影响业务。轮换etcd证书会触发 etcd 节点重启,短时间内会有写入抖动,一定要错开业务高峰。轮换all更是会把 apiserver 也跟着重启,整个集群的 API 会短暂不可用,执行前务必确认这个窗口期可以接受。
如果你不方便进 UI,也可以直接用 Rancher 的 API 触发轮换。用https://<rancher-server>/v3/clusters/<cluster-id>?action=rotateCertificates接口,请求体里带上要轮换的组件类型。我一般只建议 RKE 类型的托管集群走 API,导入的集群在 API 里对证书轮换的兼容性参差不齐,出了问题难排查,不如 UI 稳。
4.2 集群失联后的应急恢复顺序
证书更新过程中最容易出现的大事故是:证书动了,所有下游集群全失联了。这时候不要慌,按顺序处理。
首先确认 Rancher Server 本身是否正常,能打开 UI、能看到 local 集群,说明 Rancher 管理面是好的,问题出在下游连接链路。接着去 Rancher 所在集群执行下面的命令,看 agent 的运行状态:
kubectl -n cattle-system get pods -o wide找到cattle-cluster-agent或cattle-agent相关的 pod,看日志里有没有x509、certificate expired、CSR这些关键词:
kubectl -n cattle-system logs -f <agent-pod>如果确认是证书过期,需要在下游集群的 kube-system 相关命名空间里查看有没有 pending 状态的 CertificateSigningRequest。新证书申请通常以 CSR 的形式提交给 apiserver,由 Rancher 侧自动审批,但有时审批流程卡住,需要手动处理:
kubectl get csr | grep Pending kubectl certificate approve <csr-name>审批通过后,重启下游集群的 agent pod,让它重新建立连接。RKE 自建集群一般通过 Rancher UI 重新生成 kubeconfig 并覆盖 agent 配置。整个恢复过程可能需要五分钟到半小时,取决于集群规模和网络状况。
这里再强调一个恢复时的关键点:如果 Rancher 是在 Kubernetes 里跑的,并且 local 集群本身就是 Rancher 用 RKE2 或 k3s 搭的,那么在 local 集群失联时你还可以直接 SSH 到控制面节点上,用节点本地的 admin kubeconfig 来操作集群,路径一般在/etc/rancher/rke2/rke2.yaml或/etc/rancher/k3s/k3s.yaml。这个 kubeconfig 是节点本地生成的,不受 Rancher 证书影响,用来救急非常有效,我从几次真实事故里总结出来的经验,关键时刻能救命。
5. 常见问题与排查技巧实录
5.1 高频故障速查表
下面把我在实际运维中遇到过的证书相关问题整理成一张速查表,每一条都是真实踩过的坑,可以直接对照症状找解决办法。
| 现象 | 可能原因 | 处理办法 |
|---|---|---|
| 浏览器显示“证书过期”或“不安全” | Rancher 入口 HTTPS 证书过期 | 按第 2 章或第 3 章流程更新证书 |
| 浏览器提示“证书尚未生效” | 服务器系统时间漂移 | 先校准 NTP 时间,再重建自签证书 |
| Rancher 页面能开,但集群列表一片红 | 下游集群 agent 连接证书过期 | 查看 agent 日志,重启 agent,手动 approve CSR |
| 执行 kubectl 报 x509 certificate signed by unknown authority | 本地 kubeconfig 里的 CA 证书和集群 CA 不匹配 | 从 Rancher UI 重新下载 kubeconfig,替换本地文件 |
| 节点状态 NotReady | kubelet 证书过期 | 在 Rancher UI 轮换 kubelet 证书,重启对应节点 kubelet |
| 更新证书后页面仍显示旧证书 | ingress controller 未重新加载 secret | 等待几十秒,或重启 nginx ingress controller pod |
| 更新证书后集群 agent 反复重启 | 私有 CA 证书未同步到 Rancher | 确认tls-casecret 里的cacerts.pem是最新的,重新 helm upgrade |
| Rancher UI 能进,但 API 返回 401 | Rancher 内部 API 证书过期 | 重启 Rancher deployment,必要时重建 tls-rancher-ingress secret |
这张表看起来简单,但每一条背后都对应一个具体的操作链路,处理时建议把对应的章节步骤完整读完再动手,避免头疼医头。
5.2 我踩过的坑和习惯做法
最后分享几个我个人长期养成的习惯,不一定每条都适合所有环境,但能帮你省掉不少麻烦。
第一,给证书过期时间做监控,不要等业务方来催。最简单的办法就是在定时任务里跑一行 openssl 命令,检查 Rancher 入口证书和集群 agent 证书的剩余有效期,剩余不足 30 天时发告警。不需要上多复杂的监控系统,cron 加 shell 脚本就够用。
第二,更新证书前务必留好备份。Helm 部署先记录当前 helm values,出问题可以按原参数回滚;Docker 部署先改容器名或复制数据卷,确保能随时回退。我见过太多人图快直接删除重建,结果新证书有问题,旧的又找不回来,只能临时申请新证书,整个窗口期被拉长好几倍。
第三,证书更新不是一台机器的操作,是一次全链路检查。Rancher 入口证书、Rancher 内部 CA、下游集群的 kubelet 证书、kubeconfig 客户端证书,每一层都要确认一遍,因为任何一个环节的残留问题都会在下次业务流量高峰时突然爆发。我习惯每次更新完证书后,把第 2.4 小节的验证步骤完完整整走一遍,连 kubeconfig 都重新下载替换,不给自己留隐患。
Rancher 证书更新这件事,说难确实难在三套证书体系交织,说简单也确实简单,本质上就是“确认来源、备份、替换、验证”四个步骤,只是每套证书每一步的入口不一样。把本文的流程走一遍,下次再遇到证书问题,你应该不会再对着浏览器上的红色警告发愁了。