深色模式
证书过期与 kubeconfig 问题
面向遇到"突然连不上集群 / x509 证书过期 / Unauthorized"的工程师。覆盖证书盘点、续期、kubeconfig 结构与认证排障。
适用版本与前提
- Kubernetes:v1.28+(kubeadm 部署)
- 前提:有 master 节点 SSH 权限与 sudo
- 涉及:
kubeadm certs、kubelet证书轮换、kubeconfig 合并
版本相关
kubeadm 从 v1.15 起支持
kubeadm certs renew(旧命令alpha certs renew已移除)。本文以 v1.28+ 为准。
背景与问题
两类高频事故:
- 证书过期:kubeadm 签发的控制面证书默认有效期 1 年;到期后
kubectl报x509: certificate has expired or is not yet valid。 - kubeconfig 错误:context 指向错误集群/用户、token 失效、或证书被轮换后 kubeconfig 未更新,表现为
Unauthorized或连到错集群。
两者都会造成"集群还在跑,但没人能管"的尴尬局面。
核心概念
| 证书/凭证 | 位置 | 说明 |
|---|---|---|
apiserver | /etc/kubernetes/pki/apiserver.crt | apiserver 服务端证书 |
apiserver-kubelet-client | pki 目录 | apiserver 访问 kubelet |
front-proxy-client | pki 目录 | 聚合层 |
etcd-server/peer/healthcheck-client | /etc/kubernetes/pki/etcd/ | etcd 通信 |
ca | pki/ca.crt | 根 CA,10 年,通常不需要轮换 |
admin.conf | /etc/kubernetes/admin.conf | 管理员 kubeconfig(内含客户端证书) |
| kubelet 证书 | /var/lib/kubelet/pki/ | 默认自动轮换 |
kubeconfig 由三部分组成:
生产实践
1. 盘点证书到期时间
bash
# kubeadm 集群:一键查看(最推荐)
sudo kubeadm certs check-expiration
# 手动查看某个证书
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates -subject1
2
3
4
5
2
3
4
5
输出会明确列出各证书剩余有效期,这是唯一可信的盘点方式。
2. 续期证书
bash
# 续期全部(不含 kubelet 客户端证书与 CA)
sudo kubeadm certs renew all
# 续期单个
sudo kubeadm certs renew apiserver
# 重新生成 admin.conf 等 kubeconfig(续期后必须做)
sudo kubeadm init phase kubeconfig admin --kubeconfig-dir /etc/kubernetes
sudo cp /etc/kubernetes/admin.conf ~/.kube/config1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
续期后必须重启控制面静态 Pod 让新证书生效(kubeadm 不会自动重启):
bash
# 方式一:临时移出 manifest 再移回(触发重建)
sudo mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
# 等待数秒,确认容器已停止
sudo mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/
# 对 kube-controller-manager、kube-scheduler、etcd 同样操作1
2
3
4
5
6
2
3
4
5
6
生产危险
逐个重启控制面组件会造成短暂的控制面不可用窗口。多 master 集群请逐个节点操作、确认前一个恢复后再做下一个;单 master 集群请安排维护窗口。操作前备份
/etc/kubernetes。
bash
# 备份(务必先做)
sudo cp -r /etc/kubernetes /etc/kubernetes.bak.$(date +%F)1
2
2
3. kubelet 证书轮换
kubelet 客户端证书默认自动轮换(RotateCertificates)。若被禁用或长期未重启,可能出现 x509 相关错误:
bash
sudo ls -la /var/lib/kubelet/pki/
sudo journalctl -u kubelet | grep -i cert
sudo systemctl restart kubelet1
2
3
2
3
4. kubeconfig 排障与合并
bash
kubectl config view # 看完整配置
kubectl config current-context # 当前 context
kubectl config get-contexts # 全部 context
kubectl config use-context <name> # 切换
# 校验集群 CA 与服务端证书
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d | openssl x509 -noout -dates1
2
3
4
5
6
7
2
3
4
5
6
7
多集群合并:
bash
export KUBECONFIG=~/.kube/config:~/cluster-b.kubeconfig
kubectl config view --flatten > ~/.kube/merged && mv ~/.kube/merged ~/.kube/config1
2
2
注意
--flatten会把证书数据展开进单一文件,方便分发但也意味着凭证集中在一个文件里,需妥善保管权限(建议chmod 600)。
验证
bash
kubectl get nodes
kubectl get --raw /readyz
sudo kubeadm certs check-expiration # 确认新到期时间1
2
3
2
3
回滚与清理
bash
# 若续期后异常,用备份恢复
sudo rm -rf /etc/kubernetes
sudo cp -r /etc/kubernetes.bak.<date> /etc/kubernetes
# 然后重启控制面组件1
2
3
4
2
3
4
故障排查速查表
| 报错 | 原因 | 处理 |
|---|---|---|
x509: certificate has expired | 控制面/客户端证书过期 | kubeadm certs renew all + 重建 kubeconfig + 重启组件 |
Unauthorized | kubeconfig 用户凭证无效/过期/无权限 | 检查 context 与 user;必要时重签 admin.conf |
Unable to connect to the server | apiserver 地址错误或不可达 | 检查 clusters[*].server、网络、LB |
certificate signed by unknown authority | kubeconfig 里的 CA 与实际签发 CA 不匹配 | 用正确的 ca.crt 重建 kubeconfig |
| 连到了"错的集群" | current-context 指错 | kubectl config get-contexts + use-context |
client certificate is valid for... 名称不匹配 | apiserver SAN 不含访问地址 | 重新签发 apiserver 证书并加 SAN |
bash
# 查看 apiserver 证书 SAN
sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep -A2 'Subject Alternative Name'1
2
2
安全与合规
admin.conf等同cluster-admin,不应分发给普通用户;给人群发应签发受限的、可吊销的凭证。- 证书是长期凭证,一旦泄露需轮换 CA(代价很高)。优先使用短期凭证或 OIDC。
- 建议对证书到期做监控告警(如剩余 < 30 天告警),不要等到故障才处理。
常见坑
- 只续期不重启:证书文件更新了,但进程加载的还是旧的,问题依旧。
- 只续控制面不重建 kubeconfig:
admin.conf里的客户端证书没更新,kubectl 仍失败。 - 忘了 kubelet 证书:控制面好了,但节点仍报证书错误。
- 单 master 集群直接重启:造成控制面中断,应提前规划。
- 没有备份就动
/etc/kubernetes:出问题无法回滚。