使用 kubeadm 进行证书管理
本文以 kubeadm 管理的 Kubernetes 集群为例,说明控制平面证书、kubelet 客户端证书的检查、正常更新、证书过期后的恢复,以及更新后的验证方法。
重要:控制平面证书和 kubelet 证书是两套不同的机制。
kubeadm certs renew all主要负责 kubeadm 管理的控制平面/客户端证书。- kubelet 客户端证书位于
/var/lib/kubelet/pki/,正常情况下应该依靠 kubelet certificate rotation 自动轮转。- kubelet 证书过期时,不能只执行
kubeadm certs renew all,需要单独恢复 kubelet 的认证。
k8s集群证书过期
官方文档:
https://kubernetes.io/zh-cn/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/
如果 Kubernetes 集群证书过期,常见表现是访问 API Server 失败,例如:
k get no
Unable to connect to the server: tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2025-06-23T07:20:14Z is after 2025-01-02T02:18:40Z
证书问题不一定只表现为 kubectl 无法访问,也可能表现为:
kube-controller-manager、kube-scheduler等控制平面组件持续出现Unauthorized- kubelet 无法正常向 API Server 认证
- Node 状态异常、NotReady
- kubelet 日志中出现
system:anonymous - Calico 等依赖 kubelet/API Server 的组件出现认证相关错误
- CSR 长时间处于
Pending - static Pod 因证书问题无法正常启动或反复重启
因此遇到证书过期问题时,不要只更新一个证书然后立即认为故障已经恢复,应该按照本文最后的检查项逐项确认。
查看证书过期时间
查看控制平面组件证书过期时间
可以使用 kubeadm 查看 kubeadm 管理的证书:
kubeadm certs check-expiration
kubeadm certs check-expiration 会检查 /etc/kubernetes/pki 下的证书,以及 admin.conf、controller-manager.conf、scheduler.conf 中嵌入的客户端证书。
示例:
CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Jan 02, 2025 <invalid> ca no
apiserver Jan 02, 2025 <invalid> ca no
apiserver-etcd-client Jan 02, 2025 <invalid> etcd-ca no
apiserver-kubelet-client Jan 02, 2025 <invalid> ca no
controller-manager.conf Jan 02, 2025 <invalid> ca no
etcd-healthcheck-client Jan 02, 2025 <invalid> etcd-ca no
etcd-peer Jan 02, 2025 <invalid> etcd-ca no
etcd-server Jan 02, 2025 <invalid> etcd-ca no
front-proxy-client Jan 02, 2025 <invalid> front-proxy-ca no
scheduler.conf Jan 02, 2025 <invalid> ca no
CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME
ca Dec 31, 2033 8y
etcd-ca Dec 31, 2033 8y
front-proxy-ca Dec 31, 2033 8y
如果看到 <invalid>,说明对应证书已经过期。
kubelet.conf 不会出现在 kubeadm certs check-expiration 的控制平面证书列表中。
kubelet 默认启用了客户端证书自动轮转,相关证书通常位于:
/var/lib/kubelet/pki/
官方文档:
https://kubernetes.io/zh-cn/docs/tasks/tls/certificate-rotation/
kubeadm 排障文档:
因此,不要因为 kubeadm certs check-expiration 显示控制平面证书正常,就认为 kubelet 证书也一定正常。
查看kubelet证书过期时间
查看 kubelet 当前使用的客户端证书:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
例如:
subject=O = system:nodes, CN = system:node:k8s-node01
issuer=CN = kubernetes
notBefore=Aug 15 02:18:40 2025 GMT
notAfter=Aug 15 02:18:40 2026 GMT
serial=3926CE667E904BFE3239CDB014E108C4
重点关注:
notAfter
如果已经超过当前时间,则 kubelet 客户端证书已经过期。
也可以查看目录:
ls -lah /var/lib/kubelet/pki/
正常情况下可以看到类似:
kubelet-client-2026-09-27-xxxxxx.pem
kubelet-client-current.pem -> kubelet-client-2026-09-27-xxxxxx.pem
kubelet.crt
kubelet.key
kubelet-client-current.pem 是 kubelet 当前使用的客户端证书,通常是一个软链接。
不要只看文件名判断证书是否有效,最终应使用 openssl x509 -dates 检查证书实际有效期。
正常情况下 kubelet 证书应该如何工作
kubeadm 集群通常通过 kubelet certificate rotation 自动轮转客户端证书。
可以检查 kubelet 配置:
grep -nE 'rotateCertificates|serverTLSBootstrap' /var/lib/kubelet/config.yaml
通常应该至少看到:
rotateCertificates: true
如果配置为:
rotateCertificates: true
表示 kubelet 客户端证书应该进行自动轮转。
正常流程大致为:
kubelet
│
│ 证书接近过期
▼
生成新的 CSR
│
▼
CSR 被批准
│
▼
生成新的 kubelet-client-*.pem
│
▼
更新 kubelet-client-current.pem
│
▼
继续使用新证书
因此,正常情况下不应该每年手工给 Node 更新 kubelet 证书。
如果 kubelet 证书已经过期,应该重点排查:
kubectl get csr
以及 kubelet 日志:
journalctl -u kubelet --since "1 hour ago" --no-pager
手动更新证书
执行证书更新之前,建议先备份 /etc/kubernetes,尤其是:
/etc/kubernetes/pki/
/etc/kubernetes/admin.conf
/etc/kubernetes/controller-manager.conf
/etc/kubernetes/scheduler.conf
/etc/kubernetes/kubelet.conf
例如:
BACKUP_DIR="/root/kubernetes-certs-backup-$(date +%Y%m%d-%H%M%S)" && \
mkdir -p "$BACKUP_DIR" && \
cp -a /etc/kubernetes/pki "$BACKUP_DIR/" && \
cp -a /etc/kubernetes/*.conf "$BACKUP_DIR/" 2>/dev/null && \
echo "备份完成: $BACKUP_DIR"
不要在没有确认 CA 文件和 CA 私钥存在的情况下直接执行破坏性操作。
更新kubelet证书
一、先确认 kubelet 证书是否真的过期
在 Node 上执行:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
确认 notAfter 已经过期。
同时查看:
journalctl -u kubelet --since "1 hour ago" --no-pager
以及:
kubectl get csr
二、确认控制平面节点存在 CA 私钥
生成新的 kubelet kubeconfig 需要 Kubernetes CA 私钥,因此应该在正常工作的 Control Plane 节点执行。
确认:
ls -lah /etc/kubernetes/pki/ca.crt
ls -lah /etc/kubernetes/pki/ca.key
必须确认:
/etc/kubernetes/pki/ca.crt
/etc/kubernetes/pki/ca.key
都存在。
不要把:
/etc/kubernetes/pki/ca.key
复制到 Node。
CA 私钥属于整个 Kubernetes 集群的核心私钥,应该只保存在受控的 Control Plane 节点。
三、备份 Node 上原有 kubelet 配置和证书
在发生故障的 Node 上执行:
BACKUP_DIR="/root/kubelet-backup-$(date +%Y%m%d-%H%M%S)" && \
mkdir -p "$BACKUP_DIR" && \
cp -a /etc/kubernetes/kubelet.conf "$BACKUP_DIR/" 2>/dev/null && \
cp -a /var/lib/kubelet/pki/kubelet-client* "$BACKUP_DIR/" 2>/dev/null && \
echo "备份完成: $BACKUP_DIR" && \
ls -lah "$BACKUP_DIR"
四、删除失效的 kubelet 客户端证书
只删除 kubelet 客户端证书:
rm -f /var/lib/kubelet/pki/kubelet-client*
同时删除旧的 kubelet kubeconfig:
rm -f /etc/kubernetes/kubelet.conf
不要删除:
/var/lib/kubelet/pki/kubelet.crt
/var/lib/kubelet/pki/kubelet.key
这两个文件和 kubelet 客户端证书轮转不是一回事。
也不要执行:
rm -rf /var/lib/kubelet/pki
除非已经明确知道自己正在处理什么,并且有完整备份。
五、在 Control Plane 生成新的 kubelet.conf
假设故障 Node 为:
k8s-node01
在 Control Plane 执行:
NODE=k8s-node01
然后:
kubeadm kubeconfig user \
--org system:nodes \
--client-name system:node:$NODE \
> /root/${NODE}-kubelet.conf
检查:
ls -lah /root/${NODE}-kubelet.conf
确认证书:
openssl x509 \
-in <(kubectl config view --raw --kubeconfig /root/${NODE}-kubelet.conf -o jsonpath='{.users[0].user.client-certificate-data}' | base64 -d) \
-noout \
-subject \
-issuer \
-dates \
-serial
应该看到类似:
subject=O = system:nodes, CN = system:node:k8s-node01
issuer=CN = kubernetes
notBefore=Sep 27 00:00:00 2026 GMT
notAfter=Sep 27 00:00:00 2027 GMT
$NODE 必须是发生故障的 Node 名称。
例如:
NODE=k8s-node01
不能误写成 Control Plane:
NODE=k8s-master01
否则生成的客户端身份会错误。
六、将新的 kubelet.conf 复制到 Node
在 Control Plane 执行:
scp /root/${NODE}-kubelet.conf root@${NODE}:/etc/kubernetes/kubelet.conf
然后在 Node 上:
chmod 600 /etc/kubernetes/kubelet.conf
检查:
ls -lah /etc/kubernetes/kubelet.conf
七、重启 kubelet
在 Node 上执行:
systemctl restart kubelet
检查:
systemctl status kubelet --no-pager
查看最近日志:
journalctl -u kubelet --since "10 minutes ago" --no-pager
八、确认新的 kubelet 客户端证书已经生成
等待 kubelet 完成认证后:
ls -lah /var/lib/kubelet/pki/
重点查看:
ls -lah /var/lib/kubelet/pki/kubelet-client-current.pem
然后:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
确认:
subject=O = system:nodes, CN = system:node:k8s-node01
并确认:
notAfter
已经变成未来时间。
不要简单认为:
systemctl restart kubelet
执行成功就代表证书已经恢复。
必须检查 /var/lib/kubelet/pki/kubelet-client-current.pem 是否存在,并确认其 notAfter 已经更新。
九、确认 kubelet.conf 使用的是正确的认证方式
检查:
grep -nE 'client-certificate|client-key|client-certificate-data|client-key-data' /etc/kubernetes/kubelet.conf
如果使用动态轮转证书,应该确认 kubelet 最终使用的是:
/var/lib/kubelet/pki/kubelet-client-current.pem
而不是永久嵌入旧证书的:
client-certificate-data
client-key-data
必要时可以编辑:
vi /etc/kubernetes/kubelet.conf
将对应用户配置调整为:
users:
- name: system:kubelet
user:
client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
client-key: /var/lib/kubelet/pki/kubelet-client-current.pem
保存后:
systemctl restart kubelet
然后再次检查:
journalctl -u kubelet --since "10 minutes ago" --no-pager
这一步非常重要。
恢复 kubelet 时不能只关注“生成了一个新的 kubelet.conf”,还需要确认 kubelet 后续能够使用 /var/lib/kubelet/pki/kubelet-client-current.pem 进行正常的证书轮转。
kubelet证书自动轮转失败排查
如果:
rotateCertificates: true
但是证书仍然过期,重点检查下面几项。
查看 kubelet 配置
grep -nE 'rotateCertificates|serverTLSBootstrap' /var/lib/kubelet/config.yaml
查看 CSR
kubectl get csr
如果出现:
NAME AGE SIGNERNAME REQUESTOR CONDITION
csr-xxxxx 10m kubernetes.io/kube-apiserver-client-kubelet system:node:k8s-node01 Pending
说明 kubelet 已经发起 CSR,但没有完成批准。
检查具体 CSR
不要直接批准所有 Pending CSR。
先:
kubectl describe csr <CSR_NAME>
重点确认:
Requesting User
SignerName
Subject
Conditions
确认 CSR 确实来自目标 Node,并且:
CN=system:node:<node-name>
O=system:nodes
确认无误后:
kubectl certificate approve <CSR_NAME>
然后:
kubectl get csr
再次检查:
kubectl describe csr <CSR_NAME>
不建议直接批量批准所有 Pending CSR
不要在生产环境直接执行:
kubectl get csr | grep Pending | awk '{print $1}' | xargs kubectl certificate approve
因为 Pending CSR 不一定全部来自你正在恢复的 kubelet。
正确做法是:
kubectl get csr
找到目标 CSR:
kubectl describe csr <CSR_NAME>
确认身份后:
kubectl certificate approve <CSR_NAME>
更新控制平面组件证书
如果:
kubeadm certs check-expiration
发现控制平面证书已经过期,可以执行:
kubeadm certs renew all
示例输出:
certificate embedded in kubeconfig file admin.conf renewed
certificate embedded in kubeconfig file controller-manager.conf renewed
certificate embedded in kubeconfig file scheduler.conf renewed
执行完成后重新检查:
kubeadm certs check-expiration
确认相关证书的:
EXPIRES
RESIDUAL TIME
已经恢复。
kubeadm certs renew all 不会替代 kubelet 客户端证书自动轮转。
因此即使:
kubeadm certs check-expiration
全部正常,也应该单独检查:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates
更新 admin.conf
证书更新后,如果当前用户使用的是旧的 admin.conf,可以更新:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
然后:
kubectl get nodes
确认可以正常访问集群。
重启控制平面组件
kubeadm 部署的控制平面组件通常是 static Pod。
manifest 通常位于:
/etc/kubernetes/manifests/
例如:
ls -lah /etc/kubernetes/manifests/
通常可以看到:
etcd.yaml
kube-apiserver.yaml
kube-controller-manager.yaml
kube-scheduler.yaml
不要一次性移动或删除 /etc/kubernetes/manifests/ 下的全部文件。
例如不建议直接执行:
mv /etc/kubernetes/manifests/* /tmp/k8s-manifests/
因为这样可能同时停止:
- etcd
- kube-apiserver
- kube-controller-manager
- kube-scheduler
如果是单 Control Plane 集群,可能直接导致整个控制平面不可用。
应该一个组件一个组件处理。
重启 kube-controller-manager
例如:
mkdir -p /tmp/k8s-manifests
mv /etc/kubernetes/manifests/kube-controller-manager.yaml \
/tmp/k8s-manifests/
sleep 20
mv /tmp/k8s-manifests/kube-controller-manager.yaml \
/etc/kubernetes/manifests/
然后检查:
crictl ps -a | grep kube-controller-manager
以及:
kubectl get pods -n kube-system -o wide | grep kube-controller-manager
重启 kube-scheduler
mkdir -p /tmp/k8s-manifests
mv /etc/kubernetes/manifests/kube-scheduler.yaml \
/tmp/k8s-manifests/
sleep 20
mv /tmp/k8s-manifests/kube-scheduler.yaml \
/etc/kubernetes/manifests/
检查:
crictl ps -a | grep kube-scheduler
重启 kube-apiserver
mkdir -p /tmp/k8s-manifests
mv /etc/kubernetes/manifests/kube-apiserver.yaml \
/tmp/k8s-manifests/
sleep 20
mv /tmp/k8s-manifests/kube-apiserver.yaml \
/etc/kubernetes/manifests/
然后:
kubectl get --raw='/readyz?verbose'
重启 etcd
如果更新了 etcd 相关证书:
mkdir -p /tmp/k8s-manifests
mv /etc/kubernetes/manifests/etcd.yaml \
/tmp/k8s-manifests/
sleep 20
mv /tmp/k8s-manifests/etcd.yaml \
/etc/kubernetes/manifests/
检查:
crictl ps -a | grep etcd
如果是多 Control Plane 集群,重启控制平面组件时应该结合高可用拓扑进行操作,避免同时影响多个 Control Plane。
如果是单 Control Plane 集群,更应该严格遵守“一个组件一个组件重启”的原则。
static Pod 没有因为删除 Mirror Pod 而真正重启
在实际排障中可能遇到:
kubectl delete pod kube-controller-manager-xxx -n kube-system
执行成功,但是控制平面组件实际运行的 container 并没有按照预期重新创建。
这是因为:
kubectl delete pod
↓
删除 API Server 中的 Mirror Pod 对象
↓
并不等价于直接停止节点上的 static Pod container
static Pod 的真正运行状态由 kubelet 和容器运行时负责。
因此需要结合:
crictl ps -a
检查真实 container。
例如:
crictl ps -a | grep kube-controller-manager
如果确认旧 container 仍然存在,可以结合具体运行时状态进行处理。
在实际故障恢复中,如果确认需要停止旧的 static Pod container,可以使用:
crictl stop <CONTAINER_ID>
然后观察 kubelet 是否重新创建:
crictl ps -a | grep kube-controller-manager
处理 static Pod 时,建议优先使用“修改/移出 manifest → kubelet 检测到 manifest 变化 → 重新创建 Pod”的方式。
crictl stop 更适合作为故障排查和已经明确需要强制停止旧 container 时的辅助手段。
控制平面证书更新后出现 Unauthorized
例如:
Unauthorized
或者 kube-controller-manager 日志中出现:
x509: certificate has expired or is not yet valid
首先确认对应证书:
kubeadm certs check-expiration
然后确认实际配置文件:
ls -lah /etc/kubernetes/controller-manager.conf
ls -lah /etc/kubernetes/scheduler.conf
ls -lah /etc/kubernetes/admin.conf
如果已经执行:
kubeadm certs renew all
需要确保对应 static Pod 已经真正重新加载新的 kubeconfig。
可以检查:
crictl ps -a | grep kube-controller-manager
并查看:
kubectl logs -n kube-system <controller-manager-pod> --tail=100
如果 Mirror Pod 日志获取不到,可以使用容器运行时:
crictl ps -a | grep kube-controller-manager
然后:
crictl logs <CONTAINER_ID>
证书过期后的完整恢复流程
如果遇到类似:
控制平面证书过期
+
kubelet 客户端证书过期
+
Node NotReady
+
CSR Pending
建议按照下面顺序处理。
第一步:确认集群状态
kubectl get nodes -o wide
kubectl get pods -A
kubectl get csr
第二步:检查控制平面证书
kubeadm certs check-expiration
第三步:检查 kubelet 证书
在每个异常 Node:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
第四步:先恢复异常 Node 的 kubelet 认证
在正常 Control Plane:
NODE=k8s-node01
kubeadm kubeconfig user \
--org system:nodes \
--client-name system:node:$NODE \
> /root/${NODE}-kubelet.conf
复制:
scp /root/${NODE}-kubelet.conf root@${NODE}:/etc/kubernetes/kubelet.conf
Node 上:
chmod 600 /etc/kubernetes/kubelet.conf
systemctl restart kubelet
然后检查:
systemctl status kubelet --no-pager
journalctl -u kubelet --since "10 minutes ago" --no-pager
第五步:确认 kubelet 新证书
ls -lah /var/lib/kubelet/pki/
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
第六步:处理 CSR
kubectl get csr
对于确认属于目标 Node 的 Pending CSR:
kubectl describe csr <CSR_NAME>
确认无误后:
kubectl certificate approve <CSR_NAME>
第七步:恢复控制平面证书
kubeadm certs renew all
然后:
kubeadm certs check-expiration
第八步:逐个重启 static Pod
不要一次性移动全部 manifest。
按照实际需要:
etcd
kube-apiserver
kube-controller-manager
kube-scheduler
一个一个处理,并在每一步确认组件恢复正常。
第九步:最终验证
kubectl get nodes -o wide
kubectl get pods -A
kubectl get pods -n kube-system
kubectl get csr
kubeadm certs check-expiration
Node 上:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates
证书更新完成后的检查
1. 检查 kubeadm 管理的证书
kubeadm certs check-expiration
确认不存在:
<invalid>
2. 检查 kubelet 证书
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
确认:
subject=O = system:nodes, CN = system:node:<NODE_NAME>
并确认 notAfter 在未来。
3. 检查 kubelet 配置
grep -nE 'rotateCertificates|serverTLSBootstrap' /var/lib/kubelet/config.yaml
确认:
rotateCertificates: true
4. 检查 kubelet.conf
grep -nE 'client-certificate|client-key|client-certificate-data|client-key-data' /etc/kubernetes/kubelet.conf
确认 kubelet 可以使用当前轮转证书:
/var/lib/kubelet/pki/kubelet-client-current.pem
5. 检查 Node
kubectl get nodes -o wide
应该全部:
Ready
6. 检查所有 Pod
kubectl get pods -A
重点确认:
STATUS
READY
RESTARTS
没有持续异常。
7. 检查 kube-system
kubectl get pods -n kube-system -o wide
重点关注:
etcd
kube-apiserver
kube-controller-manager
kube-scheduler
coredns
kube-proxy
8. 检查 CSR
kubectl get csr
正常情况下不应该长期存在无法解释的:
Pending
9. 检查 kubelet 日志
journalctl -u kubelet --since "30 minutes ago" --no-pager
重点关注:
x509
certificate
Unauthorized
authentication
system:anonymous
如果证书恢复后仍然持续出现这些错误,需要继续排查 kubelet.conf、RBAC、CSR 和 API Server。
10. 检查 API Server
kubectl get --raw='/readyz?verbose'
确认:
ok
证书更新相关的重要注意事项
1. kubeadm certs renew all 不等于更新所有 Kubernetes 证书
错误理解:
kubeadm certs renew all
↓
所有 Kubernetes 证书全部更新
正确理解:
kubeadm certs renew all
↓
更新 kubeadm 管理的控制平面/客户端证书
kubelet 客户端证书需要单独关注:
/var/lib/kubelet/pki/kubelet-client-current.pem
2. kubelet 正常情况下应该自动轮转
如果:
rotateCertificates: true
那么一般不需要每年手动生成 kubelet.conf。
如果出现证书过期,应优先排查:
kubectl get csr
以及:
journalctl -u kubelet
而不是简单地每年人工复制一次 kubelet.conf。
3. certificateValidityPeriod 不代表 kubelet 每年都需要人工更新
例如 kubeadm 配置:
certificateValidityPeriod: 8760h
代表 kubeadm 生成的相关证书有效期约为一年。
但是 kubelet 的客户端证书有自动轮转机制。
因此:
证书有效期 1 年
不代表:
每年手工更新 kubelet
4. 不要删除 CA 私钥
绝对不要因为证书过期就删除:
/etc/kubernetes/pki/ca.key
也不要把它复制到 Node。
5. 不要直接删除整个 pki 目录
不要执行:
rm -rf /etc/kubernetes/pki
这可能造成严重的集群故障。
6. 不要一次性停止所有 static Pod
尤其是单 Control Plane 集群。
不要直接:
mv /etc/kubernetes/manifests/* /tmp/
应该:
一个组件
↓
确认恢复
↓
下一个组件
7. 不要无条件 approve 所有 CSR
不要直接:
kubectl get csr | grep Pending | awk '{print $1}' | xargs kubectl certificate approve
应该:
kubectl get csr
然后:
kubectl describe csr <CSR_NAME>
确认身份后:
kubectl certificate approve <CSR_NAME>
常用命令汇总
查看证书
kubeadm certs check-expiration
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
查看 kubelet
systemctl status kubelet --no-pager
journalctl -u kubelet --since "30 minutes ago" --no-pager
grep -nE 'rotateCertificates|serverTLSBootstrap' /var/lib/kubelet/config.yaml
查看 CSR
kubectl get csr
kubectl describe csr <CSR_NAME>
kubectl certificate approve <CSR_NAME>
查看集群
kubectl get nodes -o wide
kubectl get pods -A
kubectl get pods -n kube-system -o wide
查看 static Pod
ls -lah /etc/kubernetes/manifests/
crictl ps -a
crictl ps -a | grep kube-controller-manager
crictl ps -a | grep kube-apiserver
crictl ps -a | grep kube-scheduler
crictl ps -a | grep etcd
实际故障案例:控制平面和 kubelet 证书同时过期
以下是一次实际证书故障的典型恢复过程,用于说明为什么不能只执行 kubeadm certs renew all。
故障表现
控制平面组件出现:
x509: certificate has expired or is not yet valid
例如 kube-controller-manager 使用的客户端证书已经过期。
同时 Node 上:
kubelet-client-current.pem
也已经过期。
Node kubelet 日志中可能出现:
system:anonymous
或者:
Unauthorized
此时可能看到:
kubectl get nodes
部分 Node:
NotReady
第一阶段:恢复 controller-manager
检查:
kubeadm certs check-expiration
执行:
kubeadm certs renew all
然后:
kubeadm certs check-expiration
确认 controller-manager 证书已经更新。
如果 controller-manager 仍然使用旧证书,需要让 static Pod 真正重新加载。
检查:
crictl ps -a | grep kube-controller-manager
必要时停止旧 container:
crictl stop <CONTAINER_ID>
然后等待 kubelet 重建。
检查:
crictl ps -a | grep kube-controller-manager
并观察日志:
crictl logs <CONTAINER_ID>
第二阶段:恢复 kubelet
发现 Node 上:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-dates \
-subject \
-serial
显示证书已经过期。
此时不能只执行:
kubeadm certs renew all
而应该在正常 Control Plane 上:
NODE=k8s-node01
kubeadm kubeconfig user \
--org system:nodes \
--client-name system:node:$NODE \
> /root/${NODE}-kubelet.conf
复制:
scp /root/${NODE}-kubelet.conf root@${NODE}:/etc/kubernetes/kubelet.conf
Node 上:
chmod 600 /etc/kubernetes/kubelet.conf
systemctl restart kubelet
然后:
ls -lah /var/lib/kubelet/pki/
确认:
kubelet-client-current.pem
已经生成并指向新的证书。
检查:
openssl x509 \
-in /var/lib/kubelet/pki/kubelet-client-current.pem \
-noout \
-subject \
-issuer \
-dates \
-serial
确认:
CN=system:node:k8s-node01
O=system:nodes
以及新的 notAfter。
第三阶段:确认 Node 恢复
kubectl get nodes -o wide
确认:
k8s-node01 Ready
然后:
kubectl get pods -A
确认业务 Pod 和系统 Pod 恢复。
结论
kubeadm 管理的 Kubernetes 证书需要区分两类:
Kubernetes 证书
│
┌────────────┴────────────┐
│ │
kubeadm 管理的证书 kubelet 客户端证书
│ │
kubeadm certs renew all 自动轮转
│ │
控制平面组件 /var/lib/kubelet/pki/
admin.conf
controller-manager.conf
scheduler.conf
apiserver
etcd 等
正常情况下:
控制平面证书
↓
定期检查
↓
kubeadm certs renew all
而:
kubelet 客户端证书
↓
rotateCertificates: true
↓
自动生成 CSR
↓
CSR 被批准
↓
自动生成新证书
因此最重要的不是“每年手工更新一次证书”,而是建立一套完整的证书检查和恢复机制:
检查证书
↓
发现即将过期
↓
正常更新
↓
确认 kubelet 自动轮转
↓
检查 CSR
↓
检查 static Pod
↓
检查 Node
↓
检查所有 Pod
↓
完成验证
如果真的发生证书过期:
先确认故障范围
↓
恢复 kubelet 认证
↓
恢复控制平面证书
↓
逐个重新加载 static Pod
↓
检查 CSR
↓
检查 Node Ready
↓
检查系统 Pod
↓
检查业务 Pod
↓
最终确认所有证书有效
官方文档:
-
kubeadm 证书管理
https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/ -
kubelet 证书自动轮转
https://kubernetes.io/docs/tasks/tls/certificate-rotation/ -
kubeadm Troubleshooting
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/ -
kubelet client certificate troubleshooting
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/troubleshooting-kubeadm/#kubelet-client-cert

