错误信息
Unable to connect to the server: tls: failed to verify certificate: x509: certificate has expired or is not yet valid
Go 会附上两个时间点:“…: current time <client time> is after <notAfter>”(对于尚未生效的证书则是“is before <notBefore>”),由此可以看出是哪一方出了问题。
kubectl (client-go) — the API server certificate (often after a year without kubeadm upgrades) is outside its validity period
含义
按 kubectl 所在机器的本地时间,API 服务器出示的证书不在有效期内。在 kubeadm 集群中,控制平面证书的有效期为一年,且只会在 kubeadm 升级时自动续期,因此一年未做任何操作的集群就会报出完全相同的错误。客户端时钟错误也会产生同样的错误。
原因
kubeadm 控制平面证书在一年后过期
常见apiserver、front-proxy 和 etcd 证书(以及 admin.conf 中的客户端证书)默认有效期为一年;它们会在执行 kubeadm upgrade 时续期,也可以用 kubeadm certs renew 续期。
kubeconfig 中的客户端证书已过期
偶见服务器证书续期后,带有过期客户端证书的旧 admin.conf 无法通过身份验证(报出的是另一条消息:“You must be logged in to the server (Unauthorized)”)。
时钟偏差
偶见完整消息中出现“is before”,说明客户端时钟落后,时间早于证书的 notBefore。
修复方法
- 1.
列出证书的过期时间
kubeadm certs check-expiration 会列出每张控制平面证书及其剩余有效期。
bash # On a control-plane node sudo kubeadm certs check-expiration - 2.
续期证书并重启控制平面
kubeadm certs renew all 会写入新证书;必须重启静态 Pod 才能加载它们,内嵌了客户端证书的 kubeconfig 也必须更新。
bash sudo kubeadm certs renew all # restart the control-plane static pods so they load the new certificates, # then refresh your kubeconfig (the embedded client certificate was renewed too): sudo cp /etc/kubernetes/admin.conf "$HOME/.kube/config" - 3.
检查客户端的时间
如果完整消息中出现“is before”,就同步时钟。
bash date -u; timedatectl status | grep -i synchronized