Lanzamientos seguros con el Sincronizador de configuración

En este documento, se muestra a los operadores de clústeres y a los administradores de plataformas cómo implementar de forma segura los cambios en varios entornos con el Sincronizador de configuración. Este enfoque puede ayudarte a evitar errores que afecten a todos tus entornos de forma simultánea.

El Sincronizador de configuración te permite administrar clústeres únicos, clústeres de múltiples usuarios y la configuración de Kubernetes de varios clústeres mediante archivos almacenados en un repositorio de Git.

Las configuraciones pueden representar varios elementos, incluidos los siguientes:

El Sincronizador de configuración es especialmente adecuado para implementar parámetros de configuración, políticas y cargas de trabajo necesarias para ejecutar la plataforma que compilas sobre la edición Google Kubernetes Engine (GKE) Enterprise, por ejemplo, agentes de seguridad, agentes de supervisión y administradores de certificados.

Aunque puedes implementar aplicaciones para el usuario con el Sincronizador de configuración, no recomendamos vincular el ciclo de vida de la versión al de las cargas de trabajo administrativas mencionadas antes. En cambio, te recomendamos que uses una herramienta dedicada a la implementación de aplicaciones, como una herramienta de implementación continua, para que los equipos de aplicaciones puedan estar a cargo de sus programas de lanzamientos.

El Sincronizador de configuración es un producto potente que puede administrar muchos elementos, por lo que necesitas barreras de seguridad para evitar errores que tengan un impacto importante. En este documento, se describen varios métodos para crear barreras de seguridad. En la primera sección, se abordan los lanzamientos en etapas, y la segunda, en las pruebas y validaciones. En la tercera sección, se muestra cómo supervisar tus implementaciones.

Implementa lanzamientos en etapas con el Sincronizador de configuración

En un entorno de varios clústeres, que es una situación común para los usuarios de GKE Enterprise, no recomendamos aplicar un cambio de configuración en todos los clústeres al mismo tiempo. Un lanzamiento en etapas (clúster por clúster) es mucho más seguro porque reduce el impacto potencial de cualquier error.

Hay varias formas de implementar lanzamientos en etapas con el Sincronizador de configuración:

  • Usa las confirmaciones o las etiquetas de Git para aplicar los cambios que desees a los clústeres de forma manual.
  • Usa las ramas de Git para aplicar de forma automática los cambios cuando se combinan. Puedes usar diferentes ramas para distintos grupos de clústeres.
  • Usa objetos ClusterSelector y NamespaceSelector para aplicar cambios de forma selectiva a subgrupos de clústeres o espacios de nombres.

Todos los métodos para los lanzamientos por etapas tienen ventajas y desventajas. En la siguiente tabla, se muestra cuáles de estos métodos puedes usar al mismo tiempo:

Compatibilidad Confirmaciones o etiquetas de Git Ramas de Git Selectores de clústeres Selectores de espacios de nombres
Confirmaciones o etiquetas de Git No compatible Compatible Compatible
Ramas de Git No compatible Compatible Compatible
Selectores de clústeres Compatible Compatible Compatible
Selectores de espacios de nombres Compatible Compatible Compatible

El siguiente árbol de decisión puede ayudarte a decidir cuándo usar uno de los métodos de lanzamiento en etapas.

Árbol de decisión para los métodos de lanzamiento.

Usa confirmaciones o etiquetas de Git

En comparación con los otros métodos de lanzamiento por etapas, el uso de confirmaciones o etiquetas de Git proporciona mayor control y es más seguro. Puedes usar la página del Sincronizador de configuración en la consola de Google Cloud en la consola para actualizar varios clústeres al mismo tiempo. Usa este método si deseas aplicar cambios a tus clústeres uno por uno y controlar de forma exacta cuándo sucede.

En este método, “fijas” cada clúster a una versión específica (ya sea una confirmación o una etiqueta) de tu repositorio. Este método es similar a usar la confirmación de Git como una etiqueta de imagen de contenedor. Para implementar este método, especifica la confirmación, la etiqueta o el hash en el campo spec.git.revision del recurso personalizado RootSync o RepoSync.

Si administras tus recursos personalizados RootSync o RepoSync con una herramienta como Kustomize, puedes reducir la cantidad de trabajo manual necesario para los lanzamientos. Con esta herramienta, solo necesitas cambiar el parámetro revision en un lugar y, luego, aplicar de manera selectiva el nuevo recurso personalizado RootSync o RepoSync a tus clústeres en el orden y al ritmo que elijas.

Además, puedes usar la consola de Google Cloud para actualizar el parámetro revision de varios clústeres que pertenezcan a la misma flota al mismo tiempo. Sin embargo, si tienes un sistema automatizado para actualizar los parámetros de configuración, no te recomendamos que uses la consola de Google Cloud para realizar cambios en la configuración.

Por ejemplo, la siguiente definición de RootSync configura el Sincronizador de configuración para usar la etiqueta 1.2.3:

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-sync-system
spec:
  sourceType: git
  sourceFormat: unstructured
  git:
    repo: git@example.com:gke/config-sync.git
    revision: 1.2.3
    auth: ssh

Si aplicas esta configuración a tu clúster, el Sincronizador de configuración usará la etiqueta 1.2.3 del repositorio example.com:gke/config-sync.git.

Para actualizar un clúster, cambia el campo spec.git.revision al valor nuevo del clúster. Esto te permite definir qué clústeres se actualizan y cuándo. Si necesitas revertir un cambio, cambia el campo spec.git.revision a su valor anterior.

En el siguiente diagrama, se ilustra el proceso de lanzamiento para este método. Primero, confirma los cambios en el repositorio del Sincronizador de configuración y, luego, actualiza las definiciones de RootSync en todos los clústeres:

Proceso de lanzamiento para confirmaciones y etiquetas de Git.

Recomendamos las siguientes acciones:

  • Usa los ID de confirmación de Git en lugar de las etiquetas. Debido a la forma en que funciona Git, tienes la garantía de que nunca cambiarán. Por ejemplo, un git push --force no puede cambiar la confirmación que usa el Sincronizador de configuración. Este enfoque es útil con fines de auditoría y para hacer un seguimiento de la confirmación que usas en los registros. Además, a diferencia de las etiquetas, no existe un paso adicional para confirmar los ID.
  • Si prefieres usar etiquetas de Git en lugar de los IDs de confirmación de Git, puedes proteger tus etiquetas si usas una solución de Git que admita protección.
  • Si quieres actualizar varios clústeres al mismo tiempo, puedes hacerlo en la consola de Google Cloud. Para actualizar varios clústeres a la vez, deben ser parte de la misma flota (y estar en el mismo proyecto).

Usa ramas de Git

Si deseas que los cambios se apliquen a los clústeres en cuanto se combinen en tu repositorio de Git, configura el Sincronizador de configuración para que use ramas de Git en lugar de confirmaciones o etiquetas. En este método, creas varias ramas de larga duración en tu repositorio de Git y configuras el Sincronizador de configuración en diferentes clústeres para leer su configuración desde diferentes ramas.

Por ejemplo, un patrón simple tiene dos ramas:

  • Una rama staging para clústeres que no son de producción
  • Una rama main para clústeres de producción

Para los clústeres que no son de producción, crea el objeto RootSync o RepoSync con el campo spec.git.branch configurado como staging. Para los clústeres de producción, crea el objeto RootSync o RepoSync con el parámetro spec.git.branch establecido en main.

Por ejemplo, la siguiente definición de RootSync configura el Sincronizador de configuración para usar la rama main:

apiVersion: configsync.gke.io/v1
kind: RootSync
metadata:
  name: root-sync
  namespace: config-sync-system
spec:
  git:
    repo: git@example.com:gke/config-sync.git
    branch: main
    auth: ssh

En el siguiente diagrama, se ilustra el proceso de lanzamiento de este método:

Proceso de lanzamiento para ramas de Git.

Puedes adaptar este patrón a necesidades específicas mediante el uso de más de dos ramas o ramas asignadas a algo que no sea entornos. Si necesitas revertir un cambio, usa el comando git revert para crear una confirmación nueva en la misma rama que revierte los cambios de la confirmación anterior.

Recomendamos las siguientes acciones:

  • Cuando trabajes con varios clústeres, usa al menos dos ramas de Git para distinguir entre los clústeres de producción y los que no lo sean.
  • La mayoría de las soluciones de Git te permiten usar la función de ramas protegidas para evitar las eliminaciones o los cambios sin revisión de esas ramas. Para obtener más información, consulta la documentación de GitHub, GitLab y Bitbucket.

Usa objetos ClusterSelector y NamespaceSelector

Las ramas de Git son una buena manera de realizar un lanzamiento por etapas de cambios en varios clústeres que al final tendrán las mismas políticas. Sin embargo, si deseas lanzar un cambio solo en un subconjunto de clústeres o espacios de nombres, usa los objetos ClusterSelector y NamespaceSelector. Estos objetos tienen un objetivo similar: te permiten aplicar objetos solo a clústeres o espacios de nombres que tienen etiquetas específicas.

Por ejemplo:

  • Si usas objetos ClusterSelector, puedes aplicar diferentes políticas a los clústeres, según el país en el que se encuentren, para varios regímenes de cumplimiento.
  • Si usas objetos NamespaceSelector, puedes aplicar diferentes políticas a los espacios de nombres que usa un equipo interno y un contratista externo.

Los objetos ClusterSelector y NamespaceSelector también te permiten implementar metodologías avanzadas de prueba y lanzamiento, como las siguientes:

  • Lanzamientos Canary de políticas, en los que implementas una política nueva en un subconjunto pequeño de clústeres y espacios de nombres durante mucho tiempo para estudiar el impacto de la política
  • Pruebas A/B, en las que implementas versiones distintas de la misma política en clústeres diferentes con el fin de estudiar la diferencia del impacto de las versiones de la política y, luego, elegir la mejor para implementar en todas partes

Por ejemplo, imagina una organización con varios clústeres de producción. El equipo de la plataforma ya creó dos categorías de clústeres de producción, llamados canary-prod y prod, con objetos Cluster y ClusterSelector (consulta Usa ClusterSelectors).

El equipo de la plataforma quiere lanzar una política con el controlador de políticas para aplicar la presencia de una etiqueta de equipo en los espacios de nombres a fin de identificar a qué equipo pertenece cada espacio de nombres. Ya lanzaron una versión de esta política en el modo de ejecución de prueba y ahora quieren aplicarla en una cantidad pequeña de clústeres. Mediante objetos ClusterSelector, crean dos recursos K8sRequiredLabels distintos que se aplican a clústeres diferentes.

  • El recurso K8sRequiredLabels se aplica a los clústeres de tipo prod, con un parámetro enforcementAction configurado como dryrun:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: prod
    Spec:
      enforcementAction: dryrun
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    
  • El recurso K8sRequiredLabels se aplica a los clústeres de tipo canary-prod, sin el parámetro enforcementAction, lo que significa que la política se aplica de verdad:

    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sRequiredLabels
    metadata:
      name: ns-must-have-team
      annotations:
        configmanagement.gke.io/cluster-selector: canary-prod
    spec:
      match:
        kinds:
          - apiGroups: [""]
        kinds: ["Namespace"]
      parameters:
        labels:
          - key: "team"
    

La anotación configmanagement.gke.io/cluster-selector permite que el equipo aplique la política solo en clústeres de tipo canary-prod, lo que evita que se propaguen efectos secundarios no deseados a toda la flota de producción. Para obtener más información sobre la función de ejecución de prueba del controlador de políticas, consulta Crea restricciones.

Recomendamos las siguientes acciones:

  • Usa los objetos ClusterSelector y NamespaceSelector si necesitas aplicar un cambio de configuración a un solo subconjunto de clústeres o espacios de nombres de forma indefinida o durante mucho tiempo.
  • Si lanzas un cambio mediante selectores, ten mucho cuidado. Si usas confirmaciones de Git, cualquier error afecta solo a un clúster a la vez, ya que lanzas clúster por clúster. Sin embargo, si usas ramas de Git, cualquier error puede afectar a todos los clústeres que usen esa rama. Si usas selectores, el error puede afectar a todos los clústeres a la vez.

Implementa revisiones, pruebas y validaciones

Una de las ventajas del Sincronizador de configuración es que administra todo de forma declarativa: recursos de Kubernetes, recursos de nube y políticas. Esto significa que los archivos en un sistema de administración de control de origen representan los recursos (archivos de Git, en el caso del Sincronizador de configuración). Esta función te permite implementar flujos de trabajo de desarrollo que ya usas para el código fuente de una aplicación: revisiones y pruebas automatizadas.

Implementa revisiones

Debido a que el Sincronizador de configuración se basa en Git, puedes usar tu solución de Git preferida para alojar el repositorio del Sincronizador de configuración. Es probable que tu solución de Git tenga una función de revisión de código, que puedes usar para revisar los cambios realizados en el repositorio del Sincronizador de configuración.

Las prácticas recomendadas para revisar los cambios en tu repositorio son las mismas que para una revisión de código normal, como se muestra a continuación:

Debido a la sensibilidad de la base de código del Sincronizador de configuración, también recomendamos que, si es posible con tu solución de Git, establezcas los siguientes parámetros de configuración:

Si usas estas funciones diferentes, puedes aplicar aprobaciones para cada solicitud de cambio en tu base de código. Por ejemplo, puedes asegurarte de que al menos un miembro del equipo de la plataforma (que opere la flota de clústeres) y un miembro del equipo de seguridad (que esté a cargo de la implementación y definición de políticas de seguridad) aprueben cada cambio.

Te recomendamos la siguiente acción:

  • Aplica las revisiones de colegas en tu repositorio y protege las ramas de Git que usan tus clústeres.

Implementa pruebas automatizadas

Una práctica recomendada común cuando se trabaja en una base de código es implementar la integración continua. Esto significa que configuras pruebas automatizadas para que se ejecuten cuando se crea o se actualiza una solicitud de cambio. Las pruebas automatizadas pueden detectar muchos errores antes de que se realice una revisión manual de la solicitud de cambio. Esto ajusta el ciclo de reacción del desarrollador. Puedes implementar la misma idea con las mismas herramientas para el repositorio del Sincronizador de configuración.

Por ejemplo, un buen punto de partida es ejecutar el comando nomos vet de forma automática en los cambios nuevos. Este comando valida que la sintaxis del repositorio del Sincronizador de configuración sea válida. Puedes implementar esta prueba mediante Cloud Build si sigues el instructivo para validar la configuración. Puedes integrar Cloud Build con las siguientes opciones:

  • Bitbucket, mediante activadores de compilación
  • GitHub, con la aplicación de GitHub de Google Cloud Build. Los activadores de compilación también están disponibles para GitHub, pero la aplicación de GitHub es el método de integración que se prefiere

Como puedes ver en el instructivo de validación de configuraciones, la prueba se realiza mediante una imagen de contenedor. Por lo tanto, puedes implementar la prueba en cualquier solución de integración continua que ejecute contenedores, no solo Cloud Build.

Para ajustar aún más el ciclo de reacción, puedes pedirles a los usuarios que ejecuten el comando nomos vet como un hook previo a la confirmación de Git. Ten en cuenta que es posible que algunos usuarios no tengan acceso a los clústeres de Kubernetes que administra el Sincronizador de configuración y que no puedan ejecutar la validación completa desde su estación de trabajo. Ejecuta el comando nomos vet --clusters "" para restringir la validación a verificaciones semánticas y sintácticas.

Te recomendamos la siguiente acción:

  • Implementa pruebas en una canalización de integración continua.
  • Ejecuta al menos el comando nomos vet en todos los cambios sugeridos.

Supervisa los lanzamientos

Incluso si implementas todas las barreras de seguridad que se cubren en este documento, pueden ocurrir errores. Los siguientes son dos tipos comunes de errores:

  • Errores que no representan ningún problema para el sincronizador de configuración, pero impiden que tus cargas de trabajo funcionen de forma correcta, como una NetworkPolicy demasiado restrictiva que impide que los componentes de tu carga de trabajo se comuniquen
  • Errores que hacen que el sincronizador de configuración no pueda aplicar cambios a un clúster, como un manifiesto de Kubernetes no válido o un objeto rechazado por un controlador de entrada. Los métodos explicados antes deberían detectar la mayoría de estos errores

Detectar los errores descritos en la primera viñeta anterior es casi imposible en el nivel del Sincronizador de configuración porque esto requiere comprender el estado de cada una de las cargas de trabajo. Por este motivo, tu sistema de supervisión existente es lo mejor para detectar estos errores, ya que te avisa cuando una aplicación tiene un comportamiento deficiente.

La detección de los errores descritos en la segunda viñeta anterior, que deberían ser inusuales si se implementaron todas las barreras de seguridad, requiere una configuración específica. De forma predeterminada, el Sincronizador de configuración escribe errores en sus registros (que encontrarás de forma predeterminada en Cloud Logging). También se muestran los errores en la página de la consola de Google Cloud del Sincronizador de configuración. Ni los registros ni la consola suelen ser suficiente para detectar errores porque es probable que no los supervises en todo momento. La forma más sencilla de automatizar la detección de errores es ejecutar el comando nomos status, que te indica si hay un error en un clúster.

También puedes configurar una solución más avanzada con alertas automáticas para errores. El Sincronizador de configuración expone métricas en el formato Prometheus. Para obtener más información, consulta Supervisa el Sincronizador de configuración.

Una vez que tengas las métricas del Sincronizador de configuración en tu sistema de supervisión, crea una alerta para recibir notificaciones cuando la métrica gkeconfig_monitor_errors sea mayor que 0. Si deseas obtener más información, consulta Administra políticas de alertas para Cloud Monitoring o Reglas de alertas para Prometheus.

Resumen de los mecanismos para lanzamientos seguros con el Sincronizador de configuración

En la siguiente tabla, se resumen los diversos mecanismos descritos antes en este documento. Ninguno de estos mecanismos es exclusivo. Puedes optar por usar algunos o todos ellos para diferentes propósitos.

Mecanismos Usos ideales Usos no convenientes Ejemplo de caso de uso
ID y etiquetas de confirmación de Git Usa etiquetas o ID de confirmación de Git específicos para controlar con precisión en qué clúster se aplican cambios. No uses ID de confirmación ni etiquetas de Git para las diferencias de larga duración entre clústeres. Usa selectores de clúster. Todos tus clústeres están configurados para aplicar la confirmación 12345 de Git. Realiza un cambio con una confirmación nueva, abcdef, que deseas probar. Cambia la configuración de un solo clúster para usar esta confirmación nueva a fin de validar el cambio.
Ramas de Git Usa varias ramas de Git cuando quieras lanzar el mismo cambio en varios entornos, uno después del otro. No uses varias ramas de Git para las diferencias de larga duración entre clústeres. Las ramas se dividirán de forma significativa y será difícil volver a combinarlas. Primero, combina el cambio en la rama de etapa de pruebas, en la que los clústeres de etapa de pruebas lo tomarán.
Luego, combina el cambio en la rama principal, en la que los clústeres de producción lo tomarán.
Selectores de clústeres y de espacios de nombres Usa selectores para las diferencias de larga duración entre los clústeres y los espacios de nombres. No uses selectores para un lanzamiento por etapas en varios entornos. Si primero quieres probar una modificación en la etapa de pruebas y, luego, implementarla en producción, usa ramas de Git diferentes. Si los equipos de la aplicación necesitan acceso completo a los clústeres de desarrollo, pero solo lectura a los clústeres de producción, usa el objeto ClusterSelector para aplicar las políticas de RBAC adecuadas solo en los clústeres relevantes.
Evaluaciones entre compañeros Usa las evaluaciones entre compañeros para asegurarte de que los equipos relevantes aprueben los cambios. Los revisores manuales no detectan todos los errores, en particular, los elementos como los errores de sintaxis. Tu organización exige que el equipo de seguridad revise los cambios de configuración que afectan a varios sistemas. Haz que un miembro del equipo de seguridad revise los cambios.
Pruebas automatizadas en la canalización de integración continua Usa las pruebas automatizadas para detectar errores en los cambios sugeridos. Las pruebas automatizadas no pueden reemplazar por completo a un revisor humano. Usa ambas opciones. Ejecutar un comando nomos vet en todos los cambios sugeridos confirma que el repositorio es una configuración válida del Sincronizador de configuración.
Supervisa errores de sincronización Asegúrate de que el Sincronizador de configuración aplique los cambios a tus clústeres. Los errores de sincronización solo se producen si el Sincronizador de configuración intenta aplicar un repositorio no válido o si el servidor de la API de Kubernetes rechaza algunos de los objetos. Un usuario omite todas tus pruebas y revisiones, y confirma un cambio no válido en el repositorio del Sincronizador de configuración. Este cambio no se puede aplicar a tus clústeres. Si supervisas los errores de sincronización, recibirás una alerta si se produce un error.

Ejemplo de estrategia de lanzamiento

En esta sección, se usan los conceptos presentados en el resto de este artículo para ayudarte a crear una estrategia de implementación de extremo a extremo en todos los clústeres de tu organización. En esta estrategia, se da por sentado que tienes flotas separadas para el desarrollo, la etapa de pruebas y la producción (como se muestra en el ejemplo de flota 1, enfoque 1).

.

En esta situación, configurarás cada clúster para que se sincronice con tu repositorio de Git mediante una confirmación de Git específica. Implementar un cambio en una flota determinada es un proceso de 4 pasos:

  1. Debes actualizar un solo clúster (el "canary") en la flota para usar la confirmación nueva primero.
  2. Ejecuta pruebas y supervisa el lanzamiento para validar que todo funcione como se espera.
  3. Debes actualizar el resto de los clústeres en la flota.
  4. Vuelve a comprobar que todo funcione según lo esperado.

A fin de implementar un cambio en todos tus clústeres, repite este proceso para cada flota. Técnicamente, puedes aplicar este método con cualquier confirmación de Git, desde cualquier rama. Sin embargo, te sugerimos que adoptes el siguiente proceso para identificar los problemas durante las primeras etapas del proceso de revisión:

  1. Cuando alguien abra una solicitud de cambio en el repositorio de Git del Sincronizador de configuración, implementa ese cambio en uno de los clústeres de desarrollo.
  2. Si se acepta y combina la solicitud de cambio en tu rama principal, ejecuta la implementación completa en todas las flotas, como se describió antes.

Si bien algunos cambios pueden apuntar a una flota específica, te recomendamos que implementes todos los cambios en todas las flotas cuando sea posible. Con esta estrategia, se elimina el problema de realizar un seguimiento de qué flota se debe sincronizar con qué confirmación. Presta especial atención a los cambios que se orientan solo a la flota de producción porque no se pudieron realizar las pruebas adecuadas en flotas anteriores. Por ejemplo, esto significa que pasará más tiempo para que se muestren los problemas mientras realizas una implementación en los clústeres Canary y, luego, en el resto de los clústeres.

En resumen, una implementación de extremo a extremo completa de esta es similar a la siguiente:

  1. Alguien abre una solicitud de cambio.
  2. Se ejecutan pruebas y validaciones automatizadas, y se realiza una revisión manual.
  3. Se activa un trabajo de forma manual para implementar el cambio en el clúster de Canary de la flota de desarrollo. Las pruebas automatizadas de extremo a extremo se ejecutan en este clúster.
  4. Si todo está bien, fusionas la solicitud de cambio en la rama principal.
  5. La combinación activa un trabajo automatizado para implementar el nuevo compromiso sugerido de la rama principal en el clúster canary de la flota de desarrollo. Las pruebas automatizadas de extremo a extremo se ejecutan en este clúster (para detectar incompatibilidades potenciales entre dos solicitudes de cambio que se crearon y fusionaron aproximadamente al mismo tiempo).
  6. Los siguientes trabajos se ejecutan uno después del otro (los activas de forma manual o después de un tiempo predefinido para permitir los informes de regresiones de usuarios):
    1. Implementar en todos los clústeres de la flota de desarrollo.
    2. Ejecutar pruebas y validaciones en los clústeres de la flota de desarrollo.
    3. Implementar en el clúster canary de la flota de etapa de pruebas.
    4. Ejecutar las pruebas y validaciones en el clúster canary de la flota de etapa de pruebas.
    5. Implementar en todos los clústeres de la flota de etapa de pruebas
    6. Ejecutar pruebas y validaciones en los clústeres de la flota de etapa de pruebas.
    7. Implementar en el clúster canary de la flota de producción.
    8. Ejecutar las pruebas y validaciones en el clúster Canary de la flota de producción.
    9. Implementar en todos los clústeres de la flota de producción.
    10. Ejecutar pruebas y validaciones en los clústeres de la flota de producción.

Proceso completo de implementación:

¿Qué sigue?