Résoudre les problèmes de synchronisation des configurations avec votre cluster

Cette page explique comment résoudre les problèmes de synchronisation des configurations avec votre cluster.

Résoudre les erreurs KNV 2009

Les erreurs KNV2009 indiquent que Config Sync n'a pas réussi à synchroniser certaines configurations avec le cluster. Les sections suivantes expliquent certaines des causes les plus courantes et indiquent comment les résoudre.

Opération interdite sur certaines ressources

Étant donné que vous devez accorder leur RBAC aux objets RepoSync, il est possible qu'ils ne disposent pas des autorisations nécessaires pour appliquer les ressources.

Vous pouvez vérifier que les autorisations manquent en obtenant l'état de la ressource RepoSync :

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

Remplacez NAMESPACE par l'espace de noms dans lequel vous avez créé votre dépôt d'espaces de noms.

Vous pouvez également exécuter la commande nomos status :

Si les messages suivants apparaissent dans l'état, cela signifie que le rapprochement dans NAMESPACE ne dispose pas de l'autorisation nécessaire pour appliquer la ressource :

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"

Pour résoudre ce problème, vous devez déclarer une configuration RoleBinding qui accorde au compte de service l'autorisation de gérer la ressource défaillante dans cet espace de noms. Des informations sur l'ajout d'un objet RoleBinding sont incluses dans la section Configurer la synchronisation à partir de plusieurs dépôts.

Ce problème peut également affecter les objets RootSync si vous avez utilisé spec.override.roleRefs pour modifier les rôles accordés à l'objet RootSync. Si vous n'avez pas défini ce champ, le rôle cluster-admin est attribué par défaut aux objets RootSync.

L'objet ResourceGroup dépasse la limite de taille d'objet etcd.

Si vous recevez l'erreur suivante lorsqu'un rapprochement tente d'appliquer des configurations au cluster, l'objet ResourceGroup dépasse la limite de taille d'objet 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.

Nous vous recommandons de diviser votre dépôt Git en plusieurs dépôts. Si vous ne parvenez pas à scinder le dépôt Git, car l'objet est déjà trop volumineux et les modifications ne sont pas conservées, vous pouvez limiter le problème en configurant RootSync ou RepoSync pour désactiver temporairement l'écriture de l'état d'objet dans ResourceGroup. Pour ce faire, définissez le champ .spec.override.statusMode de l'objet RootSync ou RepoSync sur disabled. Ainsi, Config Sync cesse de mettre à jour l'état des ressources gérées dans l'objet ResourceGroup. Cette action réduit la taille de l'objet ResourceGroup. Cependant, vous ne pouvez pas afficher l'état des ressources gérées à partir de nomos status.

Si vous ne voyez aucune erreur dans l'objet RootSync ou RepoSync, cela signifie que les objets de votre source de vérité ont été synchronisés avec le cluster. Pour vérifier si la ressource ResourceGroup dépasse la limite de taille d'objet etcd, vérifiez à la fois l'état de la ressource ResourceGroup et le journal du contrôleur ResourceGroup :

  1. Vérifiez l'état de ResourceGroup:

    • Pour vérifier l'objet RootSync, exécutez la commande suivante :

      kubectl get resourcegroup root-sync -n config-management-system
      
    • Pour vérifier l'objet RepoSync, exécutez la commande suivante :

      kubectl get resourcegroup repo-sync -n NAMESPACE
      

      Remplacez NAMESPACE par l'espace de noms dans lequel vous avez créé votre dépôt d'espaces de noms.

    Le résultat ressemble à celui de l'exemple ci-dessous.

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    Si la valeur de la colonne RECONCILING est True, cela signifie que la ressource ResourceGroup est encore rapprochée.

  2. Consultez les journaux du contrôleur ResourceGroup :

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

    Si une erreur semblable à l'exemple suivant s'affiche dans le résultat, la ressource ResourceGroup est trop volumineuse et dépasse la limite de taille d'objet etcd :

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

Pour empêcher le ResourceGroup de devenir trop volumineux, réduisez le nombre de ressources de votre dépôt Git. Vous pouvez scinder un dépôt racine en plusieurs dépôts racines.

Expiration du délai de rapprochement des dépendances

Si vous synchronisez des objets avec des dépendances, vous pouvez recevoir une erreur semblable à l'exemple suivant lorsque le rapprochement tente d'appliquer des objets avec l'annotation config.kubernetes.io/depends-on au 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

Cette erreur signifie que l'objet de dépendance n'a pas rapproché le délai de rapprochement par défaut de 5 minutes. Config Sync ne peut pas appliquer l'objet dépendant, car avec l'annotation config.kubernetes.io/depends-on, Config Sync n'applique que les objets dans l'ordre souhaité. Vous pouvez ignorer le délai de rapprochement par défaut en définissant spec.override.reconcileTimeout.

Il est également possible que la dépendance soit résolue une fois la première tentative de synchronisation terminée. Dans ce cas, la dépendance doit être détectée comme réconciliée lors de la prochaine tentative de synchronisation, ce qui débloque l'application de tous les éléments dépendants. Dans ce cas, l'erreur peut être signalée brièvement, puis supprimée. L'allongement du délai d'expiration de la réconciliation peut aider à éviter que l'erreur ne soit signalée de manière intermittente.

Les informations sur l'inventaire sont "nil"

Si vous recevez l'erreur suivante lorsque le rapprochement tente d'appliquer des configurations au cluster, il est probable que votre inventaire ne dispose d'aucune ressource ou que le fichier manifeste comporte une annotation non gérée :

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

Essayez les solutions suivantes pour résoudre ce problème :

  1. Évitez de configurer des synchronisations où toutes les ressources comportent l'annotation configmanagement.gke.io/managed: disabled, en vous assurant qu'au moins une ressource est gérée par Config Sync.
  2. Ajoutez l'annotation configmanagement.gke.io/managed: disabled uniquement après avoir terminé une synchronisation initiale de la ressource sans cette annotation.

Plusieurs modèles d'objets d'inventaire

Si vous recevez l'erreur suivante lorsque le rapprochement tente d'appliquer des configurations au cluster, il est probable que vous disposiez d'une configuration d'inventaire générée par kpt dans la source de vérité, par exemple un dépôt 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

Ce problème se produit car Config Sync gère sa propre configuration d'inventaire. Pour résoudre ce problème, supprimez la configuration d'inventaire de votre source de vérité.

Impossible de modifier des champs immuables

Vous ne pouvez pas modifier un champ immuable dans une configuration en modifiant la valeur de la source de vérité. Toute tentative de modification entraîne une erreur semblable à celle-ci :

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):

Si vous devez modifier un champ immuable, supprimez l'objet de votre source de vérité, attendez que Config Sync le supprime du cluster, puis recréez l'objet dans votre source de vérité avec vos modifications.

Échec de l'interrogation de l'état

Vous pouvez autoriser Config Sync à gérer les ressources d'un espace de noms à l'aide d'un objet RepoSync. Si ce type d'objet RepoSync utilise un objet RoleBinding qui fait référence à un ClusterRole ou Role personnalisé, vous pouvez obtenir le message d'erreur suivant du déploiement du rapprochement :

KNV2009: polling for status failed: unknown

Pour résoudre ce problème, assurez-vous que vos objets ClusterRole et Role disposent au moins des autorisations suivantes pour chaque ressource gérée par l'objet RepoSync :

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

Pour savoir comment ajouter ces autorisations, consultez Créer un RoleBinding.

Échec de la détection de l'API

Si un message d'erreur semblable à celui-ci s'affiche, vous rencontrez peut-être une erreur de découverte d'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

Config Sync utilise la découverte de l'API Kubernetes pour rechercher les ressources compatibles avec le cluster. Cela permet à Config Sync de valider les types de ressources spécifiés dans votre source et de surveiller ces ressources pour détecter les modifications apportées au cluster.

Avant la version 1.28 de Kubernetes, chaque fois qu'un backend APIService était défectueux ou renvoyait un résultat de liste vide, la découverte d'API échouait, ce qui entraînait des erreurs dans Config Sync et plusieurs autres composants Kubernetes. De nombreux services backend APIService courants ne sont pas hautement disponibles. Cela peut donc arriver relativement souvent, simplement en mettant à jour le backend ou en le reprogrammant sur un autre nœud.

metrics-server et custom-metrics-stackdriver-adapter sont des exemples de backends APIService avec un seul réplica. Certains backends APIService renvoient toujours des résultats de liste vides, comme custom-metrics-stackdriver-adapter. Une autre cause fréquente d'échec de la découverte de l'API est l'état non sain des Webhooks.

Après la version 1.28 de Kubernetes, avec la fonctionnalité de découverte agrégée activée, un backend APIService non opérationnel ne provoque plus d'erreurs non traitées. Au lieu de cela, le groupe de ressources géré par cet APIService est indiqué comme ne comportant aucune ressource. Cela permet à la synchronisation de se poursuivre, à condition que la ressource défectueuse ne soit pas spécifiée dans votre source.

Autoréparation différée

L'autoréparation surveille les ressources gérées, détecte la dérive de la source de vérité et l'annule.

La réparation automatique est suspendue pendant la tentative de synchronisation. Ce comportement signifie que l'autoréparation peut être retardée, en particulier s'il existe des erreurs de synchronisation empêchant le reconciler de se terminer. Pour réactiver l'autoréparation, corrigez toutes les erreurs de synchronisation signalées.

Nombre élevé de requêtes d'API Kubernetes

Config Sync utilise une stratégie multi-instances pour mettre à l'échelle et isoler les locataires et les domaines de défaillance. Par conséquent, chaque RootSync et RepoSync dispose de sa propre instance de rapprochement. En plus de la synchronisation à chaque modification de la source, chaque instance de réconciliateur se synchronise également périodiquement dans le cadre de son comportement d'autoréparation, afin de rétablir les modifications manquées par la correction active de la dérive. Lorsque vous ajoutez des objets RootSync ou RepoSync, cela entraîne une augmentation linéaire du nombre de requêtes API effectuées par les rapprochements synchronisant les ressources avec Kubernetes. Par conséquent, si vous avez de nombreux objets RootSync et RepoSync, cela peut parfois entraîner une charge de trafic importante sur l'API Kubernetes.

Pour effectuer la synchronisation, Config Sync utilise l'application côté serveur. Cela remplace le flux de requêtes GET et PATCH normal par une seule requête PATCH, ce qui réduit le nombre total d'appels d'API, mais augmente le nombre d'appels PATCH. Cela permet de s'assurer que les modifications apportées sont correctes, même lorsque la version du groupe de ressources dans la source ne correspond pas à la version par défaut du groupe de ressources sur le cluster. Toutefois, il est possible que des requêtes PATCH s'affichent dans le journal d'audit, même si la source n'a pas été modifiée ou si l'état souhaité n'a pas été modifié. Ce comportement est normal, mais peut être surprenant.

En cas d'erreur de synchronisation, une nouvelle tentative est effectuée jusqu'à ce que la synchronisation réussisse. Toutefois, si cela nécessite une interaction humaine, Config Sync peut générer des erreurs et réessayer pendant un certain temps, ce qui augmente le nombre de requêtes envoyées à l'API Kubernetes. Les nouvelles tentatives sont exponentielles, mais si de nombreux objets RootSync ou RepoSync ne parviennent pas à se synchroniser simultanément, cela peut entraîner une charge de trafic importante sur l'API Kubernetes.

Pour résoudre ces problèmes, essayez l'une des options suivantes :

  • Corrigez rapidement les erreurs de configuration pour éviter qu'elles ne s'accumulent.
  • Combinez plusieurs objets RootSync ou RepoSync pour réduire le nombre de rapprochements qui envoient des requêtes API Kubernetes.

Désinstallation de KubeVirt bloquée par les finaliseurs

KubeVirt est un package Kubernetes qui utilise plusieurs finaliseurs, ce qui nécessite un ordre de suppression précis pour faciliter le nettoyage. Si les objets KubeVirt sont supprimés dans le mauvais ordre, la suppression d'autres objets KubeVirt peut être bloquée ou ne plus répondre indéfiniment.

Si vous avez essayé de désinstaller KubeVirt et que l'opération a été bloquée, suivez les instructions pour supprimer manuellement KubeVirt.

Pour éviter ce problème à l'avenir, déclarez des dépendances entre les objets de ressources afin de vous assurer qu'ils sont supprimés dans l'ordre inverse de leur dépendance.

Suppression d'objets bloquée par les finaliseurs

Les finaliseurs Kubernetes sont des entrées de métadonnées qui indiquent à Kubernetes de ne pas autoriser la suppression d'un objet tant qu'un contrôleur spécifique n'a pas effectué le nettoyage. Cela peut entraîner l'échec de la synchronisation ou de la réconciliation si les conditions de nettoyage ne sont pas remplies ou si le contrôleur qui effectue le nettoyage de cette ressource n'est pas opérationnel ou a été supprimé.

Pour atténuer ce problème, identifiez la ressource qui est encore en cours de finalisation et le contrôleur qui doit effectuer le nettoyage.

Si le contrôleur n'est pas opérationnel, la résolution de la cause première devrait permettre au nettoyage des ressources de se terminer, ce qui débloquera la suppression de l'objet.

Si le contrôleur est sain, il doit avoir appliqué une condition d'état à l'objet en cours de suppression pour expliquer pourquoi le nettoyage est bloqué. Si ce n'est pas le cas, consultez les journaux du contrôleur pour identifier la cause première.

Souvent, un objet qui bloque la suppression indique que les objets ont été supprimés dans le mauvais ordre. Pour éviter ce type de problème à l'avenir, déclarez des dépendances entre les objets de ressources afin de vous assurer qu'ils sont supprimés dans l'ordre inverse des dépendances.

Les champs ResourceGroup continuent de changer

Lors de la tentative de synchronisation, l'état des ressources de l'inventaire est défini sur "En attente". En cas d'échec de la synchronisation, l'inventaire est mis à jour pour modifier l'état de la ressource et le définir sur "Échec". Lorsque la synchronisation est relancée après un échec, ce schéma se répète, ce qui entraîne des mises à jour périodiques de l'inventaire. Le nombre de resourceVersion de ResourceGroup augmente alors à chaque mise à jour, et l'état de synchronisation oscille. Ce comportement est normal, mais peut être surprenant.

L'échec de la synchronisation peut être dû à plusieurs problèmes. L'une des raisons les plus courantes est l'insuffisance des autorisations pour gérer les ressources spécifiées dans la source. Pour corriger cette erreur, ajoutez les RoleBindings ou ClusterRoleBinding appropriés afin d'accorder au réconciliateur RepoSync ou RootSync l'autorisation de gérer les ressources qui ne parviennent pas à se synchroniser.

Config Sync ne supprime ni ne rétablit les champs non spécifiés dans la source.

Config Sync utilise l'application côté serveur pour appliquer les fichiers manifeste de la source à Kubernetes. Cela est nécessaire pour permettre à d'autres contrôleurs de gérer les champs metadata et spec. L'autoscaler horizontal de pods en est un exemple. Il met à jour le nombre d'instances répliquées dans un déploiement. Par conséquent, Config Sync ne gère que les champs spécifiés dans le fichier manifeste source. Cela a pour effet secondaire que lors de l'adoption des objets ressources existants, les champs non spécifiés dans la source ne sont pas modifiés, ce qui peut parfois rendre la configuration fusionnée non valide ou incorrecte.

Pour éviter ce problème lors de l'adoption d'une ressource, utilisez exactement les mêmes champs dans la source lors de l'adoption initiale, puis modifiez les champs de la source après la synchronisation, afin que Config Sync supprime correctement les champs qu'il a précédemment appliqués et les remplace par les nouveaux champs de la source. Pour éviter ce problème, vous pouvez également supprimer d'abord la ressource du cluster et autoriser Config Sync à appliquer la nouvelle version.

Config Sync ne conserve pas les champs de l'application côté client kubectl lors de l'adoption d'objets

Étant donné que Config Sync utilise l'application côté serveur, lorsqu'il adopte un objet qui a été créé à l'origine avec l'application côté client kubectl, il supprime tous les champs qui ont été définis avec l'application côté client, mais qui n'ont pas été déclarés dans la source.

Si vous souhaitez conserver ces champs, utilisez exactement les mêmes champs dans la source lorsque vous adoptez l'objet pour la première fois, ou créez l'objet à l'aide de Server-Side Apply.

Étapes suivantes