K8S集群突然失联?别慌,手把手教你用kubeadm certs renew命令一键续期所有证书

凌晨三点,刺耳的告警铃声划破寂静。作为团队唯一的值班运维工程师,你发现所有Kubernetes集群监控面板突然变成一片红色——kubectl命令返回unauthorized错误,Dashboard无法访问,节点状态全部未知。这种突如其来的"集群失联"状况,往往让运维人员瞬间血压飙升。但请先深呼吸,这极可能是证书过期引发的连锁反应。本文将带你亲历一次真实的证书续期救援行动,从故障定位到完整恢复,揭秘那些官方文档没写的实战细节。

1. 证书失效的典型症状与快速诊断

当K8S集群证书过期时,系统不会温柔地提醒你"该续费了",而是直接切断所有管理通道。以下是三个最明显的症状特征:

  • kubectl命令报错:执行任何kubectl操作都会返回Error from server (Forbidden): You must be logged in to the server (unauthorized)
  • API Server拒绝连接:尝试直接访问API端口时出现x509: certificate has expired or is not yet valid错误
  • 控制平面组件异常:kubelet日志中频繁出现certificate rotation failedfailed to renew certificate警告

快速验证工具链

# 检查所有证书过期时间(需在Master节点执行)
kubeadm certs check-expiration | grep -E 'CERTIFICATE|RESIDUAL'

# 查看kubelet当前使用的客户端证书
openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -dates

注意:如果kubeadm certs命令本身报错,说明CA证书可能已过期,需要特殊处理流程(详见第4章)

2. 安全更新前的关键准备工作

证书续期操作虽然简单,但错误的执行顺序可能导致集群不可逆损坏。请严格遵循以下准备步骤:

2.1 全量备份集群状态

# 备份证书目录(关键!)
sudo cp -a /etc/kubernetes /etc/kubernetes_$(date +%Y%m%d)

# 备份etcd数据
ETCD_POD=$(kubectl -n kube-system get pods -l component=etcd -o name)
kubectl -n kube-system exec $ETCD_POD -- sh -c "ETCDCTL_API=3 etcdctl \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  snapshot save /var/lib/etcd/snapshot.db"

2.2 维护窗口协调

影响范围 预计停机时间 业务通知建议
控制平面 3-5分钟 提前告知可能的管理API中断
工作节点 滚动重启 无需特别通知
集群内服务 无影响 无需通知

3. 一键续期全流程操作指南

3.1 核心更新命令

# 更新所有证书(包括前端代理、API Server等)
sudo kubeadm certs renew all --config /etc/kubernetes/kubeadm-config.yaml

# 特别处理kubelet客户端证书
sudo rm -f /var/lib/kubelet/pki/kubelet-client-*
sudo systemctl restart kubelet

3.2 配置文件更新清单

  1. 更新kubeconfig

    mv $HOME/.kube/config $HOME/.kube/config.bak
    sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
  2. 必须重启的组件

    # 获取需要重启的Pod列表
    COMPONENTS="kube-apiserver|kube-controller-manager|kube-scheduler|etcd"
    kubectl -n kube-system get pods -o name | grep -E "$COMPONENTS" | xargs -I{} kubectl -n kube-system delete {}
    

提示:使用--dry-run参数可以先模拟证书更新过程,验证配置正确性

4. 极端情况处理:CA证书已过期怎么办

当CA证书本身过期时,常规的renew命令会失效。此时需要分步恢复:

  1. 临时修复(快速恢复业务):

    # 手动修改系统时间(仅用于应急)
    sudo date -s "$(date -d '+1 year' '+%Y%m%d %H:%M')"
    
    # 立即执行证书更新
    sudo kubeadm certs renew all
    
  2. 永久解决方案

    # 备份旧CA
    sudo mv /etc/kubernetes/pki/{ca.key,ca.crt} /etc/kubernetes/pki/ca-backup/
    
    # 生成新CA
    sudo kubeadm init phase certs ca --config /etc/kubernetes/kubeadm-config.yaml
    
    # 重新签发所有证书
    sudo kubeadm certs renew all --config /etc/kubernetes/kubeadm-config.yaml
    

5. 预防性维护与自动化方案

为避免再次陷入证书过期的"午夜惊魂",建议建立以下防护机制:

证书监控方案对比

方案类型 实施难度 预警提前量 推荐指数
Prometheus监控 30天 ★★★★☆
CronJob定期检查 7天 ★★★☆☆
cert-manager 实时 ★★★★★

推荐自动化脚本

#!/bin/bash
# 证书过期预警脚本(建议放入crontab每周运行)
WARNING_DAYS=30
CERT_DATA=$(kubeadm certs check-expiration | grep -v '^CERTIFICATE AUTHORITY')

while read -r line; do
  expiry_date=$(echo "$line" | awk '{print $2" "$3" "$4" "$5}')
  cert_name=$(echo "$line" | awk '{print $1}')
  remaining_days=$(( ($(date -d "$expiry_date" +%s) - $(date +%s)) / 86400 ))
  
  if [ $remaining_days -lt $WARNING_DAYS ]; then
    echo "[WARNING] 证书 $cert_name 将在 $remaining_days 天后过期 ($expiry_date)"
  fi
done <<< "$CERT_DATA"

记得去年某次大促前夜,我们三个集群同时证书过期。当时手动一个个组件重启,差点错过流量高峰。现在团队硬性规定:所有新集群部署必须配置cert-manager,并在监控系统添加证书过期告警。

更多推荐