1. Kubernetes证书管理核心概念解析
在Kubernetes集群中,证书是保障各组件间安全通信的基石。集群内部组件如API Server、Controller Manager、Scheduler、etcd等都需要通过TLS证书进行双向认证。这些证书通常由集群初始化时自动生成,但都有明确的有效期限制。
证书体系主要包含以下几类:
- CA证书:集群根证书,位于/etc/kubernetes/pki目录下
- API Server证书:用于验证API Server身份
- etcd证书:用于etcd集群成员间通信
- kubelet证书:节点与API Server通信使用
- ServiceAccount令牌:用于Pod身份认证
重要提示:默认情况下,Kubernetes集群证书有效期为1年,但不同版本的处理机制存在显著差异。证书过期会导致集群组件间通信中断,表现为API不可用、节点NotReady等故障。
2. 新版本集群(1.21+)证书管理方案
2.1 自动续期机制解析
Kubernetes 1.21版本引入了证书自动轮换机制,主要包含两个关键特性:
- kube-controller-manager内置的csr-approver控制器会自动批准节点证书续期请求
- kubeadm集成了完整的证书管理子命令
这种设计使得证书管理变得更加自动化,减少了运维干预的需求。自动续期过程实际上是通过CSR(Certificate Signing Request)机制完成的,kubelet会定期检查证书有效期并在到期前自动发起续期请求。
2.2 手动续期操作指南
虽然新版本支持自动续期,但在以下场景仍需手动干预:
- 需要立即更新证书而非等待自动续期
- 自动续期功能出现异常
- 需要检查当前证书状态
完整的手动续期流程如下:
bash复制# 检查证书过期情况(需在master节点执行)
kubeadm certs check-expiration
# 续期所有证书(或指定单个组件证书)
kubeadm certs renew all
# 重启控制平面组件使新证书生效
docker ps | grep -v pause | grep -E "etcd|scheduler|controller|apiserver" | awk '{print $1}' | awk '{print "docker","restart",$1}' | bash
# 更新kubectl配置文件
cp /etc/kubernetes/admin.conf /root/.kube/config
2.3 证书有效期定制方案
对于需要特别长有效期的情况(如测试环境),可以通过修改kubeadm源码重新编译的方式实现。核心修改点是cmd/kubeadm/app/constants/constants.go文件中的CertificateValidity常量值。
实际操作示例:
go复制// 原始值
CertificateValidity = time.Hour * 24 * 365
// 修改为100年
CertificateValidity = time.Hour * 24 * 365 * 100
生产环境警告:不建议为生产环境设置过长有效期,这会降低安全性。合理的做法是保持默认有效期并确保自动续期机制正常工作。
3. 旧版本集群证书管理方案
3.1 传统续期方法详解
对于1.21之前的版本,证书续期需要使用kubeadm alpha子命令:
bash复制# 检查证书状态
kubeadm alpha certs check-expiration
# 续期所有证书
kubeadm alpha certs renew all
这种方法虽然简单,但存在两个主要限制:
- 不会自动更新kubeconfig文件中的证书
- 需要手动重启相关组件
3.2 完全重新生成证书方案
当证书已经过期或需要彻底更新时,可采用重新生成的方式:
bash复制# 备份原有证书
tar czvf /tmp/pki-$(date +%Y%m%d).tar.gz -C /etc/kubernetes pki
# 重新生成所有证书
kubeadm init phase certs all --config /etc/kubernetes/kubeadm-config.yaml
# 重新生成kubeconfig文件
kubeadm init phase kubeconfig all --config /etc/kubernetes/kubeadm-config.yaml
关键注意事项:
- 确保kubeadm-config.yaml文件存在且内容正确
- 此操作会导致短暂的服务中断
- 所有节点都需要更新证书
3.3 证书分发与验证
在多master架构中,需要将新证书分发到所有控制平面节点:
bash复制# 在主节点打包证书
tar czvf pki.tar.gz -C /etc/kubernetes pki/*
# 启动临时HTTP服务
python3 -m http.server 8080
# 在其他master节点执行
sudo -i
cd /etc/kubernetes/
rm -rf pki
wget http://<主节点IP>:8080/pki.tar.gz
tar xf pki.tar.gz
证书验证命令:
bash复制# 检查API Server证书SAN
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep -A1 "Subject Alternative Name"
# 检查etcd证书
openssl x509 -in /etc/kubernetes/pki/etcd/server.crt -noout -text | grep -A1 "Subject Alternative Name"
4. 关联组件证书更新
4.1 Calico网络插件证书更新
当使用etcd作为Calico后端时,需要同步更新etcd证书:
bash复制# 获取当前Pod CIDR
POD_CIDR=$(grep 'cluster-cidr' /etc/kubernetes/manifests/kube-controller-manager.yaml | awk -F= '{print $2}')
# 更新Calico配置文件
sed '/CALICO_IPV4POOL_CIDR/{n;s#".*"#"'$POD_CIDR'"#}' calico-etcd.yaml -i
# 编码证书内容
etcd_key=$(cat /etc/kubernetes/pki/etcd/peer.key | base64 -w 0)
etcd_crt=$(cat /etc/kubernetes/pki/etcd/peer.crt | base64 -w 0)
etcd_ca=$(cat /etc/kubernetes/pki/etcd/ca.crt | base64 -w 0)
# 更新Calico配置中的证书
sed -i -e 's/\(etcd-key: \).*/\1'$etcd_key'/' \
-e 's/\(etcd-cert: \).*/\1'$etcd_crt'/' \
-e 's/\(etcd-ca: \).*/\1'$etcd_ca'/' calico-etcd.yaml
# 应用变更
kubectl delete -f calico-etcd.yaml --grace-period=0 --force
kubectl apply -f calico-etcd.yaml
4.2 CoreDNS证书更新
CoreDNS使用ServiceAccount token进行认证,更新方法如下:
bash复制# 查找并删除旧token
kubectl get secrets -n kube-system | grep coredns-token
kubectl delete secret -n kube-system coredns-token-xxxxx
# 重启CoreDNS
kubectl scale -n kube-system deployment/coredns --replicas=0
kubectl scale -n kube-system deployment/coredns --replicas=2
# 验证新token
TOKEN=$(kubectl get secret $(kubectl get secrets -n kube-system | grep coredns-token | awk '{print $1}') -n kube-system -o jsonpath='{.data.token}' | base64 -d)
curl -k -H "Authorization: Bearer $TOKEN" https://<API-SERVER-IP>:6443/api/v1/namespaces
5. 节点证书更新流程
5.1 Worker节点证书更新
工作节点主要需要更新以下证书和配置文件:
- /etc/kubernetes/kubelet.conf
- /etc/kubernetes/pki/ca.crt
- /var/lib/kubelet/pki目录下的证书
具体操作:
bash复制# 备份原有配置
sudo -i
cd /etc/kubernetes/
mv kubelet.conf kubelet.conf.bak
mv /var/lib/kubelet/pki /var/lib/kubelet/pki.bak
# 获取新配置
wget http://<master-ip>:8080/kubelet.conf
wget http://<master-ip>:8080/pki/ca.crt -O pki/ca.crt
# 重启服务
systemctl restart kubelet
systemctl status kubelet
5.2 kube-proxy证书更新
kube-proxy证书更新相对简单,只需删除Pod让其自动重建:
bash复制kubectl delete pod -n kube-system -l k8s-app=kube-proxy
6. 证书更新后的验证与排错
6.1 基础验证方法
bash复制# 检查节点状态
kubectl get nodes
# 检查组件状态
kubectl get cs
# 检查证书有效期
kubeadm certs check-expiration
6.2 常见问题解决方案
问题1:证书更新后API Server无法启动
- 检查/var/log/pods下的API Server日志
- 确认证书SAN包含所有必要的域名和IP
- 验证证书和私钥是否匹配:
openssl x509 -noout -modulus -in apiserver.crt | openssl md5
问题2:节点持续NotReady状态
- 检查kubelet日志:
journalctl -u kubelet -f - 验证节点证书是否被批准:
kubectl get csr - 手动批准证书:
kubectl certificate approve <csr-name>
问题3:Calico网络异常
- 检查calico-node Pod日志
- 验证etcd连接配置
- 确认网络策略是否影响通信
6.3 证书管理最佳实践
- 监控证书有效期:设置监控定期检查证书过期时间
bash复制# 监控脚本示例
kubeadm certs check-expiration | grep -E 'RESIDUAL|EXPIRES' | awk '{print $NF}' | while read date; do
remaining=$(( ($(date -d "$date" +%s) - $(date +%s)) / 86400 ))
[ $remaining -lt 30 ] && echo "警告:证书将在${remaining}天后过期"
done
-
定期备份证书:将/etc/kubernetes/pki目录定期备份到安全位置
-
文档记录:记录每次证书更新的时间和操作内容
-
测试环境验证:任何证书变更操作先在测试环境验证
-
版本升级计划:考虑将旧版本集群升级到1.21+以获得更好的证书管理体验