Mensagem de erro
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
As listas de endereços vêm do seu certificado e do seu kubeconfig. Para nomes DNS, a mensagem fica “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
O que significa
O certificado do servidor de API é confiável (a cadeia dele leva à CA do cluster), mas o endereço na URL do servidor do seu kubeconfig não está entre os nomes ou IPs dos Subject Alternative Names dele. O Go lista os SANs de IP que encontrou e o endereço que procurava. O kubeadm emite o certificado do servidor de API para o IP do serviço, os endereços dos nós e alguns nomes DNS; qualquer outra forma de acessá-lo precisa de um SAN extra.
Por que acontece
Acesso por um balanceador de carga ou um IP público
comumUm balanceador de carga, um IP flutuante ou um endereço NAT na frente do plano de controle que não foi passado como SAN extra no kubeadm init.
Túneis SSH e redirecionamentos de porta (port-forward)
comumAcessar o servidor de API como https://127.0.0.1:6443 por um túnel faz o cliente pedir o endereço 127.0.0.1, que o certificado não cobre.
O endereço IP do nó mudou
ocasionalClusters de nó único com DHCP, ou em VMs movidas para outra rede, continuam com um certificado para o endereço antigo.
Como corrigir
- 1.
Listar os SANs do certificado
Compare-os com a URL do servidor no kubeconfig.
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.
Gerar de novo o certificado do servidor de API com SANs extras
O kubeadm init phase certs apiserver emite um novo certificado com --apiserver-cert-extra-sans; antes, é preciso tirar o par antigo do lugar, e depois reiniciar o kube-apiserver para que ele carregue o novo certificado.
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.
Túneis: definir tls-server-name
Com o tls-server-name, o kubectl verifica um nome que o certificado cobre enquanto se conecta ao endereço do túnel, em vez de usar 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