Solucionar problemas de erros de UpgradeFailed devido a falhas de desalojamento causadas pelos PDBs.

Resumo

Este artigo explica como identificar e resolver erros UpgradeFailed decorrentes de falhas de despejo causadas por PDBs (Orçamentos de Interrupção de Pod) que ocorrem quando você tenta atualizar um cluster do AKS (Serviço de Kubernetes do Azure).

Pré-requisitos

Este artigo requer a CLI do Azure versão 2.67.0 ou posterior. Para localizar o número da versão, execute az --version. Se você precisar instalar ou atualizar CLI do Azure, consulte Como instalar o CLI do Azure.

Para obter informações mais detalhadas sobre o processo de atualização, consulte a seção "Atualizar um cluster do AKS" em Atualizar um cluster do AKS (Serviço de Kubernetes do Azure).

Dica

Antes de iniciar uma atualização do AKS, execute a verificação de preparação para atualização no portal do Azure:

Cluster do AKS>Configurações>Atualizações>Versão de atualização

Depois de selecionar a versão do Kubernetes de destino, selecione Verificar ao lado de Atualizar preparação. Essa pré-validação pode identificar possíveis impedimentos à atualização, incluindo configurações de PDB (orçamento de indisponibilidade de pods) que podem impedir a drenagem bem-sucedida dos nós durante a atualização.

Sintomas

Uma operação de atualização de cluster do AKS falha com uma das seguintes mensagens de erro:

  • (Falha na atualização) O esvaziamento node aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx falhou quando a evicção do pod <pod-name> falhou com o erro de muitas solicitações. Esse erro geralmente é causado por um Pod Disruption Budget (PDB) restritivo. Consulte https://aka.ms/aks/debugdrainfailures. Erro original: Não é possível remover o pod, pois isso violaria o orçamento de interrupção do pod. Informações de debug do PDB: <namespace>/<pod-name> bloqueado pelo PDB <pdb-name> com 0 pods não prontos.

  • Código: UpgradeFailed
    Mensagem: Falha ao esvaziar o nó aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx ao remover o pod <pod-name> devido ao erro de Muitas Solicitações. Esse erro geralmente é causado por um Pod Disruption Budget (PDB) restritivo. Consulte https://aka.ms/aks/debugdrainfailures. Erro original: Não é possível remover o pod, pois isso violaria o orçamento de interrupção do pod. Informações de debug do PDB: <namespace>/<pod-name> bloqueado pelo PDB <pdb-name> com 0 pods não prontos.

Motivo

Este erro ocorre se um pod estiver protegido pela política de Pod Disruption Budget (PDB). Nessa situação, o pod resiste à drenagem. Após várias tentativas, a operação de atualização falha, e o cluster ou pool de nós entra em um estado Failed.

Verifique a configuração do PDB: valor ALLOWED DISRUPTIONS. O valor deve ser 1 ou maior. Para obter mais informações, consulte Planejar a disponibilidade usando orçamentos de interrupção de pod. Por exemplo, você pode verificar a carga de trabalho e seu PDB da seguinte maneira. Você deve observar que a ALLOWED DISRUPTIONS coluna não permite nenhuma interrupção. Se o valor ALLOWED DISRUPTIONS for 0, os pods não serão removidos e a drenagem do nó falhará durante o processo de atualização.

$ kubectl get deployments.apps nginx
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     2            2           62s

$ kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
nginx-7854ff8877-gbr4m   1/1     Running   0          68s
nginx-7854ff8877-gnltd   1/1     Running   0          68s

$ kubectl get pdb
NAME        MIN AVAILABLE   MAX UNAVAILABLE   ALLOWED DISRUPTIONS   AGE
nginx-pdb   2               N/A               0                     24s

Você também pode verificar se há entradas em eventos do Kubernetes usando o comando kubectl get events | grep -i drain. Uma saída semelhante mostra a mensagem "Remoção bloqueada por muitas solicitações (geralmente um pdb)":

$ kubectl get events | grep -i drain
LAST SEEN   TYPE      REASON                    OBJECT                                   MESSAGE
(...)
32m         Normal    Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Draining node: aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx
2m57s       Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
12m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
32m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
32m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>
31m         Warning   Drain                     node/aks-<nodepool-name>-xxxxxxxx-vmssxxxxxx   Eviction blocked by Too Many Requests (usually a pdb): <pod-name>

Para resolver o problema, use uma das soluções a seguir.

Solução 1: Habilitar a drenagem de pods

  1. Ajuste o PDB para habilitar a drenagem do pod. Geralmente, a interrupção permitida é controlada pelo parâmetro Min Available / Max unavailable ou Running pods / Replicas. Modifique o parâmetro Min Available / Max unavailable no nível do PDB ou aumente o número de Running pods / Replicas para elevar o valor de Interrupção Permitida para 1 ou mais.

  2. Tente atualizar novamente o cluster do AKS para a mesma versão para a qual você tentou atualizar anteriormente. Esse processo aciona uma reconciliação.

    $ az aks upgrade --name <aksName> --resource-group <resourceGroupName>
    Are you sure you want to perform this operation? (y/N): y
    Cluster currently in failed state. Proceeding with upgrade to existing version 1.28.3 to attempt resolution of failed cluster state.
    Since control-plane-only argument is not specified, this will upgrade the control plane AND all nodepools to version . Continue? (y/N): y
    

Solução 2: Fazer backup, excluir e reimplantar o PDB

Observação

Use essa solução se a edição do recurso PDB não for uma opção viável.

  1. Faça backup dos PDBs executando o seguinte comando:

    kubectl get pdb <pdb-name> -n <pdb-namespace> -o yaml > pdb-name-backup.yamlE

  2. Exclua o PDB executando o seguinte comando:

    kubectl delete pdb <pdb-name> -n <pdb-namespace>

  3. Após a conclusão da nova tentativa de atualização, reimplante o PDB aplicando o arquivo de backup usando o seguinte comando:

    kubectl apply -f pdb-name-backup.yaml.

  4. Tente atualizar o cluster do AKS para a mesma versão novamente para a qual você tentou atualizar anteriormente. Esse processo aciona uma reconciliação.

    $ az aks upgrade --name <aksName> --resource-group <resourceGroupName>
    Are you sure you want to perform this operation? (y/N): y
    Cluster currently in failed state. Proceeding with upgrade to existing version 1.28.3 to attempt resolution of failed cluster state.
    Since control-plane-only argument is not specified, this will upgrade the control plane AND all nodepools to version . Continue? (y/N): y
    

Solução 3: Exclua os pods que você não consegue drenar ou escale a carga de trabalho para zero

  1. Exclua os pods que você não pode drenar.

Observação

Se um Deployment ou StatefulSet cria os pods, um ReplicaSet os controla. Se esse for o caso, talvez seja necessário excluir o Deployment ou StatefulSet, ou reduzir para zero o número de réplicas da carga de trabalho. Antes de fazer essa alteração, faça backup do recurso executando: kubectl get <deployment.apps -or- statefulset.apps> <name> -n <namespace> -o yaml > backup.yaml.

  1. Para reduzir a carga de trabalho, use kubectl scale --replicas=0 <deployment.apps -or- statefulset.apps> <name> -n <namespace>.

  2. Tente atualizar novamente o cluster do AKS para a mesma versão para a qual você tentou atualizar anteriormente. Esse processo aciona uma reconciliação.

    $ az aks upgrade --name <aksName> --resource-group <resourceGroupName>
    Are you sure you want to perform this operation? (y/N): y
    Cluster currently in failed state. Proceeding with upgrade to existing version 1.28.3 to attempt resolution of failed cluster state.
    Since control-plane-only argument is not specified, this will upgrade the control plane AND all nodepools to version . Continue? (y/N): y