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 排查步骤
- 检查客户端证书有效期:使用
openssl x509 -in client.crt -text -noout | grep -A2 "Validity"查看Not Before和Not After。 - 对比系统时间:在客户端节点与 API Server 节点分别执行
date,确认时间偏差是否在 5 分钟以内(Kubernetes 默认容忍 5 分钟时钟偏移)。 - 查看 kubeconfig 中的证书路径:
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate}',确认实际加载的证书文件。 - 检查 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 排查步骤
- 验证证书链:
openssl verify -CAfile ca.crt client.crt,确认返回OK。 - 检查 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 一致。 - 确认 API Server 启动参数:检查
--client-ca-file指向的 CA 文件是否包含正确的根证书。 - 检查中间 CA 场景:如果使用中间 CA 签发,确保客户端证书携带完整的证书链(server.crt + intermediate.crt)。
💡 工程经验:在大型集群中,建议将 CA 证书与中间 CA 证书合并为一个 PEM 文件,通过
--client-ca-file 加载,避免因证书链不完整导致的签名验证失败。
4.3 证书认证失败排查流程图
以下 SVG 图展示了从收到 401 Unauthorized 错误到定位证书过期或签名不匹配的完整排查链路:
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 分钟内完成定位与修复。工程化落地时,务必建立证书生命周期监控与自动轮换体系,避免人工操作引入的签名错误。