K8s集群证书过期导致kubelet报错?手把手教你快速更新证书(含避坑指南)
Kubernetes集群证书管理:从“node not found”到高可用运维实战
凌晨三点,手机突然响起刺耳的告警声。屏幕上跳动着熟悉的红色警告:“kubelet.go:2461] Error getting node err=node "k8s-master" not found”。你揉了揉惺忪的睡眼,心里一沉——生产环境的Kubernetes集群出问题了。这已经不是第一次遇到证书过期导致的故障,但每次处理都像是在和时间赛跑,稍有不慎就会导致服务中断。
Kubernetes集群的证书管理,对于很多运维工程师来说,就像房间里的大象——大家都知道它很重要,但往往等到问题爆发时才匆忙应对。证书过期导致的节点失联、API Server拒绝连接、Pod调度失败等问题,已经成为生产环境中最常见的“定时炸弹”。今天,我们就来深入探讨如何系统化地管理Kubernetes证书,从被动救火转向主动预防。
1. Kubernetes证书体系深度解析
要真正掌握证书管理,首先得理解Kubernetes的证书架构。很多人只知道kubeadm certs renew all这个命令,却不清楚背后到底发生了什么。实际上,一个标准的Kubernetes集群包含多种类型的证书,每种都有其特定的生命周期和作用域。
1.1 证书类型与作用域
Kubernetes集群中的证书主要分为以下几类:
| 证书类型 | 默认有效期 | 主要用途 | 影响范围 |
|---|---|---|---|
| CA证书 | 10年 | 根证书,签发其他所有证书 | 整个集群 |
| API Server证书 | 1年 | API Server的TLS服务端证书 | 控制平面通信 |
| etcd证书 | 1年 | etcd集群内部通信 | 数据存储层 |
| kubelet客户端证书 | 1年 | kubelet向API Server认证 | 节点注册与心跳 |
| front-proxy证书 | 1年 | 聚合层代理通信 | API扩展功能 |
| Service Account令牌 | 无期限 | Pod内服务账户认证 | 应用权限控制 |
这里有个常见的误解:很多人认为只要更新了API Server证书就万事大吉。实际上,证书链的完整性才是关键。如果CA证书过期,所有由其签发的证书都会失效;如果某个中间证书过期,依赖它的组件也会出现问题。
1.2 证书存储位置与访问权限
不同组件的证书存储在不同的位置,了解这些位置对于故障排查至关重要:
# 查看集群证书存储位置
ls -la /etc/kubernetes/pki/
# 典型目录结构
/etc/kubernetes/pki/
├── apiserver.crt # API Server服务端证书
├── apiserver.key
├── apiserver-etcd-client.crt # API Server访问etcd的客户端证书
├── apiserver-etcd-client.key
├── apiserver-kubelet-client.crt # API Server访问kubelet的客户端证书
├── apiserver-kubelet-client.key
├── ca.crt # 集群根CA证书
├── ca.key # CA私钥(需严格保护)
├── etcd/
│ ├── ca.crt # etcd集群CA证书
│ ├── healthcheck-client.crt
│ ├── peer.crt # etcd节点间通信证书
│ └── server.crt # etcd服务端证书
└── front-proxy-ca.crt # 前端代理CA证书
注意:
ca.key是集群的根私钥,一旦泄露或丢失,整个集群的证书体系都需要重建。务必将其备份到安全的位置,并设置严格的访问权限。
2. 证书过期故障的精准诊断
当出现"node not found"错误时,证书过期只是众多可能原因之一。我们需要一套系统化的诊断流程,而不是盲目地执行证书更新命令。
2.1 症状分析与初步定位
首先,通过几个关键命令快速判断问题范围:
# 检查kubelet服务状态
systemctl status kubelet -l
# 查看kubelet日志中的关键错误
journalctl -u kubelet --since "1 hour ago" | grep -E "(certificate|expired|not found|refused)"
# 测试API Server连通性
curl -k https://<API_SERVER_IP>:6443/healthz
# 或者使用kubectl测试
kubectl cluster-info --request-timeout=5s
如果看到类似下面的错误,很可能是证书问题:
x509: certificate has expired or is not yet valid
Unable to connect to the server: x509: certificate has expired
2.2 证书状态检查工具
手动检查每个证书的过期时间既繁琐又容易遗漏。我通常使用一个自制的检查脚本:
#!/bin/bash
# check-k8s-certs.sh - Kubernetes证书过期检查工具
CERT_DIR="/etc/kubernetes/pki"
KUBECONFIG_DIR="/etc/kubernetes"
echo "=== Kubernetes证书过期检查报告 ==="
echo "检查时间: $(date)"
echo ""
# 检查PKI目录下的所有证书
echo "1. PKI证书检查:"
for cert in $(find $CERT_DIR -name "*.crt"); do
echo "证书: $(basename $cert)"
openssl x509 -in $cert -noout -dates | grep notAfter
echo "剩余天数: $(( ($(date -d "$(openssl x509 -in $cert -noout -dates | grep notAfter | cut -d= -f2)" +%s) - $(date +%s)) / 86400 ))"
echo "---"
done
# 检查kubeconfig中的证书
echo ""
echo "2. Kubeconfig证书检查:"
for config in $KUBECONFIG_DIR/*.conf; do
if [ -f "$config" ]; then
echo "配置文件: $(basename $config)"
# 提取并检查嵌入的证书
kubectl --kubeconfig=$config config view --raw -o jsonpath='{.users[*].user.client-certificate-data}' | \
base64 -d | openssl x509 -noout -dates 2>/dev/null || echo "无嵌入证书"
echo "---"
fi
done
# 检查Service Account令牌
echo ""
echo "3. Service Account令牌检查:"
for token in $(find /var/run/secrets/kubernetes.io/serviceaccount -name "*.crt" 2>/dev/null); do
echo "令牌: $(basename $token)"
openssl x509 -in $token -noout -dates 2>/dev/null || echo "非x509格式"
echo "---"
done
这个脚本会输出每个证书的过期时间和剩余天数,让你对集群的证书健康状况一目了然。
2.3 网络与配置排查
证书问题有时会与网络配置问题混淆。在确认证书状态前,先排除网络因素:
# 检查网络连通性
ping -c 3 <API_SERVER_IP>
nc -zv <API_SERVER_IP> 6443
# 检查防火墙规则
iptables -L -n | grep 6443
firewall-cmd --list-all # 对于firewalld
# 检查kubelet配置
cat /etc/kubernetes/kubelet.conf | grep server
如果网络连通性正常,但API Server端口拒绝连接,很可能是API Server本身没有正常启动——这又可能回到证书问题,因为API Server需要有效的证书才能启动。
3. 证书更新操作实战指南
确定了证书问题后,我们需要谨慎地执行更新操作。这里的关键是顺序和验证。
3.1 标准更新流程
对于使用kubeadm部署的集群,证书更新相对简单,但需要注意执行顺序:
# 1. 备份当前证书(安全第一!)
sudo cp -r /etc/kubernetes/pki /etc/kubernetes/pki.backup.$(date +%Y%m%d)
# 2. 更新所有证书
sudo kubeadm certs renew all
# 3. 查看更新结果
sudo kubeadm certs check-expiration
# 4. 更新kubeconfig文件中的证书
sudo kubeadm init phase kubeconfig all --config /etc/kubernetes/kubeadm-config.yaml
# 5. 分发新的kubeconfig到所有节点
# 对于控制平面节点
sudo cp /etc/kubernetes/admin.conf ~/.kube/config
# 对于工作节点,需要手动更新或重新join
更新后,你会看到类似这样的输出:
Certificate expiration dates:
Certificate Name Expiration Date Residual Time
admin.conf Dec 30 12:00:00 2025 GMT 364d
apiserver Dec 30 12:00:00 2025 GMT 364d
apiserver-etcd-client Dec 30 12:00:00 2025 GMT 364d
apiserver-kubelet-client Dec 30 12:00:00 2025 GMT 364d
...
3.2 组件重启顺序与注意事项
证书更新后,相关组件需要重启才能使用新证书。错误的重启顺序可能导致集群短暂不可用:
-
首先重启静态Pod控制器:
# 移动静态Pod manifests让kubelet重新拉取 sudo mv /etc/kubernetes/manifests /etc/kubernetes/manifests.backup sudo mkdir /etc/kubernetes/manifests # 等待几秒让kubelet检测到变化 sleep 10 # 恢复manifests sudo mv /etc/kubernetes/manifests.backup/* /etc/kubernetes/manifests/ -
重启kubelet服务:
sudo systemctl daemon-reload sudo systemctl restart kubelet -
验证组件状态:
# 等待所有组件就绪 sleep 30 # 检查组件状态 kubectl get pods -n kube-system kubectl get nodes # 检查证书是否生效 kubectl cluster-info
重要提示:在生产环境中,建议逐个节点进行证书更新和重启,避免同时影响多个控制平面节点。对于高可用集群,可以先更新备用节点,验证无误后再更新主节点。
3.3 特殊情况处理
场景一:CA证书即将过期
如果CA证书即将过期(剩余时间少于90天),简单的renew命令可能不够:
# 检查CA证书过期时间
sudo kubeadm certs check-expiration | grep ca
# 如果CA证书即将过期,需要重新生成
# 注意:这会重新签发所有证书,需要更复杂的操作
sudo kubeadm init phase certs all --config /etc/kubernetes/kubeadm-config.yaml
场景二:etcd证书问题
etcd证书问题比较隐蔽,因为etcd通常运行在控制平面内部。如果遇到etcd相关错误:
# 检查etcd集群健康状态
kubectl exec -n kube-system etcd-<node-name> -- etcdctl \
--cert /etc/kubernetes/pki/etcd/peer.crt \
--key /etc/kubernetes/pki/etcd/peer.key \
--cacert /etc/kubernetes/pki/etcd/ca.crt \
--endpoints https://127.0.0.1:2379 endpoint health
# 更新etcd证书
sudo kubeadm certs renew etcd-peer
sudo kubeadm certs renew etcd-server
sudo kubeadm certs renew etcd-healthcheck-client
4. 自动化证书管理与预防策略
手动管理证书终究不是长久之计。在生产环境中,我们需要建立自动化的证书管理机制。
4.1 使用cert-manager实现自动续期
cert-manager是Kubernetes原生的证书管理工具,可以自动处理证书的颁发和续期:
# cert-manager安装(使用helm)
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager \
--namespace cert-manager \
--create-namespace \
--version v1.13.0 \
--set installCRDs=true
# 创建ClusterIssuer(使用自签名CA)
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
为Kubernetes API Server配置自动续期:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: kube-apiserver
namespace: kube-system
spec:
secretName: kube-apiserver-cert
duration: 8760h # 1年
renewBefore: 720h # 提前30天续期
issuerRef:
name: selfsigned-issuer
kind: ClusterIssuer
commonName: kube-apiserver
dnsNames:
- kubernetes
- kubernetes.default
- kubernetes.default.svc
- kubernetes.default.svc.cluster.local
- <API_SERVER_IP>
ipAddresses:
- 127.0.0.1
- <API_SERVER_IP>
usages:
- server auth
- client auth
4.2 监控与告警配置
预防胜于治疗。建立完善的监控体系可以在证书过期前及时发现问题:
# Prometheus规则示例 - 证书过期告警
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: k8s-certificate-expiry
namespace: monitoring
spec:
groups:
- name: certificate-expiry
rules:
- alert: K8SCertificateExpiringSoon
expr: kubelet_certificate_manager_client_ttl_seconds < 2592000 # 30天
for: 5m
labels:
severity: warning
annotations:
summary: "Kubernetes证书即将过期"
description: "证书 {{ $labels.name }} 将在 {{ $value | humanizeDuration }} 后过期"
- alert: K8SCertificateExpired
expr: kubelet_certificate_manager_client_ttl_seconds < 0
for: 1m
labels:
severity: critical
annotations:
summary: "Kubernetes证书已过期"
description: "证书 {{ $labels.name }} 已过期 {{ $value | humanizeDuration }}"
4.3 定期维护检查清单
建立定期检查机制,我通常会在每个月的第一个周一执行以下检查:
-
证书状态检查:
# 使用之前的检查脚本 ./check-k8s-certs.sh > /var/log/k8s-cert-check-$(date +%Y%m%d).log # 检查kubeadm管理的证书 kubeadm certs check-expiration -
集群健康状态验证:
# 检查所有节点状态 kubectl get nodes -o wide # 检查核心组件状态 kubectl get pods -n kube-system # 检查事件中的异常 kubectl get events --sort-by='.lastTimestamp' | tail -20 -
备份验证:
# 验证etcd备份 etcdctl snapshot status /backup/etcd-snapshot.db # 验证证书备份 ls -la /backup/certificates/
4.4 灾难恢复演练
证书问题最坏的情况是CA私钥丢失或损坏。这时需要完整的灾难恢复:
# 灾难恢复流程示例
# 1. 从备份恢复CA证书和密钥
sudo cp /backup/certificates/ca.* /etc/kubernetes/pki/
# 2. 重新生成所有证书
sudo kubeadm init phase certs all --config /etc/kubernetes/kubeadm-config.yaml
# 3. 重新生成kubeconfig文件
sudo kubeadm init phase kubeconfig all --config /etc/kubernetes/kubeadm-config.yaml
# 4. 重启所有组件
sudo systemctl restart kubelet
在实际操作中,我发现很多团队忽略了证书管理的系统性。证书过期问题往往在深夜或周末爆发,就是因为缺乏预警机制。建立自动化的证书管理流程,不仅能减少运维负担,更能提高集群的稳定性。
记得有一次,客户的集群在凌晨两点证书过期,导致所有服务中断。我们花了四个小时才完全恢复。从那以后,我坚持在每个集群部署cert-manager,并设置多层告警。现在,证书过期前30天就会收到邮件提醒,前7天会触发电话告警,真正做到了防患于未然。
证书管理看似琐碎,却是Kubernetes运维的基石。掌握这些技巧,你就能从容应对各种证书相关的问题,让集群运行更加稳定可靠。
更多推荐
所有评论(0)