Renovar manualmente os certificados de cluster expirados

Neste documento, descrevemos como renovar manualmente os certificados expirados para seu GKE em Bare Metal. Os certificados do Transport Layer Security (TLS) são usados pelos componentes do plano de controle do GKE em Bare Metal. Quando esses certificados expiram, sua capacidade de gerenciar cargas de trabalho e ciclos de vida de clusters é bloqueada até que eles possam ser renovados. Para mais informações sobre o impacto dos certificados expirados, consulte Expiração de certificados.

Por padrão, os certificados TLS têm um período de validade de um ano. O GKE em Bare Metal renova esses certificados automaticamente durante upgrades de cluster e quando ocorre a alternância de autoridades certificadoras. Recomendamos que você faça upgrade dos clusters regularmente para garantir a segurança e o suporte deles, além de evitar que os certificados TLS expirem.

Erros causados pela expiração do certificado

Se os certificados TLS no cluster expirarem, os controladores principais não poderão estabelecer conexões TLS com o servidor da API Kubernetes. Essa falta de conectividade causa os seguintes erros:

  • Unable to connect to the server: x509: Unable to connect to the server

    Quando você usa kubectl para receber os nós do cluster, a resposta inclui um erro que faz referência à expiração do certificado:

    kubectl get nodes --kubeconfig KUBECONFIG_PATH
    

    Substitua KUBECONFIG_PATH pelo caminho para o arquivo kubeconfig do cluster.

    Quando os certificados expirarem, a resposta será semelhante ao seguinte:

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • could not connect: x509 ou rejected connection

    Os certificados expirados bloqueiam o acesso ao cluster do etcd porque os pares não podem se comunicar entre si. Os registros do etcd podem conter entradas de erro como as abaixo:

    W | rafthttp: health check for peer 6221a1d241bb2d0a could not connect: x509: certificate
    has expired or is not yet valid
    I | embed: rejected connection from "10.200.0.4:46108" (error "remote error: tls: bad
    certificate", ServerName "")
    

Verificar os prazos de validade do certificado

Esta seção tem instruções para verificar os prazos de validade dos certificados usados pelo cluster. Siga as etapas abaixo em cada nó do plano de controle.

Para verificar os prazos de validade do certificado:

  1. Faça login em uma das máquinas de nó do plano de controle e execute o seguinte comando:

    sudo kubeadm certs check-expiration
    

    A saída do comando lista os certificados criados por kubeadm para os componentes do plano de controle e a expiração deles:

    CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
    admin.conf                 Nov 28, 2021 19:09 UTC   53m                                     no
    apiserver                  Nov 28, 2021 19:09 UTC   53m             ca                      no
    apiserver-etcd-client      Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    apiserver-kubelet-client   Nov 28, 2021 19:09 UTC   53m             ca                      no
    controller-manager.conf    Nov 28, 2021 19:09 UTC   53m                                     no
    etcd-healthcheck-client    Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-peer                  Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    etcd-server                Nov 28, 2021 19:09 UTC   53m             etcd-ca                 no
    front-proxy-client         Nov 28, 2021 19:09 UTC   53m             front-proxy-ca          no
    scheduler.conf             Nov 28, 2021 19:09 UTC   53m                                     no
    
    CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
    ca                      Nov 26, 2031 18:06 UTC   9y              no
    etcd-ca                 Nov 26, 2031 18:06 UTC   9y              no
    front-proxy-ca          Nov 26, 2031 18:06 UTC   9y              no
    
  2. Execute o seguinte comando para verificar os prazos de validade dos certificados kubelet:

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    A resposta para cada comando é semelhante à seguinte saída:

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

    Se todos os nós do plano de controle tiverem sido inicializados ao mesmo tempo, os prazos de validade do certificado serão de minutos em minutos. Essa relação de tempo se aplica a todos os nós do plano de controle. É possível verificar os tempos de expiração executando os comandos anteriores em cada nó do plano de controle.

  3. Execute o seguinte comando na estação de trabalho do administrador para verificar o prazo de validade do certificado do cliente no arquivo kubeconfig do cluster:

    grep 'client-certificate-data' KUBECONFIG_PATH | \
        awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    

    A resposta é parecida com esta:

    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    
  4. Execute o seguinte comando para procurar a validade do certificado kubeconfig do cluster no cluster de administrador:

    kubectl get secret/CLUSTER_NAME-kubeconfig -n CLUSTER_NAMESPACE -o --kubeconfig=ADMIN_KUBECONFIG jsonpath='{.data.value}' | base64 --decode | grep client-certificate-data | awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
    
    Validity
        Not Before: Sep 17 22:27:53 2021 GMT
        Not After : Sep 17 22:33:16 2022 GMT
    

    O certificado kubeconfig no cluster de administrador e o certificado no arquivo kubeconfig da estação de trabalho do administrador são os mesmos. Portanto, a saída desse comando e do comando da etapa anterior precisam ser iguais.

Renovar certificados manualmente

Para renovar manualmente os certificados TLS de um cluster, siga as instruções nas seções a seguir.

Renovar certificados em cada nó do plano de controle

Siga estas etapas em cada nó do plano de controle do cluster afetado:

  1. Faça backup da pasta /etc/kubernetes.

  2. Execute o seguinte comando kubeadm para renovar todos os certificados:

    O comando renova os certificados usando as autoridades certificadoras (CAs, na sigla em inglês) atuais na máquina.

    sudo kubeadm certs renew all
    

    A resposta ao comando será semelhante ao seguinte exemplo:

    certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
    certificate for serving the Kubernetes API renewed
    certificate the apiserver uses to access etcd renewed
    certificate for the API server to connect to kubelet renewed
    certificate embedded in the kubeconfig file for the controller manager to use renewed
    certificate for liveness probes to healthcheck etcd renewed
    certificate for etcd nodes to communicate with each other renewed
    certificate for serving etcd renewed
    certificate for the front proxy client renewed
    certificate embedded in the kubeconfig file for the scheduler manager to use renewed
    
  3. Verifique se os certificados têm um novo expiry time executando o seguinte comando:

    sudo kubeadm certs check-expiration
    
  4. Reinicie os contêineres com os seguintes comandos:

    Nem todos os componentes do plano de controle são compatíveis com a atualização dinâmica de certificados. Portanto, nesta etapa, os contêineres kube-apiserver, kube-scheduler, kube-controller-manager e etcd são reiniciados para coletar os certificados renovados.

    Repita as seguintes etapas para cada um dos quatro contêineres:

    1. Encontre o ID de cada contêiner:

      sudo crictl ps | grep CONTAINER_NAME
      

      Substitua CONTAINER_NAME pelo nome dos seguintes contêineres: kube-apiserver, kube-scheduler, kube-controller-manager ou etcd (não etcd-defrag).

      A resposta é semelhante ao seguinte:

      c331ade490cb6       28df10594cd92      26 hours ago       Running          kube-apiserver ...
      

      O ID do contêiner é o valor na primeira coluna.

    2. Interrompa cada contêiner:

      sudo crictl stop CONTAINER_ID
      

      Substitua CONTAINER_ID pelo ID do contêiner da etapa anterior.

      Quando o contêiner interrompido é encerrado, o kubelet cria um novo no lugar e exclui o interrompido. Se você encontrar um erro, como context deadline exceeded (código de erro DeadlineExceeded), execute novamente o comando.

Verificar se a conectividade foi restaurada

A esta altura, os certificados do kubeadm precisam ser renovados em todos os nós do plano de controle. Se você estiver renovando os certificados expirados, siga a etapa a seguir.

  • Para verificar a conexão com o servidor da API Kubernetes, execute o seguinte comando kubectl em qualquer nó do plano de controle:

    kubectl get nodes --kubeconfig=/etc/kubernetes/admin.conf
    

A resposta retornará a lista de nós do cluster. Se os certificados forem renovados corretamente, nenhum erro de TLS ou certificado será retornado.

Substituir o arquivo kubeconfig do cluster

Para substituir o arquivo kubeconfig do cluster por um que tenha os certificados renovados, siga estas etapas:

  1. Para criar o novo arquivo kubeconfig, execute o seguinte comando kubectl na estação de trabalho do administrador:

    kubectl --kubeconfig="ADMIN_KUBECONFIG" get secret/CLUSTER_NAME-kubeconfig  \
        -n "CLUSTER_NAMESPACE"  -o jsonpath='{.data.value}'  | base64 --decode > new_kubeconfig.conf
    

    Substitua:

    • ADMIN_KUBECONFIG: o caminho para o arquivo kubeconfig do cluster de administrador.

    • CLUSTER_NAME: o nome do cluster para o qual você está renovando os certificados.

    • CLUSTER_NAMESPACE: o namespace do cluster para o qual você está renovando os certificados.

    O arquivo new_kubeconfig.conf contém os dados atualizados do certificado.

  2. Verifique se o novo kubeconfig funciona executando qualquer comando kubectl usando as novas credenciais:

    kubectl get nodes --kubeconfig new_kubeconfig.conf
    
  3. Substitua o conteúdo do antigo arquivo kubeconfig salvo no diretório do cluster na estação de trabalho de administrador pelo conteúdo do novo arquivo kubeconfig new-kubeconfig.conf.

    Por padrão, o caminho para o arquivo de configuração do cluster é bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig.

Verifique os certificados do kubelet e reinicie o etcd-defrag

Para concluir manualmente o processo de renovação dos certificados do cluster, execute as etapas a seguir em cada nó do plano de controle:

  1. Faça login no nó do plano de controle e verifique o cliente do kubelet e o expiry time do certificado. Para isso, execute os seguintes comandos:

    Os certificados do kubelet são alternados automaticamente, desde que o plano de controle esteja acessível. O período de renovação automática dos certificados do kubelet é menor que o período de validade dos certificados do componente do plano de controle. Portanto, é provável que os certificados do kubelet tenham sido renovados anteriormente

    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2
    sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
    

    A saída de qualquer um dos comandos será parecida com esta:

    Validity
        Not Before: Nov 28 18:04:57 2022 GMT
        Not After : Nov 28 19:04:57 2023 GMT
    
  2. Use o seguinte comando para reiniciar o contêiner etcd-defrag:

    O contêiner etcd-defrag usa o certificado do cliente apiserver-etcd para se comunicar com o etcd e precisa ser reiniciado a fim de coletar os certificados atualizados.

    kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
    

Você concluiu as etapas manuais para renovar os certificados do cluster. Verifique se todos os pods estão sendo executados corretamente e se nenhum erro de TLS é relatado para os contêineres do plano de controle.