错误信息
Unable to connect to the server: tls: failed to verify certificate: x509: certificate signed by unknown authority
在这一行之前,kubectl 1.37 还会把失败的 API 发现请求记录为一条错误级别的日志,其中包含“Couldn't get current server API group list”和同样的 TLS 错误。如果 kubeconfig 中的 CA 与真正的 CA 同名,文本后面还会接着“(possibly because of … while trying to verify candidate authority certificate \"kubernetes\")”。
kubectl (client-go) — the API server's certificate does not chain to the kubeconfig's certificate-authority-data
含义
kubectl 依据 kubeconfig 中存储的集群 CA(certificate-authority 或 certificate-authority-data)验证 API 服务器的证书,而不是依据系统的公共根证书。“Unknown authority”表示服务器出示的证书无法通过证书链追溯到这个 CA:kubeconfig 中没有 CA,或者是另一个集群的 CA,又或者你与 API 服务器之间有某个组件出示了自己的证书。
原因
kubeconfig 中缺少集群的 CA,或者包含的是另一个集群的 CA
常见手动编辑过的 kubeconfig、合并后指向错误集群条目的上下文,或者 server URL 被改成了出示另一张证书的负载均衡器。
执行 TLS 检查的代理为 API 服务器连接重新签发证书
常见kubectl 会使用 HTTPS_PROXY;公司代理出示的是自己的证书,而该证书不是由集群 CA 签发的。
托管集群的端点变了
偶见重新创建的 EKS、GKE 或 AKS 集群(或者轮换过的集群 CA)会让旧的 kubeconfig 条目中留下不再匹配的 CA。
修复方法
- 1.
查看 kubeconfig 中的 CA 和 server
解码 certificate-authority-data,并把它的主体和日期与 API 服务器证书的颁发者对比。
bash kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' \ | base64 -d | openssl x509 -noout -subject -enddate kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}' - 2.
嵌入正确的集群 CA
用集群的 CA(kubeadm 集群为 /etc/kubernetes/pki/ca.crt)设置集群条目,并把它嵌入 kubeconfig。
bash # kubeadm clusters: the cluster CA is /etc/kubernetes/pki/ca.crt on a control-plane node kubectl config set-cluster my-cluster --server=https://k8s.example.com:6443 \ --certificate-authority=ca.crt --embed-certs=true - 3.
为托管集群重新生成 kubeconfig
各云厂商的 CLI 会写入新的集群条目,其中包含当前的端点和 CA。
bash # Managed clusters: regenerate the kubeconfig entry from the provider aws eks update-kubeconfig --name my-cluster --region eu-central-1 gcloud container clusters get-credentials my-cluster --region europe-west1 az aks get-credentials --resource-group rg --name my-cluster - 4.
访问 API 服务器时绕过代理
把 API 服务器的主机或网段加入 NO_PROXY,而不是禁用 TLS 验证(insecure-skip-tls-verify)。
bash # kubectl honours HTTPS_PROXY; exclude the API server so a TLS-inspecting proxy is bypassed export NO_PROXY=k8s.example.com,10.0.0.0/8
相关错误
x509: certificate signed by unknown authority (possibly because of "crypto/rsa:…kubectl and other Go clientsUnable to connect to the server: tls: failed to verify certificate: x509: certi…kubectl (client-go)x509: certificate signed by unknown authorityGo crypto/x509Error response from daemon: Get "https://registry.example.com:5000/v2/": tls: f…Docker Engine (dockerd)