错误信息
Unable to connect to the server: tls: failed to verify certificate: x509: certificate is valid for 10.96.0.1, 192.168.1.10, not 127.0.0.1
消息中的地址列表来自你的证书和 kubeconfig。对于 DNS 名称,消息是“x509: certificate is valid for kubernetes, kubernetes.default, …, not k8s.example.com”。
kubectl (client-go) — the API server address in the kubeconfig is not among the API server certificate's SANs
含义
API 服务器的证书是受信任的(它的证书链能通向集群 CA),但 kubeconfig 中 server URL 的地址不在其主题备用名称(SAN)所列的名称或 IP 之中。Go 会列出它找到的 IP SAN 和它要匹配的地址。kubeadm 为 API 服务器签发的证书包含 Service IP、节点地址和几个 DNS 名称;通过其他任何方式访问 API 服务器,都需要额外的 SAN。
原因
通过负载均衡器或公网 IP 访问
常见控制平面前面的负载均衡器、浮动 IP 或 NAT 地址,在执行 kubeadm init 时没有作为额外的 SAN 传入。
SSH 隧道和端口转发
常见通过隧道以 https://127.0.0.1:6443 访问 API 服务器时,要验证的名称是 127.0.0.1,而证书并不覆盖这个地址。
节点的 IP 地址变了
偶见使用 DHCP 的单节点集群,或者被迁移到其他网络的虚拟机,保留的仍是为旧地址签发的证书。
修复方法
- 1.
列出证书的 SAN
把它们与 kubeconfig 中的 server URL 对比。
bash # On a control-plane node: the names and addresses the API server certificate covers sudo openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -ext subjectAltName - 2.
用额外的 SAN 重新生成 API 服务器证书
kubeadm init phase certs apiserver 会按 --apiserver-cert-extra-sans 签发新证书;必须先把旧的证书和密钥移走,然后重启 kube-apiserver 才能加载新证书。
bash # kubeadm: add the missing address/name to the API server certificate sudo mv /etc/kubernetes/pki/apiserver.{crt,key} /root/ sudo kubeadm init phase certs apiserver --apiserver-cert-extra-sans=203.0.113.20,k8s.example.com # then restart the kube-apiserver static pod (e.g. move its manifest out of /etc/kubernetes/manifests and back) - 3.
隧道:设置 tls-server-name
kubectl 的 tls-server-name 让它在连接隧道地址的同时,验证证书中确实包含的名称,而不必使用 insecure-skip-tls-verify。
bash # Through a tunnel or port-forward: keep verifying the name the certificate has kubectl config set-cluster my-cluster --server=https://127.0.0.1:6443 --tls-server-name=kubernetes