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

Esta página mostra como resolver problemas de sincronização de configurações com o cluster.

Resolva problemas de erros KNV 2009

Os erros KNV2009 indicam que o Config Sync não conseguiu sincronizar algumas configurações com o cluster. As secções seguintes explicam algumas das causas mais comuns e como resolvê-las.

A operação em determinados recursos é proibida

Uma vez que tem de conceder RBAC aos objetos RepoSync, pode faltar-lhe as autorizações necessárias para aplicar recursos.

Pode verificar se as autorizações estão em falta obtendo o estado do recurso RepoSync:

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

Substitua NAMESPACE pelo espaço de nomes no qual criou o repositório do espaço de nomes.

Também pode usar o comando nomos status.

Se vir as seguintes mensagens no estado, significa que o reconciliador em NAMESPACE não tem a autorizaçã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 este problema, tem de declarar uma configuração RoleBinding que conceda à conta de serviço do reconciliador autorização para gerir o recurso com falha nesse espaço de nomes. Os detalhes sobre como adicionar uma RoleBinding estão incluídos no artigo Configure a sincronização a partir de vários repositórios.

Este problema também pode afetar objetos RootSync se tiver usado spec.override.roleRefs para alterar as funções concedidas ao objeto RootSync. Se não tiver definido este campo, os objetos RootSync recebem a função cluster-admin por predefinição.

O objeto ResourceGroup excede o limite de tamanho do objeto de etcd

Se receber o seguinte erro quando um reconciliador tenta aplicar configurações ao cluster, o objeto ResourceGroup excede o limite de tamanho do 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 que divida o seu repositório Git em vários repositórios. Se não conseguir dividir o repositório Git porque o objeto já é demasiado grande e as alterações não estão a ser mantidas, pode mitigar o problema configurando o RootSync ou o RepoSync para desativar temporariamente a escrita do estado do objeto no ResourceGroup. Pode fazê-lo definindo o campo .spec.override.statusMode do objeto RootSync ou RepoSync como disabled. Ao fazê-lo, o Config Sync deixa de atualizar o estado dos recursos geridos no objeto ResourceGroup. Esta ação reduz o tamanho do objeto ResourceGroup. No entanto, não pode ver o estado dos recursos geridos a partir de nomos status.

Se não vir nenhum erro do objeto RootSync ou RepoSync, significa que os objetos da sua fonte de informações verdadeiras foram sincronizados com o cluster. Para verificar se o recurso ResourceGroup excede o limite de tamanho do objeto etcd, verifique o estado do recurso ResourceGroup e o registo do controlador ResourceGroup:

  1. Verifique o estado do ResourceGroup:

    • Para verificar o objeto RootSync, execute o seguinte comando:

      kubectl get resourcegroup root-sync -n config-management-system
      
    • Para verificar o objeto RepoSync, execute o seguinte comando:

      kubectl get resourcegroup repo-sync -n NAMESPACE
      

      Substitua NAMESPACE pelo espaço de nomes no qual criou o repositório do espaço de nomes.

    O resultado é semelhante ao seguinte exemplo:

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    Se o valor na coluna RECONCILING for True, significa que o recurso ResourceGroup ainda está a ser reconciliado.

  2. Verifique os registos do controlador ResourceGroup:

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

    Se vir um erro semelhante ao exemplo seguinte no resultado, o recurso ResourceGroup é demasiado grande e excede o etcd limite de tamanho do objeto:

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

Para evitar que o grupo de recursos fique demasiado grande, reduza o número de recursos no seu repositório Git. Pode dividir um repositório raiz em vários repositórios raiz.

Dependency apply reconcile timeout

Se estivesse a sincronizar objetos com dependências, pode receber um erro semelhante ao exemplo seguinte quando o reconciliador tenta 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

Este erro significa que o objeto de dependência não foi reconciliado dentro do limite de tempo de reconciliação predefinido 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 pretendida. Pode substituir o limite de tempo de conciliação predefinido por um período mais longo definindo spec.override.reconcileTimeout.

Também é possível que a dependência seja reconciliada após a conclusão da tentativa de sincronização inicial. Neste caso, a dependência deve ser detetada como reconciliada na próxima tentativa de sincronização, desbloqueando a aplicação de quaisquer dependentes. Quando isto acontece, o erro pode ser comunicado brevemente e, em seguida, removido. Aumentar o tempo limite de conciliação pode ajudar a evitar que o erro seja comunicado intermitentemente.

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

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

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

Para resolver este problema, experimente os seguintes passos:

  1. Evite configurar sincronizações em que todos os recursos têm a anotação configmanagement.gke.io/managed: disabled, garantindo que, pelo menos, um recurso é gerido pelo Config Sync.
  2. Adicione a anotação configmanagement.gke.io/managed: disabled apenas depois de concluir uma sincronização inicial do recurso sem esta anotação.

Vários modelos de objetos de inventário

Se receber o seguinte erro quando o reconciliador tenta aplicar configurações ao cluster, é provável que tenha uma configuração de inventário gerada pelo kpt na fonte de 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 ocorre porque o Config Sync gere a sua própria configuração de inventário. Para resolver este problema, elimine a configuração do inventário na sua fonte de dados fidedigna.

Não é possível fazer alterações a campos imutáveis

Não pode alterar nenhum campo imutável numa configuração alterando o valor na fonte de verdade. A tentativa de fazer essa alteração provoca 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 precisar de alterar um campo imutável, elimine o objeto da sua fonte de dados fidedignos, aguarde que o Config Sync elimine o objeto do cluster e, em seguida, recrie o objeto na sua fonte de dados fidedignos com as atualizações.

Falha na sondagem do estado

Pode autorizar o Config Sync a gerir recursos num espaço de nomes através de um objeto RepoSync. Se este tipo de objeto RepoSync usar um objeto RoleBinding que faça referência a um ClusterRole ou Role personalizado, pode receber a seguinte mensagem de erro da implementação do reconciliador:

KNV2009: polling for status failed: unknown

Para resolver este problema, certifique-se de que os objetos ClusterRole e Role têm, pelo menos, as seguintes autorizações para cada recurso que o objeto RepoSync gere:

  • list
  • watch
  • get
  • patch
  • delete
  • create

Para ver instruções sobre como adicionar estas autorizações, consulte o artigo Crie uma RoleBinding.

Falha na descoberta da API

Se vir uma mensagem de erro semelhante à seguinte, pode estar a ter um erro de deteção 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 deteção da API Kubernetes para procurar os recursos suportados pelo cluster. Isto permite que o Config Sync valide os tipos de recursos especificados na sua origem e monitorize esses recursos para verificar se existem alterações no cluster.

Antes da versão 1.28 do Kubernetes, sempre que um back-end do APIService não estava em bom estado ou devolvia um resultado de lista vazio, a API Discovery falhava, o que fazia com que o Config Sync e vários outros componentes do Kubernetes apresentassem erros. Muitos back-ends de APIService comuns não estão altamente disponíveis, pelo que isto pode acontecer com relativa frequência, apenas atualizando o back-end ou fazendo com que seja reagendado para outro nó.

Alguns exemplos de back-ends APIService com uma única réplica incluem metrics-server e custom-metrics-stackdriver-adapter. Alguns back-ends de APIService devolvem sempre resultados de listas vazias, como custom-metrics-stackdriver-adapter. Outra causa comum de falha na descoberta de APIs são os webhooks não íntegros.

Após a versão 1.28 do Kubernetes, com a funcionalidade Aggregated Discovery ativada, um backend APIService não saudável deixa de causar erros não processados. Em alternativa, o grupo de recursos processado por esse APIService é apresentado como não tendo recursos. Isto permite que a sincronização continue, desde que o recurso não saudável não seja especificado na sua fonte.

Autorreparação atrasada

A autocorreção monitoriza os recursos geridos, deteta o desvio da fonte de informações fidedignas e reverte esse desvio.

A autorrecuperação está pausada enquanto se tenta fazer a sincronização. Este comportamento significa que a autocorreção pode ser atrasada, especialmente se existirem erros de sincronização que impeçam a conclusão do reconciliador. Para reativar a autocorreção, corrija todos os erros de sincronização comunicados.

Número elevado de pedidos da API Kubernetes

O Config Sync usa uma estratégia de várias instâncias para dimensionar e isolar inquilinos e domínios de falhas. Por este motivo, cada RootSync e RepoSync tem a sua própria instância de reconciliação. Além de sincronizar sempre que são feitas alterações à origem, cada instância do reconciliador também sincroniza periodicamente como parte do respetivo comportamento de autocorreção, para reverter quaisquer alterações perdidas pela correção de desvio ativa. Quando adiciona objetos RootSync ou RepoSync, isto provoca um aumento linear no número de pedidos de API feitos pelos reconciliadores que sincronizam recursos com o Kubernetes. Assim, se tiver muitos objetos RootSync e RepoSync, isto pode, por vezes, causar uma carga de tráfego significativa na API Kubernetes.

Para realizar a sincronização, o Config Sync usa o Server-Side Apply. Isto substitui o fluxo normal de pedidos GET e PATCH por um único pedido PATCH, o que reduz o número total de chamadas de API, mas aumenta o número de chamadas PATCH. Isto garante que as alterações feitas estão corretas, mesmo quando a versão do grupo de recursos na origem não corresponde à versão do grupo de recursos predefinida no cluster. No entanto, pode ver pedidos PATCH no registo de auditoria, mesmo quando não houve alterações à origem ou desvio do estado pretendido. Isto é normal, mas pode ser surpreendente.

Quando a sincronização apresenta erros, são feitas novas tentativas até ser bem-sucedida. No entanto, se isto exigir interação humana, a sincronização de configuração pode estar a gerar erros e a tentar novamente durante algum tempo, o que aumenta a quantidade de pedidos feitos à API Kubernetes. As novas tentativas são feitas com um intervalo exponencial, mas, se muitos objetos RootSync ou RepoSync não forem sincronizados em simultâneo, isto pode causar uma carga de tráfego significativa na API Kubernetes.

Para mitigar estes problemas, experimente uma das seguintes opções:

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

A desinstalação do KubeVirt está bloqueada por finalizadores

O KubeVirt é um pacote do Kubernetes que usa vários finalizadores, o que requer uma ordenação precisa da eliminação para facilitar a limpeza. Se os objetos KubeVirt forem eliminados pela ordem errada, a eliminação de outros objetos KubeVirt pode ficar bloqueada ou deixar de responder indefinidamente.

Se tentou desinstalar o KubeVirt e este ficou bloqueado, siga as instruções para eliminar o KubeVirt manualmente.

Para mitigar este problema no futuro, declare dependências entre objetos de recursos para garantir que são eliminados na ordem de dependência inversa.

Eliminação de objetos bloqueada por finalizadores

Os finalizadores do Kubernetes são entradas de metadados que indicam ao Kubernetes que não deve permitir a remoção de um objeto até que um controlador específico tenha realizado a limpeza. Isto pode fazer com que a sincronização ou a conciliação falhem se as condições de limpeza não forem satisfeitas ou se o controlador que realiza a limpeza desse recurso não estiver em bom estado ou tiver sido eliminado.

Para mitigar este problema, identifique que recurso ainda está a ser finalizado e que controlador deve realizar a limpeza.

Se o controlador não estiver em bom estado, a correção da causa principal deve permitir que a limpeza dos recursos seja concluída, desbloqueando a remoção do objeto.

Se o controlador estiver em bom estado, deve ter aplicado uma condição de estado ao objeto que está a ser eliminado para explicar por que motivo a limpeza está parada. Caso contrário, verifique os registos do controlador para ver indicações da causa principal.

Muitas vezes, ter um objeto preso na eliminação é um indicador de que os objetos foram eliminados pela ordem errada. Para evitar este tipo de problema no futuro, declare dependências entre objetos de recursos, para garantir que são eliminados na ordem inversa das dependências.

Os campos ResourceGroup continuam a mudar

Quando se tenta a sincronização, o inventário é atualizado para alterar o estado do recurso para pendente. Quando a sincronização falha, o inventário é atualizado para alterar o estado do recurso para com falhas. Quando a sincronização é repetida após a falha, este padrão repete-se, o que provoca atualizações periódicas ao inventário. Isto faz com que o ResourceGroup resourceVersion aumente com cada atualização e o estado de sincronização alterne entre os estados. Isto é normal, mas pode ser surpreendente.

A falha de sincronização pode ser causada por vários problemas. Um dos motivos mais comuns são as autorizações insuficientes para gerir os recursos especificados na origem. Para corrigir este erro, adicione as RoleBindings ou ClusterRoleBinding adequadas para conceder autorização ao reconciliador RepoSync ou RootSync para gerir os recursos que não estão a ser sincronizados.

O Config Sync não remove nem reverte campos não especificados na origem

O Config Sync usa a opção Server-Side Apply para aplicar manifestos da origem ao Kubernetes. Isto é necessário para permitir que outros controladores geram os campos metadata e spec. Um exemplo disto é o redimensionador automático horizontal de pods, que atualiza o número de réplicas numa implementação. Por este motivo, a sincronização de configuração só gere os campos especificados no manifesto de origem. Isto tem o efeito secundário de que, quando se adotam objetos de recursos existentes, os campos não especificados na origem não são alterados, o que, por vezes, pode fazer com que a configuração unida seja inválida ou incorreta.

Para evitar este problema ao adotar um recurso, use exatamente os mesmos campos na origem quando adotar inicialmente e, em seguida, altere os campos na origem após a sincronização, para que o Config Sync remova corretamente os campos que aplicou anteriormente e os substitua pelos novos campos da origem. Outra forma de evitar este problema é eliminar primeiro o recurso do cluster e permitir que o Config Sync aplique a nova versão.

O Config Sync não retém campos da aplicação do lado do cliente kubectl quando adota objetos

Uma vez que a sincronização de configuração usa a aplicação do lado do servidor, quando a sincronização de configuração adota um objeto que foi originalmente criado com a aplicação do lado do cliente, anula a definição de todos os campos que foram definidos com a aplicação do lado do cliente, mas não declarados na origem.kubectl

Se quiser que esses campos sejam mantidos, use exatamente os mesmos campos na origem quando adotar inicialmente o objeto ou crie o objeto usando o Server-Side Apply.

O que se segue?