1. 问题现象与背景分析
那天凌晨三点,我被刺耳的告警声惊醒——生产环境中的Kubernetes集群出现大面积Pod异常。登录控制台后发现,十几个关键业务Pod卡在ContainerCreating状态,而Calico组件日志中不断刷出"Unauthorized"错误。这一切都源于两小时前我们对某个节点虚拟机执行的快照恢复操作。
作为基础设施团队的新人,这是我第一次处理Kubernetes存储层故障。通过查阅文档和社区案例,发现这是典型的"快照恢复后身份凭证失效"问题。当使用虚拟机快照回滚节点时,虽然磁盘数据回到了过去的状态,但Kubernetes和Calico的认证信息却已发生变化,导致新旧凭证不匹配。具体表现为:
- kubelet无法通过旧证书与API Server建立安全连接
- Calico的Felix组件因认证失败无法同步网络策略
- CNI插件在配置网络时因权限不足而阻塞Pod创建
2. 关键组件交互原理
2.1 Kubernetes证书体系
每个Node节点都持有以下关键身份凭证:
/etc/kubernetes/pki/kubelet.crt:kubelet客户端证书/etc/kubernetes/pki/kubelet.key:对应私钥/etc/kubernetes/kubelet.conf:包含当前CA证书和Bearer Token
这些凭证默认有效期1年,但快照恢复会使节点使用过期的历史凭证。API Server会拒绝这些凭证的认证请求,表现为kubelet日志中的x509: certificate has expired or is not yet valid错误。
2.2 Calico身份验证机制
Calico组件通过两种方式认证:
- 节点使用
/var/lib/calico/nodename中存储的节点标识 - Felix进程通过
/etc/cni/net.d/calico-tls/下的TLS证书与API通信
快照恢复会导致这些凭证与etcd中记录的最新状态不一致,触发Unauthorized错误。特别需要注意的是,Calico v3.20+版本强化了安全策略,对凭证失效更加敏感。
3. 完整排查与修复流程
3.1 诊断步骤实录
检查Pod事件流:
kubectl describe pod <stuck_pod> -n <namespace>在Events段发现关键错误:
Warning FailedCreatePodSandBox 2m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to setup network: calico: Unauthorized分析Calico组件日志:
kubectl logs -n kube-system calico-node-xxxxx -c felix输出包含:
2023-03-15 03:12:45.123 [ERROR] Failed to validate TLS config: unauthorized: authentication credentials invalid验证kubelet证书状态:
openssl x509 -in /etc/kubernetes/pki/kubelet.crt -noout -dates发现证书有效期与当前系统时间不匹配。
3.2 修复操作全记录
3.2.1 节点证书更新
删除失效凭证:
rm -f /etc/kubernetes/pki/kubelet.* rm -f /etc/kubernetes/kubelet.conf重新生成凭证(适用于kubeadm集群):
kubeadm alpha certs renew kubelet-client systemctl restart kubelet
注意:如果使用Rancher等管理平台,需要通过平台UI重新生成节点注册令牌
3.2.2 Calico身份重置
清理旧节点数据:
rm -f /var/lib/calico/nodename rm -rf /etc/cni/net.d/calico-tls/*重建Calico证书:
kubectl delete pod -n kube-system -l k8s-app=calico-node强制同步网络策略:
calicoctl node status --allow-version-mismatch
3.2.3 批量恢复Pod
删除卡住的Pod(有Deployment管理的会自愈):
kubectl delete pod --force --grace-period=0 <pod_name>检查CNI插件状态:
journalctl -u kubelet -f | grep -i cni
4. 深度避坑指南
4.1 虚拟机快照最佳实践
快照前准备:
- 执行
kubectl drain <node>优雅驱逐工作负载 - 停止kubelet和容器运行时服务
systemctl stop kubelet docker- 执行
快照后操作:
- 删除以下易变文件后再启动服务:
rm -f /var/lib/kubelet/device-plugins/* rm -f /var/run/containerd/*
4.2 证书管理进阶技巧
监控证书过期(加入Prometheus告警规则):
- alert: KubeletCertificateExpiry expr: kubelet_certificate_manager_client_expiration_seconds < 86400*7 for: 10m使用cert-manager自动轮换:
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.10.1/cert-manager.yaml
4.3 Calico特定配置优化
在calico-configConfigMap中增加容错参数:
data: typha_service_name: "none" felix_logseverity: "Warning" cni_network_config: |- { "name": "k8s-pod-network", "cniVersion": "0.3.1", "plugins": [ { "type": "calico", "log_level": "WARN", "authentication": { "type": "none" } } ] }5. 故障预防体系
5.1 节点健康检查清单
建议将以下检查项加入日常巡检脚本:
#!/bin/bash check_certs() { local cert=$1 if ! openssl x509 -checkend 86400 -noout -in "$cert"; then echo "[CRITICAL] Certificate expires soon: $cert" fi } check_certs /etc/kubernetes/pki/kubelet.crt check_certs /etc/cni/net.d/calico-tls/etcd-ca.crt5.2 自动化修复方案
对于频繁发生的问题,可创建自动化修复Job:
apiVersion: batch/v1 kind: Job metadata: name: node-cert-repair spec: template: spec: hostPID: true containers: - name: repair image: alpine command: ["/bin/sh", "-c"] args: - | apk add openssl kubectl kubectl config set-cluster local --server=https://${KUBERNETES_SERVICE_HOST} kubectl config set-credentials admin --token=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) kubectl config set-context local --cluster=local --user=admin kubectl config use-context local # 修复逻辑 rm -f /host/etc/kubernetes/pki/kubelet.* kubectl certificate approve $(kubectl get csr | grep Pending | awk '{print $1}') volumeMounts: - name: host mountPath: /host volumes: - name: host hostPath: path: / type: Directory6. 从这次事故中学到的
快照不是备份:虚拟机快照会破坏分布式系统的状态一致性,生产环境应使用
etcd snapshot等原生备份方案凭证生命周期管理:所有集群节点都应配置证书监控,建议使用Vault等工具集中管理
变更影响评估:即使看似简单的运维操作,在云原生环境下也可能引发连锁反应。建立完整的变更checklist至关重要
那次凌晨的故障让我们损失了37分钟的业务时间。现在团队已经建立了完善的预防机制:所有节点证书过期前30天自动续期,Calico启用宽松认证模式,关键节点禁用快照功能。这些经验或许能帮你少走些弯路。