Resolver problemas de sincronização de configurações com o cluster

Nesta página, mostramos como resolver problemas de sincronização de configurações com o cluster.

Resolver erros do KNV 2009

Os erros KNV2009 indicam que o Config Sync falhou ao sincronizar algumas configurações com o cluster. As seções a seguir explicam algumas das causas mais comuns e como resolvê-las.

É proibida a operação em determinados recursos

Como você precisa conceder o RBAC aos objetos RepoSync, talvez as permissões necessárias para aplicar recursos estejam faltando.

Você pode verificar se as permissões estão ausentes recebendo o status do recurso RepoSync:

kubectl get reposync repo-sync -n NAMESPACE -o yaml

Substitua NAMESPACE pelo namespace em que você criou seu repositório de namespace.

Também é possível usar o comando nomos status

Se as mensagens a seguir aparecerem no status, significa que o reconciliação em NAMESPACE não tem a permissão necessária para aplicar o recurso:

KNV2009: deployments.apps "nginx-deployment" is forbidden: User "system:serviceaccount:config-management-system:ns-reconciler-default" cannot get resource "deployments" in API group "apps" in the namespace "default"

Para corrigir esse problema, é preciso declarar uma configuração RoleBinding que conceda à conta de serviço a permissão do reconciliador para gerenciar o recurso com falha nesse namespace. Os detalhes sobre como adicionar um RoleBinding estão incluídos em Configurar a sincronização de vários repositórios.

Esse problema também pode afetar objetos RootSync se você tiver usado spec.override.roleRefs para mudar os papéis concedidos ao objeto RootSync. Se você não tiver definido esse campo, os objetos RootSync vão receber o papel cluster-admin por padrão.

O recurso etcd excede o limite de tamanho de objeto

Se você receber o seguinte erro quando um reconciliador tentar aplicar configurações ao cluster, o objeto ResourceGroup vai exceder o limite de tamanho de objeto etcd:

KNV2009: too many declared resources causing ResourceGroup.kpt.dev, config-management-system/root-sync failed to be applied: task failed (action: "Inventory", name: "inventory-add-0"): Request entity too large: limit is 3145728. To fix, split the resources into multiple repositories.

Recomendamos dividir o repositório do Git em vários repositórios. Se não for possível dividir o repositório do Git porque o objeto já é muito grande e as mudanças não estão sendo persistidas, você poderá configurar o RootSync ou RepoSync para desativar temporariamente a gravação do status do objeto no ResourceGroup. Para isso, defina o campo .spec.override.statusMode do objeto RootSync ou RepoSync como disabled. Ao fazer isso, o Config Sync interromperá a atualização do status dos recursos gerenciados no objeto ResourceGroup. Essa ação reduz o tamanho do objeto ResourceGroup. No entanto, não é possível conferir o status dos recursos gerenciados de nomos status ou gcloud alpha anthos config sync.

Se nenhum erro do objeto RootSync ou RepoSync for exibido, os objetos da sua fonte de verdade foram sincronizados com o cluster. Para verificar se o recurso ResourceGroup excede o limite de tamanho do objeto etcd, verifique o status do recurso ResourceGroup e o registro do controlador ResourceGroup:

  1. Verifique o status do ResourceGroup:

    • Para verificar o objeto RootSync, execute o comando a seguir.

      kubectl get resourcegroup root-sync -n config-management-system
      
    • Para verificar o objeto RepoSync, execute o comando a seguir.

      kubectl get resourcegroup repo-sync -n NAMESPACE
      

      Substitua NAMESPACE pelo namespace em que você criou seu repositório de namespace.

    A resposta será semelhante a:

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    Se o valor da coluna RECONCILING for True, significa que o recurso ResourceGroup ainda está fazendo a reconciliação.

  2. Verifique os registros do controlador ResourceGroup:

    kubectl logs deployment resource-group-controller-manager -c manager -n resource-group-system
    

    Se você encontrar um erro semelhante ao exemplo a seguir na saída, o recurso ResourceGroup é muito grande e excede o limite de tamanho de objeto etcd:

    "error":"etcdserver: request is too large"
    

Para evitar que o ResourceGroup seja muito grande, reduza o número de recursos no seu repositório Git. É possível dividir um repositório raiz em vários repositórios raiz.

Tempo limite de reconciliação de aplicação da dependência

Se você estava sincronizando objetos com dependências, talvez receba um erro semelhante ao exemplo a seguir quando o reconciliador tentar aplicar objetos com a anotação config.kubernetes.io/depends-on ao cluster:

KNV2009: skipped apply of Pod, bookstore/pod4: dependency apply reconcile timeout: bookstore_pod3__Pod  For more information, see https://g.co/cloud/acm-errors#knv2009

Esse erro significa que o objeto de dependência não reconciliou dentro do tempo limite padrão de reconciliação de cinco minutos. O Config Sync não pode aplicar o objeto dependente porque com a anotação config.kubernetes.io/depends-on o Config Sync só aplica objetos na ordem que você quer. É possível modificar o tempo limite de reconciliação padrão para um tempo maior, configurando spec.override.reconcileTimeout.

Também é possível que a dependência seja reconciliada após a tentativa inicial de sincronização. Nesse caso, a dependência precisa ser detectada como reconciliada na próxima tentativa de repetição de sincronização, desbloqueando a aplicação de dependências. Quando isso acontece, o erro pode ser relatado brevemente e removido. Aumentar o tempo limite de reconciliação pode ajudar a evitar que o erro seja informado de maneira intermitente.

As informações do inventário são nulas

Se você receber o seguinte erro quando o reconciliador tentar aplicar configurações ao cluster, é provável que o inventário não tenha recursos ou o manifesto tenha uma anotação não gerenciada:

KNV2009: inventory info is nil\n\nFor more information, see https://g.co/cloud/acm-errors#knv2009

Para resolver esse problema, tente o seguinte:

  1. Evite configurar sincronizações em que todos os recursos tenham a anotação configmanagement.gke.io/managed: disabled. Para isso, garanta que pelo menos um recurso seja gerenciado pelo Config Sync.
  2. Adicione a anotação configmanagement.gke.io/managed: disabled somente após concluir uma sincronização inicial do recurso sem essa anotação.

Vários modelos de objeto de inventário

Se você receber o seguinte erro quando o reconciliador tentar aplicar configurações ao cluster, é provável que você tenha uma configuração de inventário gerada por kpt na fonte da verdade, por exemplo, um repositório Git:

KNV2009: Package has multiple inventory object templates.  The package should have one and only one inventory object template.   For more information, see https://g.co/cloud/acm-errors#knv2009

O problema acontece porque o Config Sync gerencia a própria configuração de inventário. Para resolver esse problema, exclua a configuração do inventário na sua fonte de verdade.

Não é possível fazer mudanças em campos imutáveis

Não é possível alterar nenhum campo imutável em uma configuração mudando o valor na fonte da verdade. Tentar fazer essa mudança causa um erro semelhante ao seguinte:

KNV2009: failed to apply RESOURCE: admission webhook "deny-immutable-field-updates.cnrm.cloud.google.com" denied the request: cannot make changes to immutable field(s):

Se você precisar atualizar um campo imutável, exclua manualmente o objeto do cluster. O Config Sync pode recriar o objeto com o novo valor do campo.

Falha na descoberta da API

Se você receber uma mensagem de erro semelhante a esta, talvez esteja enfrentando um erro de descoberta de API:

KNV2002: API discovery failed: APIServer error: unable to retrieve the complete list of server APIs: external.metrics.k8s.io/v1beta1: received empty response for: external.metrics.k8s.io/v1beta1

O Config Sync usa a descoberta da API Kubernetes para procurar quais recursos são compatíveis com o cluster. Isso permite que o Config Sync valide os tipos de recurso especificados na sua origem e observe se há mudanças nesses recursos no cluster.

Antes da versão 1.28 do Kubernetes, sempre que um back-end do APIService estava inativo ou retornava um resultado de lista vazio, a API Discovery falhava, causando erros no Config Sync e em vários outros componentes do Kubernetes. Muitos back-ends comuns do APIService não têm alta disponibilidade. Portanto, isso pode acontecer com relativa frequência, apenas atualizando o back-end ou reprogramando-o para outro nó.

Exemplos de back-ends do APIService com uma única réplica incluem metrics-server e custom-metrics-stackdriver-adapter. Alguns back-ends do APIService sempre retornam resultados de lista vazios, como custom-metrics-stackdriver-adapter. Outro motivo comum de falha na descoberta de API é o uso de webhooks inativos.

Depois da versão 1.28 do Kubernetes, com o recurso de descoberta agregada ativado, um back-end do APIService inoperante não causa mais erros não tratados. Em vez disso, o grupo de recursos processado por esse APIService é mostrado como não tendo recursos. Isso permite que a sincronização continue, desde que o recurso com problemas não seja especificado na fonte.

Autocorreção atrasada

A autocorreção observa recursos gerenciados, detecta desvios da fonte da verdade e reverte esse desvio.

A autocorreção é pausada enquanto a sincronização está sendo tentada. Esse comportamento significa que a autocorreção pode ser atrasada, especialmente se houver erros de sincronização que impeçam a conclusão do reconciliador. Para reativar a autocorreção, corrija todos os erros de sincronização informados.

Alto número de solicitações da API Kubernetes

O Config Sync usa uma estratégia de várias instâncias para escalonar e isolar locatários e domínios de falha. Por isso, cada RootSync e RepoSync recebe a própria instância de reconciliação. Além de sincronizar sempre que mudanças são feitas na fonte, cada instância de reconciliador também sincroniza periodicamente como parte do comportamento de autocorreção para reverter as mudanças perdidas pela remediação de desvios ativos. Quando você adiciona objetos RootSync ou RepoSync, isso causa um aumento linear no número de solicitações de API feitas pelos reconciliadores que sincronizam recursos com o Kubernetes. Portanto, se você tiver muitos objetos RootSync e RepoSync, isso poderá causar uma carga de tráfego significativa na API Kubernetes.

Para realizar a sincronização, o Config Sync usa a aplicação do lado do servidor. Isso substitui o fluxo normal de solicitações GET e PATCH por uma única solicitação PATCH, reduzindo o número total de chamadas de API, mas aumentando o número de chamadas PATCH. Isso garante que as mudanças feitas estejam corretas, mesmo quando a versão do grupo de recursos na origem não corresponder à versão padrão do grupo de recursos no cluster. No entanto, é possível que você veja solicitações PATCH no registro de auditoria, mesmo quando não houve nenhuma mudança na origem ou desvio do estado desejado. Isso é normal, mas pode gerar surpresa.

Quando a sincronização apresentar um erro, ela será repetida até ser concluída. No entanto, se isso exigir interação humana, o Config Sync poderá apresentar erros e tentar novamente por um tempo, aumentando a quantidade de solicitações feitas à API Kubernetes. As novas tentativas são feitas de maneira exponencial, mas se muitos objetos RootSync ou RepoSync falharem na sincronização ao mesmo tempo, isso poderá causar uma carga de tráfego significativa na API Kubernetes.

Para minimizar esses problemas, tente uma das seguintes opções:

  • Corrija erros de configuração rapidamente para que eles não se acumulem.
  • Combine vários objetos RootSync ou RepoSync para reduzir o número de reconciliadores que fazem solicitações de API Kubernetes.

A desinstalação do KubeVirt é bloqueada por finalizadores.

O KubeVirt é um pacote do Kubernetes que usa vários finalizadores, exigindo uma ordem de exclusão precisa para facilitar a limpeza. Se os objetos do KubeVirt forem excluídos na ordem errada, a exclusão de outros objetos do KubeVirt poderá parar ou deixar de responder indefinidamente.

Se você tentou desinstalar o KubeVirt e ele foi bloqueado, siga as instruções para excluir o KubeVirt manualmente.

Para atenuar esse problema no futuro, declare dependências entre objetos de recurso para garantir que eles sejam excluídos na ordem de dependência inversa.

Exclusão de objetos bloqueada por finalizadores

Os finalizadores do Kubernetes são entradas de metadados que informam ao Kubernetes que não é permitido remover um objeto até que um controlador específico tenha feito a limpeza. Isso pode causar falhas na sincronização ou na reconciliação se as condições de limpeza não forem atendidas ou se o controlador que executa a limpeza para esse recurso estiver com problemas ou tiver sido excluído.

Para atenuar esse problema, identifique qual recurso ainda está sendo finalizado e qual controlador precisa fazer a limpeza.

Se o controlador não estiver em bom estado, a correção da causa raiz permitirá que a limpeza do recurso seja concluída, desbloqueando a remoção do objeto.

Se o controlador estiver em bom estado, ele terá aplicado uma condição de status ao objeto que está sendo excluído para explicar por que a limpeza foi interrompida. Caso contrário, verifique os registros do controlador para encontrar indicações da causa raiz.

Muitas vezes, um objeto que não pode ser excluído é uma indicação de que os objetos foram excluídos na ordem errada. Para evitar esse tipo de problema no futuro, declare dependências entre objetos de recurso para garantir que eles sejam excluídos na ordem inversa de dependência.

Os campos de ResourceGroup continuam mudando

Quando a sincronização é tentada, o inventário é atualizado para mudar o status do recurso para "pendente". Quando a sincronização falha, o inventário é atualizado para mudar o status do recurso para "falha". Quando a sincronização é repetida após uma falha, esse padrão se repete, causando atualizações periódicas no inventário. Isso faz com que o ResourceGroup resourceVersion aumente a cada atualização e o status de sincronização mude de um lado para o outro. Isso é normal, mas pode gerar surpresa.

A falha na sincronização pode ser causada por vários problemas. Uma das causas mais comuns é permissões insuficientes para gerenciar os recursos especificados na origem. Para corrigir esse erro, adicione as RoleBindings ou ClusterRoleBindings adequadas para conceder a permissão RepoSync ou RootSync ao reconciliador para gerenciar os recursos que não estão sincronizando.

A aplicação no servidor não remove nem reverte campos não especificados na origem

O Config Sync usa a aplicação do lado do servidor para aplicar manifestos da origem ao Kubernetes. Isso é necessário para permitir que outros controladores gerenciem os campos metadata e spec. Um exemplo disso é o escalonador automático horizontal de pods, que atualiza o número de réplicas em uma implantação. Por isso, o Config Sync só gerencia campos especificados no manifesto de origem. Isso tem o efeito colateral de que, ao adotar objetos de recursos, os campos não especificados na origem não são alterados, o que pode fazer com que a configuração mesclada seja inválida ou incorreta.

Para evitar esse problema ao adotar um recurso, use os mesmos campos na fonte durante a adoção inicial e mude os campos na fonte após a sincronização. Assim, o Config Sync remove corretamente os campos aplicados anteriormente e os substitui pelos novos campos da fonte. Outra maneira de evitar esse problema é excluir o recurso do cluster primeiro e permitir que o Config Sync aplique a nova versão.

A seguir