Se, em resposta ao comando
kubectl get pod
você obtiver:
Unable to connect to the server: x509: certificate has expired or is not yet valid
então, provavelmente, um ano se passou, seus certificados kubernetes expiraram, os componentes do cluster pararam de usá-los, a interação entre eles parou e o cluster se transformou em uma abóbora.

O que fazer e como restaurar um cluster?
Primeiro, precisamos entender onde estão localizados os certificados que precisam ser atualizados.
Dependendo da maneira como o cluster foi instalado, o local e o nome dos arquivos de certificado podem variar. Por exemplo, ao criar um cluster, o Kubeadm decompõe os arquivos de certificado de acordo com
as práticas recomendadas . Portanto, todos os certificados estão localizados no
/etc/kuberenetes/pki
, em arquivos com a extensão
.crt
, chaves privadas, respectivamente, nos arquivos
.key
. Além disso, em
/etc/kubernetes/
estão
.conf
arquivos
.conf
com configuração de acesso para administrador de contas de usuário, controlador de gerente, sheduler e kubelet no nó principal. Os certificados nos arquivos
.conf
estão no campo user.client-certificate-data no formato codificado em base64.
Você pode verificar a data de validade para quem foi emitido e por quem o certificado foi assinado usando este pequeno script shcert
Ainda existem certificados que usam o kubelet em nós de trabalho para autenticação na API. Se você usou o kubeadm join para adicionar nós ao cluster, provavelmente o nó foi conectado usando o procedimento de
inicialização TLS ; nesse caso, o kubelet poderá renovar seu certificado automaticamente se receber a opção
--rotate-certificates
. Nas versões recentes do kubernetes, essa opção já está ativada por padrão.
Verificar se o nó está conectado usando o procedimento de inicialização TLS é bastante simples - nesse caso, o arquivo
/etc/kubernetes/kubelet.conf
geralmente é especificado no campo de certificado do cliente no arquivo
/var/lib/kubelet/pki/kubelet-client-current.pem
que é um link simbólico para o certificado atual.
Você também pode ver as datas de validade deste certificado usando o script
shcert
Voltamos ao problema de renovação de certificados.Se você instalou o cluster usando o kubeadm, tenho boas notícias para você. A partir da versão 1.15, o kubeadm pode atualizar quase todos os certificados do plano de controle com um comando
kubeadm alpha certs renew all
Este comando renova todos os certificados no diretório / etc / kubernetes, mesmo se eles já tiverem expirado e tudo estiver quebrado.
Somente o certificado kubelet não será atualizado - esse é o que está no arquivo
/etc/kubernetes/kubelet.conf
!
Atualização: o kubeadm, a partir da versão 1.17, inclui em todos os nós (mesmo no primeiro assistente em que o kubeadm init foi executado) a renovação automática do certificado culet. A verificação é muito simples - em /etc/kubernetes/kubelet.conf
caminho para o arquivo /var/lib/kubelet/pki/kubelet-client-current.pem
será indicado no campo de certificado do cliente
Para renovar este certificado, use o comando create user account
kubeadm alpha kubeconfig user --client-name system:node:kube.slurm.io --org system:nodes > /etc/kubernetes/kubelet.conf
Se o sistema tiver uma conta de usuário, este comando atualizará o certificado para esta conta. Não se esqueça de especificar o nome do host correto na opção
--client-name
, você pode
--client-name
nome
--client-name
host no campo Assunto de um certificado existente:
shcert /etc/kubernetes/kubelet.conf
E, é claro, após atualizar os certificados, é necessário reiniciar todos os componentes do plano de controle, reiniciar o nó inteiro ou parar os contêineres com etcd, api, controller-manager e scheduler com o
docker stop
e, em seguida, reiniciar o kubelet
systemctl restart kubelet
.
Se o cluster tiver uma versão antiga: 1.13 ou menos, ele simplesmente não funcionará para atualizar o kubeadm para a 1.15, pois ele puxa as dependências kubelet e kubernetes-cni, o que pode causar problemas, pois o desempenho dos componentes do cluster difere nas versões em mais de um. estágio, não garantido. A maneira mais fácil de sair dessa situação é instalar o kubeadm em outra máquina, pegar o arquivo binário
/usr/bin/kubeadm
, copiá-lo para os nós principais do cluster falecido e usá-lo apenas para renovar certificados. E depois que o cluster tiver sido revitalizado, atualize-o passo a passo usando métodos regulares, instalando o kubeadm uma versão mais nova a cada vez.
E, finalmente, a partir da versão 1.15, o kubeadm aprendeu a renovar todos os certificados ao atualizar um cluster com o comando
kubeadm upgrade
. Portanto, se você atualizar regularmente seu cluster pelo menos uma vez por ano, seus certificados sempre serão válidos.
Mas se o cluster não estiver instalado usando o kubeadm, você terá que abrir o openssl e renovar todos os certificados individualmente.
O problema é que os certificados contêm campos estendidos e diferentes ferramentas de instalação de cluster podem adicionar seu próprio conjunto de campos. Além disso, os nomes desses campos na configuração openssl e na saída do conteúdo do certificado estão correlacionados, mas fracamente. É necessário pesquisar e selecionar no Google.
Vou dar um exemplo de configuração para o openssl, em seções separadas, cujos atributos estendidos são descritos, específicos para cada tipo de certificado. Iremos nos referir à seção correspondente ao criar e assinar o csr. Essa configuração foi usada para revitalizar o cluster estabelecido há um ano pelo fazendeiro.
openssl.cnf [req] distinguished_name = req_distinguished_name req_extensions = v3_req [v3_req] keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [client] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [apiproxyclient] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth [etcd] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [api] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = ec2-us-east-1-1a-c1-master-2 DNS.2 = ec2-us-east-1-1a-c1-master-3 DNS.3 = ec2-us-east-1-1a-c1-master-1 DNS.4 = localhost DNS.5 = kubernetes DNS.6 = kubernetes.default DNS.7 = kubernetes.default.svc DNS.8 = kubernetes.default.svc.cluster.local IP.1 = 10.0.0.109 IP.2 = 10.0.0.159 IP.3 = 10.0.0.236 IP.4 = 127.0.0.1 IP.5 = 10.43.0.1
Atributos reais e nomes adicionais no certificado podem ser visualizados usando o comando
openssl x509 -in cert.crt -text
Ao renovar o certificado para a API do servidor, tive um problema: o certificado atualizado não funcionou. A solução foi emitir um certificado válido por 1 ano no passado.
No openssl, você não pode emitir um certificado válido no passado com um comando simples, o código afirma estritamente que o certificado é válido apenas a partir do momento atual. Mas você pode voltar no tempo localmente usando a biblioteca libfaketime
yum install libfaketime LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req ...
Emitimos certificados estendidos de acordo com o seguinte algoritmo:
Criamos um CSR usando um certificado existente, especificamos a seção desejada com uma lista de atributos avançados no arquivo de configuração:
openssl x509 -x509toreq -in "node.cert" -out "node.csr" -signkey "node.key" -extfile "openssl.cnf" -extensions client
Assinamos com o certificado raiz correspondente, alterando o tempo há 1 ano e especificando a seção desejada com uma lista de atributos avançados no arquivo de configuração
LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req -days 36500 -in "node.csr" -CA "kube-ca.pem" -CAkey "kube-ca-key.pem" -CAcreateserial -out "node.new.cert" -extfile "openssl.cnf" -extensions client
Verificamos os atributos e reiniciamos os componentes do plano de controle.
Sergey Bondarev,
Professor Slurm
slurm.io