4. 认证失败场景一:证书过期与签名不匹配

在 Kubernetes 鉴权拦截链路中,认证(Authentication)是请求进入 API Server 的第一道关卡。当客户端(kubectl、kubelet、ServiceAccount 等)提供的 TLS 证书无效时,API Server 会立即返回 401 Unauthorized 错误,并拒绝后续的鉴权与准入控制。本章聚焦于最常见的两种证书认证失败场景:证书过期与签名不匹配,深入分析其错误特征、排查思路与工程化修复方案。

4.1 证书过期:时间窗口失效

Kubernetes 集群中,CA 签发的客户端证书与服务器证书均包含 Not Before 和 Not After 字段。当系统时间超出证书有效期时,TLS 握手阶段会直接失败。

4.1.1 错误特征与日志定位

证书过期时,kube-apiserver 日志与客户端输出具有明显特征:

组件 典型错误信息 关键字段
kube-apiserver tls: bad certificate x509: certificate has expired or is not yet valid
kubectl error: You must be logged in to the server (Unauthorized) certificate has expired
kubelet failed to get client certificate for TLS handshake certificate expired
⚠️ 常见误区:很多运维人员看到 401 Unauthorized 会直接怀疑 RBAC 权限不足,而忽略了证书过期这一前置原因。务必先检查 TLS 握手阶段的错误日志。

4.1.2 排查步骤

  1. 检查客户端证书有效期:使用 openssl x509 -in client.crt -text -noout | grep -A2 "Validity" 查看 Not Before 和 Not After。
  2. 对比系统时间:在客户端节点与 API Server 节点分别执行 date,确认时间偏差是否在 5 分钟以内(Kubernetes 默认容忍 5 分钟时钟偏移)。
  3. 查看 kubeconfig 中的证书路径:kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate}',确认实际加载的证书文件。
  4. 检查 kube-apiserver 日志:在 master 节点执行 journalctl -u kube-apiserver -n 50 | grep -i "certificate\|expired\|bad certificate"。

4.1.3 工程化修复方案

  • 手动更新证书:使用 kubeadm alpha certs renew client-admin(kubeadm 集群)或重新签发客户端证书。
  • 自动轮换:对于 kubelet 证书,启用 RotateKubeletServerCertificate 与 RotateKubeletClientCertificate 特性门控,实现证书自动续期。
  • 时间同步:在所有节点部署 NTP 服务(chrony/ntpd),确保集群时间一致。

4.2 签名不匹配:CA 信任链断裂

当客户端证书不是由 API Server 信任的 CA 签发,或者证书链不完整时,TLS 握手会因签名验证失败而中断。

4.2.1 错误特征与日志定位

组件 典型错误信息 关键字段
kube-apiserver tls: failed to verify client certificate x509: certificate signed by unknown authority
kubectl error: certificate signed by unknown authority certificate is not trusted
kubelet failed to verify certificate signature unknown authority

4.2.2 排查步骤

  1. 验证证书链:openssl verify -CAfile ca.crt client.crt,确认返回 OK。
  2. 检查 kubeconfig 中的 CA 数据:kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d | openssl x509 -text -noout | grep "Subject\|Issuer",确认 CA 证书与签发客户端证书的 CA 一致。
  3. 确认 API Server 启动参数:检查 --client-ca-file 指向的 CA 文件是否包含正确的根证书。
  4. 检查中间 CA 场景:如果使用中间 CA 签发,确保客户端证书携带完整的证书链(server.crt + intermediate.crt)。
💡 工程经验:在大型集群中,建议将 CA 证书与中间 CA 证书合并为一个 PEM 文件,通过 --client-ca-file 加载,避免因证书链不完整导致的签名验证失败。

4.3 证书认证失败排查流程图

以下 SVG 图展示了从收到 401 Unauthorized 错误到定位证书过期或签名不匹配的完整排查链路:

证书认证失败排查流程图 证书认证失败排查流程图(401 Unauthorized) 收到 401 Unauthorized 错误 检查 kube-apiserver 日志 错误类型判断 证书过期 签名不匹配 检查证书有效期 对比系统时间 更新证书 / 同步时间 验证证书链 检查 CA 文件配置 重新签发 / 合并 CA 验证修复结果

4.4 证书认证失败对比总结

对比维度 证书过期 签名不匹配
根本原因 证书超出有效期或系统时间偏差 CA 信任链断裂、中间 CA 缺失、CA 文件配置错误
错误日志关键字 certificate has expired certificate signed by unknown authority
排查工具 openssl x509、date openssl verify、kubectl config view
修复手段 证书续期、NTP 时间同步 重新签发、合并 CA 链、修正 --client-ca-file
自动化方案 kubelet 证书轮换、cert-manager CA 证书统一管理、Operator 自动签发

4.5 工程落地最佳实践

  • 证书监控:部署 Prometheus + Blackbox Exporter 或 cert-manager 的 Certificate 资源,对证书过期时间设置告警(提前 30 天、7 天、1 天)。
  • 统一 CA 管理:使用 cfssl 或 cert-manager 作为集群 CA 基础设施,避免手动签发导致的签名不一致。
  • kubeconfig 校验脚本:在 CI/CD 流水线中加入 kubectl config view --raw | openssl x509 -checkend 86400 检查,确保证书在部署时有效。
  • 时间同步加固:所有节点配置 chrony,并设置 maxdistance 0.1 限制时钟偏移,从根源减少证书过期误报。
📌 核心结论:证书过期与签名不匹配是 Kubernetes 认证失败的两大主因。通过日志关键字快速区分场景,结合 openssl 工具链与集群时间同步机制,可以在 5 分钟内完成定位与修复。工程化落地时,务必建立证书生命周期监控与自动轮换体系,避免人工操作引入的签名错误。