La résolution des problèmes de synchronisation de la configuration dans Config Sync permet de s'assurer que vos clusters restent alignés sur votre source de vérité centrale. En cas d'échec de la synchronisation, les déploiements peuvent se bloquer et les configurations de cluster peuvent s'écarter de leur état déclaré. Vous pouvez diagnostiquer et corriger les erreurs de synchronisation KNV2009 courantes (par exemple, des autorisations de contrôle des accès basé sur les rôles (RBAC) manquantes, des objets ResourceGroup dépassant les limites de taille etcd et la latence des webhooks) pour restaurer le rapprochement automatisé.
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 comment les résoudre.
Opération interdite sur certaines ressources
Étant donné que vous devez accorder aux objets RepoSync leur RBAC, il se peut qu'il ne dispose pas des autorisations nécessaires pour appliquer des 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, les objets RootSync se voient attribuer le rôle cluster-admin par défaut.
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. Cela 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 :
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-systemPour vérifier l'objet
RepoSync, exécutez la commande suivante :kubectl get resourcegroup repo-sync -n NAMESPACERemplacez
NAMESPACEpar 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 35mSi la valeur de la colonne
RECONCILINGestTrue, cela signifie que la ressource ResourceGroup est encore rapprochée.Consultez les journaux du contrôleur ResourceGroup :
kubectl logs deployment resource-group-controller-manager -c manager -n resource-group-systemSi 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 rapprochée une fois la tentative de synchronisation initiale terminée. Dans ce cas, la dépendance doit être détectée comme rapprochée lors de la prochaine tentative de synchronisation, ce qui débloque l'application de toutes les dépendances. Dans ce cas, l'erreur peut être signalée brièvement, puis supprimée. L'allongement du délai avant expiration du rapprochement peut aider à éviter que l'erreur ne soit signalée par intermittence.
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 :
- É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. - Ajoutez l'annotation
configmanagement.gke.io/managed: disableduniquement 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 supprime l'objet 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 un Role personnalisé, vous pouvez recevoir 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 :
listwatchgetpatchdeletecreate
Pour savoir comment ajouter ces autorisations, consultez Créer une liaison de rôle.
É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 d'API Kubernetes pour identifier 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 les modifications apportées à ces ressources dans le cluster.
Avant la version 1.28 de Kubernetes, chaque fois qu'un backend APIService était défaillant ou renvoyait une liste vide, la découverte d'API échouait, ce qui entraînait une erreur de Config Sync et de 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 une seule instance répliquée. Certains backends APIService renvoient toujours des résultats de liste vides, comme custom-metrics-stackdriver-adapter. Une autre cause courante d'échec de la détection d'API est l'état non opérationnel des webhooks.
Après la version 1.28 de Kubernetes, lorsque la fonctionnalité de découverte agrégée est activée, un backend APIService non opérationnel ne provoque plus d'erreurs non gérées. Au lieu de cela, le groupe de ressources géré par cet APIService est affiché comme ne contenant aucune ressource. Cela permet de poursuivre la synchronisation, tant que la ressource non opérationnelle n'est 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.
L'autoréparation est suspendue pendant la tentative de synchronisation. Ce comportement signifie que l'autoréparation peut être retardée, en particulier si des erreurs de synchronisation empêchent l'outil de rapprochement 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-instance pour faire évoluer et isoler les locataires et les domaines d'erreur. Par conséquent, chaque RootSync et RepoSync dispose de sa propre instance de rapprochement. En plus de se synchroniser chaque fois que des modifications sont apportées à la source, chaque instance de rapprochement se synchronise également régulièrement dans le cadre de son comportement d'autoréparation, afin d'annuler les modifications manquées par la correction active des écarts. 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. 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 du groupe de ressources par défaut sur le cluster. Toutefois, vous pouvez voir des requêtes PATCH dans le journal d'audit, même si aucune modification n'a été apportée à la source ou si l'état souhaité n'a pas été modifié. Ce comportement est normal, mais peut être surprenant.
En cas d'erreur de synchronisation, l'opération est relancée jusqu'à ce qu'elle aboutisse. Toutefois, si cela nécessite une intervention humaine, Config Sync peut rencontrer 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 espacées de manière exponentielle, 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
RootSyncouRepoSyncpour 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 se bloquer ou cesser de 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 la 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 du rapprochement 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 résoudre ce problème, identifiez la ressource qui est toujours 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 racine devrait permettre de terminer le nettoyage des ressources, ce qui débloquera la suppression de l'objet.
Si le contrôleur est opérationnel, 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 du problème.
Souvent, un objet bloqué lors de 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 les 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 d'une tentative de synchronisation, l'inventaire est mis à jour pour modifier l'état de la ressource en "en attente". En cas d'échec de la synchronisation, l'inventaire est mis à jour pour que l'état de la ressource passe à "É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. C'est normal, mais cela peut surprendre.
Les échecs de synchronisation peuvent être causés par plusieurs problèmes. L'une des plus courantes est l'insuffisance des autorisations pour gérer les ressources spécifiées dans la source. Pour corriger cette erreur, ajoutez les objets RoleBinding ou ClusterRoleBinding appropriés afin d'accorder au rapprocheur RepoSync ou RootSync l'autorisation de gérer les ressources qui ne se synchronisent pas.
Config Sync ne supprime ou ne rétablit pas les champs non spécifiés dans la source.
Config Sync utilise l'application côté serveur pour appliquer les fichiers manifestes 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, qui met à jour le nombre d'instances répliquées dans un déploiement, en est un exemple. 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. Une autre façon d'éviter ce problème consiste à 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 créé à l'origine avec l'application côté client kubectl, il annule la définition de tous les champs définis avec l'application côté client, mais non 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 l'application côté serveur.
Étapes suivantes
- Si le problème persiste, vérifiez s'il s'agit d'un problème connu.
Si vous ne trouvez pas de solution à votre problème dans la documentation, consultez les ressources suivantes pour obtenir de l'aide :
- Obtenir de l'aide de la communauté en posant des questions sur Stack Overflow. Si vous utilisez kpt ou Kustomize, utilisez le tag
kptoukustomizepour rechercher des problèmes similaires. - Signaler des bugs ou demander des fonctionnalités à l'aide de l'outil public de suivi des problèmes sur GitHub.