Soluciona problemas de sincronización de la configuración con tu clúster

Resolver los problemas de sincronización de la configuración en el Sincronizador de configuración ayuda a garantizar que tus clústeres se mantengan alineados con tu fuente de información central. Cuando la sincronización falla, las implementaciones pueden detenerse y las configuraciones del clúster pueden desviarse de su estado declarado. Puedes diagnosticar y corregir errores de sincronización comunes de KNV2009, como la falta de permisos de control de acceso basado en roles (RBAC), objetos ResourceGroup que superan los límites de tamaño de etcd y la latencia de webhook, para restablecer la conciliación automatizada.

Soluciona problemas relacionados con los errores KNV 2009

Los errores KNV2009 indican que el Sincronizador de configuración no pudo sincronizar algunos parámetros de configuración con el clúster. En las siguientes secciones, se explican algunas de las causas más comunes y cómo resolverlas.

No se permite la operación en ciertos recursos

Debido a que debes otorgar a los objetos RepoSync su RBAC, es posible que falten los permisos necesarios para aplicar recursos.

Para verificar que faltan los permisos, obtén el estado de los recursos de RepoSync:

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

Reemplaza NAMESPACE por el espacio de nombres en el que creaste el repositorio de espacio de nombres.

También puedes usar el comando nomos status.

Si ves los siguientes mensajes en el estado, significa que el conciliador en NAMESPACE carece del permiso necesario para aplicar el 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 solucionar este problema, debes declarar una configuración de RoleBinding que otorgue a la cuenta de servicio del reconciliador permiso para administrar el recurso con errores en ese espacio de nombres. Los detalles sobre cómo agregar una RoleBinding se incluyen en Configura la sincronización desde varios repositorios.

Este problema también puede afectar a los objetos RootSync si usaste spec.override.roleRefs para cambiar los roles otorgados al objeto RootSync. Si no configuraste este campo, se otorga el rol cluster-admin a los objetos RootSync de forma predeterminada.

El recurso ResourceGroup excede el límite de tamaño del objeto etcd

Si recibes el siguiente error cuando un conciliador intenta aplicar configuraciones al clúster, el objeto ResourceGroup supera el límite de tamaño de objeto de 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.

Te recomendamos dividir el repositorio de Git en varios repositorios. Si no puedes dividir el repositorio de Git porque el objeto ya es demasiado grande y no se conservan los cambios, puedes mitigarlo configurando RootSync o RepoSync para inhabilitar temporalmente la escritura del estado del objeto en ResourceGroup. Para ello, configura el campo .spec.override.statusMode del objeto RootSync o RepoSync como disabled. Cuando lo haces, el Sincronizador de configuración deja de actualizar el estado de los recursos administrados en el objeto ResourceGroup. Esta acción reduce el tamaño del objeto ResourceGroup. Sin embargo, no puedes ver el estado de los recursos administrados desde nomos status.

Si no ves ningún error del objeto RootSync o RepoSync, significa que los objetos de tu fuente de información se sincronizaron con el clúster. Para comprobar si el recurso ResourceGroup excede el límite de tamaño del objeto etcd, verifica el estado del recurso ResourceGroup y el registro del controlador ResourceGroup:

  1. Verifica el estado de ResourceGroup:

    • Para verificar el objeto RootSync, ejecuta el siguiente comando:

      kubectl get resourcegroup root-sync -n config-management-system
      
    • Para verificar el estado RepoSync, ejecuta el siguiente comando:

      kubectl get resourcegroup repo-sync -n NAMESPACE
      

      Reemplaza NAMESPACE por el espacio de nombres en el que creaste el repositorio de espacio de nombres.

    El resultado es similar al siguiente ejemplo.

    NAME        RECONCILING   STALLED   AGE
    root-sync   True          False     35m
    

    Si el valor en la columna RECONCILING es True, significa que el recurso de ResourceGroup todavía se encuentra en conciliación.

  2. Revisa los registros para el controlador ResourceGroup:

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

    Si ves un error similar al siguiente ejemplo en el resultado, el recurso de ResourceGroup es demasiado grande y supera el límite de tamaño de los objetos etcd:

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

Para evitar que ResourceGroup se vuelva demasiado grande, reduce la cantidad de recursos en el repositorio de Git. Puedes dividir un repositorio raíz en varios repositorios raíz.

Tiempo de espera de conciliación de aplicación de dependencias

Si sincronizabas objetos con dependencias, es posible que recibas un error similar al siguiente ejemplo cuando el conciliador intenta aplicar objetos con la anotación config.kubernetes.io/depends-on al clúster:

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 error significa que el objeto de dependencia no concilió dentro del tiempo de espera de conciliación predeterminado de 5 minutos. El Sincronizador de configuración no puede aplicar el objeto dependiente, ya que con la anotación config.kubernetes.io/depends-on, el Sincronizador de configuración solo aplica objetos en el orden que desees. Puedes anular el tiempo de espera de conciliación predeterminado por un período más largo si configuras spec.override.reconcileTimeout.

También es posible que la dependencia se concilie después de que se complete el intento de sincronización inicial. En este caso, la dependencia se debe detectar como conciliada en el siguiente intento de sincronización, lo que desbloquea la aplicación de cualquier dependiente. Cuando esto sucede, es posible que el error se informe brevemente y, luego, se quite. Extender el tiempo de espera de conciliación puede ayudar a evitar que el error se informe de forma intermitente.

La información del inventario es nula

Si recibes el siguiente error cuando el conciliador intenta aplicar configuraciones al clúster, es probable que tu inventario no tenga recursos o que el manifiesto tenga una anotación no administrada:

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

Para resolver este problema, realiza las siguientes acciones:

  1. Evita configurar sincronizaciones en las que todos los recursos tengan la anotación configmanagement.gke.io/managed: disabled. Para ello, asegúrate de que el Sincronizador de configuración administre al menos un recurso.
  2. Agrega la anotación configmanagement.gke.io/managed: disabled solo después de completar una sincronización inicial del recurso sin esta anotación.

Varias plantillas de objetos de inventario

Si recibes el siguiente error cuando el conciliador intenta aplicar configuraciones al clúster, es probable que tengas una configuración de inventario generada por kpt en la fuente de confianza, por ejemplo, un repositorio de 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

El problema se produce porque el Sincronizador de configuración administra su propia configuración de inventario. Para resolver este problema, borra la configuración de inventario en tu fuente de información.

No se pueden realizar cambios en los campos inmutables

No puedes cambiar ningún campo inmutable en una configuración cambiando el valor en la fuente de confianza. Si intentas realizar este cambio, se producirá un error similar al siguiente:

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 necesitas cambiar un campo inmutable, borra el objeto de tu fuente de información, espera a que el Sincronizador de configuración borre el objeto del clúster y, luego, vuelve a crear el objeto en tu fuente de información con las actualizaciones.

No se pudo realizar el sondeo de estado

Puedes autorizar al Sincronizador de configuración para que administre recursos en un espacio de nombres con un objeto RepoSync. Si este tipo de objeto RepoSync usa un objeto RoleBinding que hace referencia a un ClusterRole o Role personalizado, es posible que recibas el siguiente mensaje de error de la implementación del conciliador:

KNV2009: polling for status failed: unknown

Para resolver este problema, asegúrate de que tus objetos ClusterRole y Role tengan, como mínimo, los siguientes permisos para cada recurso que administra el objeto RepoSync:

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

Para obtener instrucciones sobre cómo agregar estos permisos, consulta Crea un RoleBinding.

No se pudo detectar la API

Si ves un mensaje de error similar al siguiente, es posible que tengas un error de descubrimiento de la 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

El Sincronizador de configuración usa el descubrimiento de la API de Kubernetes para buscar qué recursos admite el clúster. Esto permite que el Sincronizador de configuración valide los tipos de recursos especificados en tu fuente y supervise esos recursos para detectar cambios en el clúster.

Antes de la versión 1.28 de Kubernetes, cada vez que un backend de APIService no estaba en buen estado o mostraba un resultado de lista vacía, el descubrimiento de API fallaba, lo que provocaba errores en Sincronizador de configuración y en varios otros componentes de Kubernetes. Muchos backends de APIService comunes no tienen alta disponibilidad, por lo que esto puede suceder con relativa frecuencia, solo con actualizar el backend o reprogramarlo en otro nodo.

Entre los ejemplos de backends de APIService con una sola réplica, se incluyen metrics-server y custom-metrics-stackdriver-adapter. Algunos backends de APIService siempre devuelven resultados de listas vacías, como custom-metrics-stackdriver-adapter. Otra causa común de la falla en el descubrimiento de la API son los webhooks en mal estado.

Después de la versión 1.28 de Kubernetes, con la función de descubrimiento agregado habilitada, un backend de APIService en mal estado ya no causa errores no controlados. En su lugar, se muestra que el grupo de recursos que controla ese APIService no tiene recursos. Esto permite que la sincronización continúe, siempre y cuando el recurso en mal estado no se especifique en tu fuente.

Autorreparación retrasada

La autorreparación observa los recursos administrados, detecta el desvío de la fuente de información y revierte ese desvío.

La reparación automática se pausa mientras se intenta realizar la sincronización. Este comportamiento significa que la reparación automática podría retrasarse, en especial si hay errores de sincronización que impiden que se complete el conciliador. Para volver a habilitar la reparación automática, corrige todos los errores de sincronización informados.

Gran cantidad de solicitudes a la API de Kubernetes

El Sincronizador de configuración usa una estrategia de instancias múltiples para escalar y aislar usuarios y dominios de fallas. Debido a esto, cada RootSync y RepoSync obtiene su propia instancia de conciliador. Además de sincronizar cada vez que se realizan cambios en la fuente, cada instancia de conciliador también se sincroniza de forma periódica como parte de su comportamiento de reparación automática para revertir cualquier cambio que se haya omitido en la corrección de desvío activa. Cuando agregas objetos RootSync o RepoSync, se produce un aumento lineal en la cantidad de solicitudes a la API que realizan los conciliadores que sincronizan recursos con Kubernetes. Por lo tanto, si tienes muchos objetos RootSync y RepoSync, esto puede causar una carga de tráfico significativa en la API de Kubernetes.

Para realizar la sincronización, el Sincronizador de configuración usa la aplicación del servidor. Esto reemplaza el flujo normal de solicitudes GET y PATCH por una sola solicitud PATCH, lo que reduce la cantidad total de llamadas a la API, pero aumenta la cantidad de llamadas PATCH. Esto garantiza que los cambios realizados sean correctos, incluso cuando la versión del grupo de recursos en la fuente no coincida con la versión predeterminada del grupo de recursos en el clúster. Sin embargo, es posible que veas solicitudes PATCH en el registro de auditoría, incluso cuando no haya habido ningún cambio en la fuente o desviación del estado que deseas. Esto es normal, pero puede ser sorprendente.

Cuando la sincronización genera un error, se vuelve a intentar hasta que se completa correctamente. Sin embargo, si esto requiere interacción humana, es posible que el Sincronizador de configuración genere un error y vuelva a intentarlo durante un tiempo, lo que aumentará la cantidad de solicitudes realizadas a la API de Kubernetes. Los reintentos se retrasan de forma exponencial, pero si muchos objetos RootSync o RepoSync no se sincronizan de forma simultánea, esto puede causar una carga de tráfico significativa en la API de Kubernetes.

Para mitigar estos problemas, prueba una de las siguientes opciones:

  • Corrige los errores de configuración rápidamente para que no se acumulen.
  • Combina varios objetos RootSync o RepoSync para reducir la cantidad de conciliadores que realizan solicitudes a la API de Kubernetes.

La desinstalación de KubeVirt está bloqueada por finalizadores

KubeVirt es un paquete de Kubernetes que usa varios finalizadores, lo que requiere un orden de eliminación preciso para facilitar la limpieza. Si los objetos de KubeVirt se borran en el orden incorrecto, la eliminación de otros objetos de KubeVirt podría detenerse o dejar de responder de forma indefinida.

Si intentaste desinstalar KubeVirt y se bloqueó, sigue las instrucciones para borrar KubeVirt de forma manual.

Para mitigar este problema en el futuro, declara dependencias entre objetos de recursos para asegurarte de que se borren en orden inverso de dependencia.

La eliminación de objetos se bloqueó por los finalizadores

Los finalizadores de Kubernetes son entradas de metadatos que le indican a Kubernetes que no permita que se quite un objeto hasta que un controlador específico haya realizado la limpieza. Esto puede provocar que la sincronización o la conciliación fallen si no se cumplen las condiciones para la limpieza o si el controlador que realiza la limpieza de ese recurso está en mal estado o se borró.

Para mitigar este problema, identifica qué recurso aún se está finalizando y qué controlador debería realizar la limpieza.

Si el controlador no está en buen estado, corregir la causa raíz debería permitir que se complete la limpieza de recursos, lo que desbloqueará la eliminación del objeto.

Si el controlador está en buen estado, debería haber aplicado una condición de estado al objeto que se borra para explicar por qué se detuvo la limpieza. De lo contrario, revisa los registros del controlador para ver indicios de la causa raíz.

A menudo, que un objeto se atasque durante la eliminación indica que los objetos se borraron en el orden incorrecto. Para evitar este tipo de problema en el futuro, declara dependencias entre objetos de recursos para asegurarte de que se borren en orden inverso de dependencia.

Los campos ResourceGroup cambian constantemente

Cuando se intenta realizar la sincronización, se actualiza el inventario para cambiar el estado del recurso a pendiente. Cuando falla la sincronización, se actualiza el inventario para cambiar el estado del recurso a fallido. Cuando se vuelve a intentar la sincronización después de un error, este patrón se repite, lo que provoca actualizaciones periódicas en el inventario. Esto hace que el ResourceGroup resourceVersion aumente con cada actualización y que el estado de sincronización cambie de un lado a otro. Esto es normal, pero puede ser sorprendente.

Los errores de sincronización pueden deberse a varios problemas. Uno de los más comunes es la falta de permisos para administrar los recursos especificados en la fuente. Para corregir este error, agrega los objetos RoleBinding o ClusterRoleBinding adecuados para otorgar al conciliador RepoSync o RootSync permiso para administrar los recursos que no se sincronizan.

El Sincronizador de configuración no quita ni revierte los campos que no se especifican en la fuente

El Sincronizador de configuración usa la aplicación del servidor para aplicar manifiestos de la fuente a Kubernetes. Esto es necesario para permitir que otros controladores administren los campos metadata y spec. Un ejemplo de esto es el Horizontal Pod Autoscaler, que actualiza la cantidad de réplicas en un Deployment. Por este motivo, el Sincronizador de configuración solo administra los campos especificados en el manifiesto de origen. Esto tiene el efecto secundario de que, cuando se adoptan objetos de recursos existentes, no se cambia ningún campo no especificado en la fuente, lo que a veces puede hacer que la configuración combinada no sea válida o sea incorrecta.

Para evitar este problema cuando adoptes un recurso, usa exactamente los mismos campos en la fuente cuando lo adoptes inicialmente y, luego, cambia los campos en la fuente después de la sincronización, de modo que el Sincronizador de configuración quite correctamente los campos que aplicó antes y los reemplace por los campos nuevos de la fuente. Otra forma de evitar este problema es borrar primero el recurso del clúster y permitir que el Sincronizador de configuración aplique la versión nueva.

El Sincronizador de configuración no conserva los campos de la aplicación del cliente de kubectl cuando se adoptan objetos

Debido a que el Sincronizador de configuración usa la aplicación del servidor, cuando adopta un objeto que se creó originalmente con la aplicación del cliente de kubectl, desactiva los campos que se configuraron con la aplicación del cliente, pero que no se declararon en la fuente.

Si deseas que se conserven esos campos, usa exactamente los mismos campos en la fuente cuando adoptes el objeto inicialmente o créalo con Server-Side Apply.

¿Qué sigue?

Si no encuentras una solución a tu problema en la documentación, consulta los siguientes recursos para obtener más ayuda: