Implementaciones de Canary en GKE y GKE Enterprise con redes de la API de Gateway

En este documento, se describe cómo configurar y usar implementaciones canary para implementar tus aplicaciones en GKE o GKE Enterprise con Cloud Deploy y la malla de servicios de la API de Gateway de Kubernetes.

Una implementación de versiones canary es un lanzamiento progresivo de una nueva versión de tu aplicación, en el que aumentas gradualmente el porcentaje de tráfico que se envía a la nueva versión mientras supervisas el rendimiento de la aplicación. Esto te ayuda a detectar posibles problemas con anticipación y minimizar el impacto en tus usuarios.

Cómo funcionan las implementaciones canary para GKE y GKE Enterprise con la API de Gateway

  1. Además de las referencias de Deployment y Service, debes proporcionar un recurso de HTTPRoute, con una regla backendRefs que haga referencia al Service.

  2. Cloud Deploy crea una nueva Deployment, con el nombre de tu Deployment original más -canary, y un nuevo servicio con el nombre del servicio original más -canary.

    Los Secrets, los ConfigMaps y los escaladores automáticos horizontales de Pods también se copian y se les cambia el nombre con -canary.

  3. En cada fase de la versión canary, Cloud Deploy modifica el objeto HTTPRoute para actualizar la ponderación entre los pods de la Deployment original y los de la Deployment de la versión canary, según el porcentaje de esa fase.

    Dado que puede haber una demora en la propagación de los cambios en los recursos de HTTPRoute, puedes incluir la propiedad routeUpdateWaitTime en tu configuración para que el sistema espere una cantidad de tiempo especificada para esta propagación.

  4. Durante la fase de stable, la Deployment de -canary se reduce a cero y la Deployment original se actualiza para usar la Deployment de la nueva versión.

    Además, el objeto HTTPRoute ahora se revierte al original que proporcionaste.

    Cloud Deploy no modifica el objeto Deployment o Service original hasta la fase stable.

Con Cloud Deploy, puedes configurar implementaciones de versiones canary en GKE y GKE Enterprise en una sola etapa o en varias.

Las instrucciones que se incluyen aquí solo abarcan lo específico de la configuración de la versión canary. En el documento Implementa en un clúster de Google Kubernetes Engine, se incluyen las instrucciones generales para configurar y ejecutar tu canalización de implementación.

Asegúrate de tener los permisos necesarios

Además de otros permisos de Identity and Access Management que necesitas para usar Cloud Deploy, necesitas los siguientes permisos para realizar acciones adicionales que podrían ser necesarias para una implementación de versiones canary:

  • clouddeploy.rollouts.advance
  • clouddeploy.rollouts.ignoreJob
  • clouddeploy.rollouts.cancel
  • clouddeploy.rollouts.retryJob
  • clouddeploy.jobRuns.get
  • clouddeploy.jobRuns.list
  • clouddeploy.jobRuns.terminate

Consulta Roles y permisos de IAM para obtener más información sobre qué roles disponibles incluyen estos permisos.

Prepara tu skaffold.yaml

Tu archivo skaffold.yaml define cómo se renderizan y se implementan tus manifiestos de Kubernetes. Para que una implementación de versiones canary en GKE o GKE Enterprise funcione correctamente, asegúrate de que apunte correctamente a tus manifiestos y defina los artefactos de compilación necesarios. No se requiere ninguna configuración especial específica de la versión canary en skaffold.yaml más allá de lo que se necesita para una implementación estándar. Puedes usar perfiles de Skaffold para administrar diferentes variaciones de manifiestos para las fases de lanzamiento de versiones canary personalizadas.

Prepara tus manifiestos de Kubernetes

Tus manifiestos de Kubernetes deben incluir un recurso Deployment y un recurso Service. El Service debe definir un selector que coincida con las etiquetas de los Pods administrados por el Deployment. La etiqueta predeterminada que busca Cloud Deploy es app, pero se puede configurar en la canalización.

Además de Deployment y Service, tus manifiestos deben incluir un recurso HTTPRoute configurado para la división del tráfico, que haga referencia a Service y a la puerta de enlace asociada.

Configura una versión canary automatizada

Usa la API de Gateway de Kubernetes (con Istio o cualquier implementación compatible) para la división del tráfico precisa y basada en porcentajes que administra la malla o la puerta de enlace, y que coordina Cloud Deploy.

  1. Configura los recursos de la API de Gateway: Asegúrate de que tu puerta de enlace y la malla de servicios subyacente (p.ej., Istio) o el controlador de puerta de enlace estén configurados correctamente en tus clústeres.

  2. En el manifiesto de Kubernetes que se proporcionó a Cloud Deploy cuando creaste la versión, incluye lo siguiente:

    • Un HTTPRoute que hace referencia a tu recurso de Gateway

    • Es una Deployment.

    • Un servicio

  3. Configura tu canalización de entrega y el destino en el que realizarás la implementación de detección de fallos:

    • La configuración del destino es la misma que la de cualquier otro destino.

    • La configuración de la canalización de entrega, en la secuencia de progresión para el destino específico, incluye una sección gatewayServiceMesh para hacer referencia a la configuración de la API de Gateway de Kubernetes HTTPRoute, así como a tu Deployment y servicio.

      strategy:
       canary:
         runtimeConfig:
           kubernetes:
             gatewayServiceMesh:
               httpRoute: "ROUTE"
               service: "SERVICE"
               deployment: "DEPLOYMENT"
               routeUpdateWaitTime: "WAIT_TIME"
               podSelectorLabel: "LABEL"
         canaryDeployment:
           percentages:
           - 50
      

      En el ejemplo anterior, se ilustra lo siguiente:

      • ROUTE es la configuración de httpRoute que define el comportamiento de enrutamiento que deseas.

      • SERVICE es tu configuración de Service, que Cloud Deploy requiere para las implementaciones de versiones canary en GKE y GKE Enterprise.

      • DEPLOYMENT es tu configuración de Deployment, que Cloud Deploy requiere para las implementaciones de versiones canary en GKE y GKE Enterprise.

      • WAIT_TIME es un período durante el cual Cloud Deploy espera a que finalice la propagación de los cambios en el recurso HTTPRoute para evitar solicitudes descartadas. Por ejemplo: routeUpdateWaitTime: 60s.

        Si ejecutas una versión canary con la API de Gateway sin Istio y la API de Gateway está conectada a un balanceador de cargas Google Cloud , es posible que se pierda una pequeña cantidad de tráfico cuando se reduzca la instancia canary. Puedes configurar este parámetro si observas este comportamiento.

      • LABEL es una etiqueta del selector de Pods. Debe coincidir con el selector de etiquetas en el servicio y la Deployment de Kubernetes definidos en tu manifiesto. Esto es opcional. El valor predeterminado es app.

Configura una versión canary personalizada

Puedes configurar tu versión canary de forma manual en lugar de depender por completo de la automatización que proporciona Cloud Deploy. Con la configuración personalizada de la versión canary, puedes especificar lo siguiente en la definición de tu canalización de entrega:

  • Nombres de las fases de lanzamiento

    En una versión canary completamente automatizada, Cloud Deploy nombra las fases por ti (canary-25, canary-75, stable, por ejemplo). Sin embargo, con una versión canary personalizada, puedes asignar cualquier nombre a cada fase, siempre que sea único entre todas las fases de esta etapa de la versión canary y cumpla con las restricciones de ID de recursos. Sin embargo, el nombre de la fase final (100%) debe ser stable.

  • Objetivos de porcentaje para cada fase

    Especifica los porcentajes por separado, por fase.

  • Perfiles de Skaffold que se usarán para la fase

    Puedes usar un perfil de Skaffold independiente para cada fase, el mismo perfil o cualquier combinación. Además, cada perfil puede usar un manifiesto de Kubernetes diferente. También puedes usar más de un perfil para una fase determinada. Cloud Deploy los combina.

  • Indica si hay un trabajo de verificación para la fase.

    Recuerda que, si habilitas la verificación, también debes configurar tu skaffold.yaml para la verificación.

  • Indica si hay trabajos previos o posteriores a la implementación para la fase.

    Si habilitas trabajos previos a la implementación o posteriores a ella, debes configurar tu skaffold.yaml para esos trabajos.

Todos los tipos de destino son compatibles con la versión canary personalizada.

Elementos de configuración de versión canary personalizados

En el siguiente código YAML, se muestra la configuración de las fases de la implementación de canary completamente personalizada:

strategy:
  canary:
    # Custom configuration for each canary phase
    customCanaryDeployment:
      phaseConfigs:
      - phaseId: "PHASE1_NAME"
        percentage: PERCENTAGE1
        profiles: [ "PROFILE_NAME" ]
        verify: true | false
        predeploy:
          actions: "PREDEPLOY_ACTION"
        postdeploy:
          actions: "POSTDEPLOY_ACTION"
      - 
      - phaseId: "stable"
        percentage: 100
        profiles: [ "LAST_PROFILE_NAME" ]
        verify: true|false
        predeploy:
          actions: "PREDEPLOY_ACTION"
        postdeploy:
          actions: "POSTDEPLOY_ACTION"

En este archivo YAML

  • PHASE1_NAME

    Es el nombre de la fase. Cada nombre de fase debe ser único.

  • [ "PROFILE_NAME" ]

    Es el nombre del perfil que se usará para la fase. Puedes usar el mismo perfil para cada fase, uno diferente para cada una o cualquier combinación. También puedes especificar más de un perfil. Cloud Deploy usa todos los perfiles que especificas, además del perfil o manifiesto que usa la etapa general.

  • stable

    La fase final debe llamarse stable.

  • PERCENTAGE1

    Es el porcentaje de la implementación para la primera fase. Cada fase debe tener un valor de porcentaje único, y ese valor debe ser un porcentaje entero (no 10.5, por ejemplo), y las fases deben estar en orden ascendente.

  • verify: true|false

    Indica a Cloud Deploy si se debe incluir un trabajo de verificación para la fase. Ten en cuenta que, para que cada fase use la verificación, Skaffold usa el mismo perfil de verificación que se especifica para la renderización y la implementación de esa fase.

  • PREDEPLOY_ACTION

    Es el mismo que el ACTION_NAME que usaste en tu skaffold.yaml para definir la acción personalizada que deseas ejecutar antes de la implementación.

  • POSTDEPLOY_ACTION

    Es el mismo ACTION_NAME que usaste en tu skaffold.yaml para definir la acción personalizada que deseas ejecutar después de la implementación.

El porcentaje de la última fase debe ser 100. Las fases se ejecutan en el orden en que las configures en esta sección customCanaryDeployment, pero si los valores de porcentaje no están en orden ascendente, el comando para registrar la canalización de entrega falla con un error.

Ten en cuenta que la configuración de un canary personalizado de la API de Gateway no incluye una sección runtimeConfig. Si incluyes runtimeConfig, se considera una versión canary basada en un servicio personalizado.

Configura una versión canary personalizada y automatizada

Esto combina la definición de fases personalizadas (nombres, porcentajes, perfiles, verificación, hooks) con la administración automática del tráfico de Cloud Deploy para GKE o GKE Enterprise. Tú defines las fases, pero Cloud Deploy controla la manipulación de recursos subyacentes según los porcentajes y el runtimeConfig elegido.

Para configurar esto, incluye una sección runtimeConfig con serviceNetworking y la sección customCanaryDeployment (que define phaseConfigs) dentro del bloque strategy.canary. Cloud Deploy usará los perfiles de Skaffold especificados para la renderización, pero ajustará automáticamente el tráfico según los porcentajes de runtimeConfig y de fase.

serialPipeline:
  stages:
  - targetId: gke-prod
    profiles: []
    strategy:
      canary:
        # Include runtimeConfig for automatic traffic management
        runtimeConfig:
          kubernetes:
            gatewayServiceMesh:
              httpRoute: "my-route"
              service: "my-app"
              deployment: "my-deployment"  
        # Include customCanaryDeployment for phase customization
        customCanaryDeployment:
          phaseConfigs:
          - phaseId: "warmup"
            percentage: 10
            profiles: ["profile-a"] # Profile used for rendering this phase
            verify: true
          - phaseId: "scaling"
            percentage: 50
            profiles: ["profile-b"] # Different profile for this phase
            verify: true
          - phaseId: "stable"
            percentage: 100
            profiles: ["profile-b"] # Can reuse profiles
            verify: true

Implementa una HTTPRoute en un clúster diferente

Cuando tienes una versión canary configurada con la malla de servicios de la API de Gateway, puedes especificar un clúster alternativo que no sea el de destino en el que implementar la HTTPRoute.

Para ello, usa una estrofa routeDestinations en la configuración de tu estrategia de lanzamiento canary para identificar el clúster o los clústeres de destino de HTTPRoute y un parámetro de configuración booleano para propagar el servicio al mismo clúster que no es de destino. Además, creas una sección associatedEntities en la configuración de destino para identificar los clústeres.

  1. Configura associatedEntities en tu destino.

    Cada entidad es un clúster en el que Cloud Deploy implementará el objeto HTTPRoute y, de manera opcional, el servicio de Kubernetes. En la definición del destino, incluye una sección associatedEntities:

    associatedEntities:
      [KEY]:
        gkeClusters:
        - cluster: [PATH]
          dnsEndpoint: [true|false]
          internalIp: [true|false]
          proxyUrl:
    

    Aquí:

    • KEY es un nombre arbitrario para este grupo de entidades asociadas. Usarás este nombre para hacer referencia a las entidades de routeDestinations en tu configuración de versión canary.

    • PATH es la ruta de acceso al recurso que identifica el clúster de GKE en el que se implementará tu HTTPRoute (y, de manera opcional, el Service).

    • dnsEndpoint indica si se debe usar el extremo de DNS del clúster en caso de que se hayan configurado varios extremos. El valor predeterminado es false.

    • internalIp indica si se debe usar la IP interna (IP privada) del clúster si se configuraron varios extremos. El valor predeterminado es false.

    Puedes incluir la cantidad de clústeres que desees, con o sin internalIp.

  2. Configura routeDestinations en tu configuración de versión canary.

    Cada destino de ruta hace referencia a una sección associatedEntities y indica si también se debe implementar el servicio en el clúster alternativo. Agrega lo siguiente dentro de la estrofa gatewayServiceMesh en tu configuración de versión canary:

    routeDestinations:
      destinationIds: ["KEY"]
      propagateService: [true|false]
    

    Aquí:

    • KEY es el nombre que configuraste en el destino, en associatedEntities. Usa este nombre para hacer referencia a las entidades de routeDestinations en tu configuración de versión canary.

      También puedes proporcionar el valor @self para implementar el objeto HTTPRoute en el clúster de destino, además del destino asociado.

    • propagateService indica si deseas implementar el servicio en el clúster asociado, además de la HTTPRoute. El valor predeterminado es false.

Ejecuta la versión canary de GKE o GKE Enterprise

  1. Registra la canalización y los destinos: Aplica los archivos de configuración de tu canalización de entrega y de destino de GKE o GKE Enterprise.

    
    gcloud deploy apply --file=delivery-pipeline.yaml --region=REGION
    gcloud deploy apply --file=gke-targets.yaml --region=REGION
    

    La canalización de entrega incluye la configuración de versión canary automatizada o personalizada para el entorno de ejecución que elegiste.

  2. Crea una versión: Inicia la implementación y proporciona el nombre de la imagen.

    
    gcloud deploy releases create RELEASE_NAME \
                                    --delivery-pipeline=PIPELINE_NAME \
                                    --region=REGION
      # e.g., --images=my-cloudrun-service=gcr.io/my-project/my-app:v1.1
      # Add --skaffold-file or --source if not using default Skaffold config discovery
    

    La canalización de entrega identificada por PIPELINE_NAME contiene la configuración de versión canary automatizada o personalizada que se describe en este documento.

  3. Avanza la versión canary:

    gcloud CLI

    gcloud deploy rollouts advance ROLLOUT_NAME \
                                --release=RELEASE_NAME \
                                --delivery-pipeline=PIPELINE_NAME \
                                --region=REGION
    

    Aquí:

    ROLLOUT_NAME es el nombre de la versión actual que se avanza a la siguiente fase.

    RELEASE_NAME es el nombre de la versión de la que forma parte esta implementación.

    PIPELINE_NAME es el nombre de la canalización de entrega que usas para administrar la implementación de esta versión.

    REGION es el nombre de la región en la que se creó la versión, por ejemplo, us-central1. Este campo es obligatorio.

    Consulta la referencia del SDK de Google Cloud para obtener más información sobre el comando gcloud deploy rollouts advance.

    Google Cloud console

    1. Abre la página Canalizaciones de entrega.

    2. Haz clic en tu canalización que se muestra en la lista de canalizaciones de entrega.

      En la página Detalles de la canalización de entrega, se muestra una representación gráfica del progreso de tu canalización de entrega.

    3. En la pestaña Lanzamientos, en Detalles de la canalización de entrega, haz clic en el nombre de tu lanzamiento.

      Se muestra la página de detalles del lanzamiento.

      Detalles del lanzamiento en la consola de Google Cloud

      Observa que, en este ejemplo, la versión tiene una fase canary-50 y una fase stable. Es posible que tu lanzamiento tenga más fases o fases diferentes.

    4. Haz clic en Adelantar lanzamiento.

      El lanzamiento avanza a la siguiente fase.

Fases omitidas

Si implementas una versión canary y tu aplicación aún no se implementó en ese entorno de ejecución, Cloud Deploy omitirá la fase canary y ejecutará la fase estable. Consulta Cómo omitir fases la primera vez para saber por qué sucede esto.

¿Qué sigue?