Soluciona problemas de sincronización de parámetros de configuración con tu clúster

En esta página, se muestra cómo resolver problemas con la sincronización de parámetros de configuración en tu clúster.

Soluciona problemas de KNV 2009

Los errores KNV2009 indican que el Sincronizador de configuración no pudo sincronizar algunas configuraciones en 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 agente de conciliación 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, los objetos RootSync obtienen el rol cluster-admin 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 del 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.

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 de nomos status ni gcloud alpha anthos config sync.

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 intente 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 reconcilie después de que se complete el intento de sincronización inicial. En este caso, la dependencia se debe detectar como reconciliada en el próximo intento de reintento de sincronización, lo que desbloquea la aplicación de cualquier elemento dependiente. Cuando esto sucede, es posible que el error se informe brevemente y, luego, se quite. Alargar el tiempo de espera de conciliación podría 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 que kpt generó 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 ocurre porque el Sincronizador de configuración administra su propia configuración de inventario. Para resolver este problema, borra la configuración del 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 solo cambiando el valor en la fuente de la verdad. Si intentas realizar ese 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 actualizar un campo inmutable, borra manualmente el objeto en el clúster. Luego, el Sincronizador de configuración puede volver a crear el objeto con el nuevo valor del campo.

No se pudo encontrar la API

Si ves un mensaje de error similar al siguiente, es posible que experimentes 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 en busca de 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 ocurrir con relativa frecuencia, solo con la actualización del backend o su reprogramación 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 muestran resultados de listas vacías, como custom-metrics-stackdriver-adapter. Otra razón común de fallas en el descubrimiento de la API son los webhooks no saludables.

Después de la versión 1.28 de Kubernetes, con la función de descubrimiento agregado habilitada, un backend de APIService que no está en buen estado ya no causa errores no controlados. En cambio, 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 no se especifique el recurso no disponible en tu fuente.

Autorreparación diferida

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

La autocorrección se pausa mientras se intenta la sincronización. Este comportamiento significa que la autocorrección podría retrasarse, en especial si hay errores de sincronización que impiden que se complete el agente de conciliación. Para volver a habilitar la autocorrección, 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 sincronizarse cada vez que se realizan cambios en la fuente, cada instancia del reconciliador también se sincroniza periódicamente como parte de su comportamiento de autorecuperación para revertir cualquier cambio que no haya detectado la mitigación de deriva activa. Cuando agregas objetos RootSync o RepoSync, se produce un aumento lineal en la cantidad de solicitudes a la API que realizan los agentes de conciliación que sincronizan recursos con Kubernetes. Por lo tanto, si tienes muchos objetos RootSync y RepoSync, a veces 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 ni desviación del estado que deseas. Esto es normal, pero puede ser sorprendente.

Cuando la sincronización falla, se vuelve a intentar hasta que se realiza correctamente. Sin embargo, si esto requiere interacción humana, es posible que el Sincronizador de configuración genere errores y vuelva a intentarlo durante un tiempo, lo que aumentará la cantidad de solicitudes que se realizan 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.

Los finalizadores bloquean la desinstalación de KubeVirt

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, es posible que la eliminación de otros objetos de KubeVirt se detenga o deje 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 las dependencias entre objetos de recursos para asegurarte de que se borren en orden inverso de dependencia.

Los finalizadores bloquean la eliminación de objetos

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 de limpieza o si el controlador que realiza la limpieza de ese recurso no está en buen estado o se borró.

Para mitigar este problema, identifica qué recurso aún 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 y se desbloquee 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, verifica los registros del controlador para ver si hay indicios de la causa raíz.

A menudo, tener un objeto atascado durante la eliminación es un indicador de que los objetos se borraron en el orden incorrecto. Para evitar este tipo de problemas en el futuro, declara las dependencias entre los 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, el inventario se actualiza para cambiar el estado del recurso a pendiente. Cuando la sincronización falla, el inventario se actualiza para cambiar el estado del recurso a fallido. Cuando se vuelve a intentar la sincronización después de una falla, este patrón se repite, lo que genera actualizaciones periódicas del 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.

La falla de sincronización puede 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 RoleBinding o ClusterRoleBinding adecuados para otorgarle al agente de conciliación RepoSync o RootSync permiso para administrar los recursos que no se sincronizan.

La aplicación del servidor no quita ni revierte los campos que no se especifican en la fuente.

El Sincronizador de configuración usa 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 cambian los campos no especificados 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 la adoptes por primera vez y, luego, cambia los campos de la fuente después de la sincronización, de modo que el Sincronizador de configuración quite correctamente los campos que aplicó anteriormente y los reemplace por los campos nuevos de la fuente. Otra forma de evitar este problema es borrar el recurso del clúster primero y permitir que el Sincronizador de configuración aplique la versión nueva.

¿Qué sigue?