Implementa versiones canary de Cloud Run con ramas de Git y Cloud Build

Last reviewed 2023-05-26 UTC

En este documento, se muestra cómo implementar una canalización de implementación para Cloud Run que implemente el progreso del código desde las ramas del desarrollador hasta la producción con pruebas canary automatizadas y la administración del tráfico basada en porcentajes. Está dirigido a los administradores de la plataforma que son responsables de crear y administrar canalizaciones de CI/CD. En este documento, se supone que tienes un conocimiento básico de los conceptos de canalización de Git, Cloud Run y CI/CD.

Cloud Run te permite implementar y ejecutar tus aplicaciones con poca sobrecarga o esfuerzo. Muchas organizaciones usan canalizaciones de versiones sólidas para migrar el código a la producción. Cloud Run proporciona funciones de administración de tráfico únicas que te permiten implementar técnicas de administración de versiones avanzadas con poco esfuerzo.

Objetivos

  • Crea tu servicio de Cloud Run
  • Habilita una rama de desarrollador
  • Implementa pruebas canary
  • Lanzamiento seguro en producción

Costos

En este documento, usarás los siguientes componentes facturables de Google Cloud:

Para generar una estimación de costos en función del uso previsto, usa la calculadora de precios. Es posible que los usuarios nuevos de Google Cloud califiquen para obtener una prueba gratuita.

Antes de comenzar

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  2. Asegúrate de que la facturación esté habilitada para tu proyecto de Google Cloud.

  3. En la consola de Google Cloud, activa Cloud Shell.

    Activar Cloud Shell

    En la parte inferior de la consola de Google Cloud, se inicia una sesión de Cloud Shell en la que se muestra una ventana de línea de comandos. Cloud Shell es un entorno de shell con Google Cloud CLI ya instalada y con valores ya establecidos para el proyecto actual. La sesión puede tardar unos segundos en inicializarse.

Prepara tu entorno

  1. En Cloud Shell, crea variables de entorno para usar en este instructivo:

    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
  2. Habilita las siguientes API:

    • Resource Manager
    • GKE
    • Cloud Build
    • Container Registry
    • Cloud Run
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        secretmanager.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        run.googleapis.com
    
  3. Otorga el rol de Administrador de Cloud Run (roles/run.admin) a la cuenta de servicio de Cloud Build

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
      --role=roles/run.admin
    
  4. Otorga el rol de IAM de Usuario de cuenta de servicio a la cuenta de servicio de Cloud Build en la (roles/iam.serviceAccountUser) de cuenta de servicio del entorno de ejecución de Cloud Run

    gcloud iam service-accounts add-iam-policy-binding \
    $PROJECT_NUMBER-compute@developer.gserviceaccount.com \
      --member=serviceAccount:$PROJECT_NUMBER@cloudbuild.gserviceaccount.com \
      --role=roles/iam.serviceAccountUser
    

Configura valores de Git

Si nunca usaste Git en Cloud Shell, configura los valores user.name y user.email que deseas usar:

    git config --global user.email YOUR_EMAIL_ADDRESS
    git config --global user.name YOUR_USERNAME
    git config --global credential.helper store
  • YOUR_EMAIL_ADDRESS: Es el correo electrónico que se usa con tu cuenta de GitHub.
  • YOUR_USERNAME: Es el ID de usuario de GitHub.

Si usas MFA con GitHub, crea un token de acceso personal y úsalo como tu contraseña cuando interactúes con GitHub a través de la línea de comandos.

Almacena tu ID de usuario de GitHub en una variable de entorno para facilitar el acceso:

export GH_USER=YOUR_GITHUB_ID

Bifurca el repositorio del proyecto

Para crear tu propia versión de escritura del repositorio de labs, bifurca el repositorio de muestra en tu cuenta de GitHub a través de la IU de GitHub.

Clone el repositorio de muestra

Clona y prepara el repositorio de muestra:

git clone https://github.com/$GH_USER/software-delivery-workshop.git cloudrun-progression

cd cloudrun-progression/labs/cloudrun-progression

Conecta tu repositorio de Git.

Cloud Build te permite crear y administrar conexiones a repositorios de código fuente mediante la consola de Google Cloud. Puedes crear y administrar conexiones con la primera o la segunda generación de repositorios de Cloud Build. En este instructivo, se usan repositorios de Cloud Build de segunda generación.

Otorga los permisos necesarios

Para conectar tu host de GitHub, otorga la función de administrador de conexión de Cloud Build (roles/cloudbuild.connectionAdmin) a tu cuenta de usuario:

PN=$(gcloud projects describe ${PROJECT_ID} --format="value(projectNumber)")
CLOUD_BUILD_SERVICE_AGENT="service-${PN}@gcp-sa-cloudbuild.iam.gserviceaccount.com"
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
 --member="serviceAccount:${CLOUD_BUILD_SERVICE_AGENT}" \
 --role="roles/secretmanager.admin"

Crea la conexión del host

  1. Configura la conexión del repositorio de Cloud Build:

    gcloud alpha builds connections create github $GH_USER --region=us-central1
    
  2. Haz clic en el vínculo proporcionado en el resultado y sigue las instrucciones en pantalla para completar la conexión.

  3. Verifica la instalación de tu conexión de GitHub:

    gcloud alpha builds connections describe $GH_USER --region=us-central1
    

Mediante la conexión de host que acabas de configurar, vincula en el repositorio de muestra que bifurcaste:

 gcloud alpha builds repositories create cloudrun-progression \
     --remote-uri=https://github.com/$GH_USER/software-delivery-workshop.git \
     --connection=$GH_USER \
     --region=us-central1

Establece la variable de nombre del repositorio

Almacena el nombre del repositorio para usarlo más adelante:

export REPO_NAME=projects/$PROJECT_ID/locations/us-central1/connections/$GH_USER/repositories/cloudrun-progression

Implementa tu servicio de Cloud Run

En esta sección, compilarás y también implementarás la aplicación de producción inicial que usarás en este instructivo.

Implemente el servicio

  • En Cloud Shell, compila e implementa la aplicación, incluido un servicio que requiera autenticación. Para hacer un servicio público, usa la marca --allow-unauthenticated.

        gcloud builds submit --tag gcr.io/$PROJECT_ID/hello-cloudrun
    
        gcloud run deploy hello-cloudrun \
          --image gcr.io/$PROJECT_ID/hello-cloudrun \
          --platform managed \
          --region us-central1 \
          --tag=prod -q
    

    El resultado luce de la siguiente manera:

    Deploying container to Cloud Run service [hello-cloudrun] in project [sdw-mvp6] region [us-central1]
    ✓ Deploying new service... Done.
      ✓ Creating Revision...
      ✓ Routing traffic...
    Done.
    Service [hello-cloudrun] revision [hello-cloudrun-00001-tar] has been deployed and is serving 100 percent of traffic.
    Service URL: https://hello-cloudrun-apwaaxltma-uc.a.run.app
    The revision can be reached directly at https://prod---hello-cloudrun-apwaaxltma-uc.a.run.app
    

El resultado incluye la URL del servicio y una URL única para la revisión. Tus valores serán un poco diferentes de lo que se indica aquí.

Valida la implementación

  1. Una vez completada la implementación, visualiza el servicio recién implementado en la página Revisiones en la consola de Cloud.

  2. En Cloud Shell, observa la respuesta del servicio autenticado:

    PROD_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    
    echo $PROD_URL
    
    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $PROD_URL
    

Habilita implementaciones de ramas

En esta sección, habilitarás una URL única para las ramas de desarrollo en Git.

Configura el activador de rama

Cada rama se representa con una URL identificada por el nombre de la rama. Las confirmaciones de la rama activan una implementación, y las actualizaciones son accesibles en esa misma URL.

  1. En Cloud Shell, configura el activador:

    gcloud alpha builds triggers create github \
    --name=branchtrigger \
    --repository=$REPO_NAME \
    --branch-pattern='[^(?!.*main)].*' \
    --build-config=labs/cloudrun-progression/branch-cloudbuild.yaml \
    --region=us-central1
    
  2. Para revisar el activador, ve a la página Activadores de Cloud Build en la consola de Cloud.

Crea cambios en una rama

  1. En Cloud Shell, crea una rama de nombres nuevo:

    git checkout -b new-feature-1
    
  2. Abre la aplicación de muestra con tu editor favorito o el IDE de Cloud Shell:

    edit app.py
    
  3. En la aplicación de ejemplo, modifica la línea 24 para indicar que necesitas la versión 1.1 en lugar de la v1.0:

    @app.route('/')
    
    def hello_world():
        return 'Hello World v1.1'
    
    
  4. Para volver a tu terminal, haz clic en Abrir terminal.

Ejecuta el activador de rama

  1. En Cloud Shell, confirma el cambio y envíalo al repositorio remoto:

    git add . && git commit -m "updated" && git push origin new-feature-1
    
  2. Para revisar la compilación en curso, ve a la pantalla del historial de compilaciones de Cloud Build.

  3. Para revisar la nueva revisión, después de que se complete la compilación, ve a la página Revisiones de Cloud Run en la consola de Google Cloud:

  4. En Cloud Shell, obtén la URL única de esta rama:

    BRANCH_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.traffic[] | select (.tag==\"new-feature-1\")|.url")
    
    echo $BRANCH_URL
    
  5. Accede a la URL autenticada:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $BRANCH_URL
    

    El resultado de respuesta actualizado se verá como el siguiente:

    Hello World v1.1
    

Automatiza las pruebas que tienen una versión canary

Cuando el código se lanza a producción, es común lanzar código a un subconjunto pequeño de tráfico en vivo antes de migrar todo el tráfico a la base de código nueva.

En esta sección, implementarás un activador que se activa cuando se confirma el código en la rama principal. El activador implementa el código en una URL canary única y enruta el 10% de todo el tráfico en vivo a la revisión nueva.

  1. En Cloud Shell, configura el activador de la rama:

    gcloud alpha builds triggers create github \
      --name=maintrigger \
      --repository=$REPO_NAME \
      --branch-pattern=main \
      --build-config=labs/cloudrun-progression/main-cloudbuild.yaml \
      --region=us-central1
    
  2. Para revisar el activador nuevo, ve a la página Activadores de Cloud Build en la consola de Cloud.

  3. En Cloud Shell, combina la rama con la línea principal y envíala al repositorio remoto:

    git checkout main
    git merge new-feature-1
    git push origin main
    
  4. Para revisar la compilación en curso, ve a la página Compilaciones de Cloud Build.

  5. Una vez que se complete la compilación, ve a la página Revisiones de Cloud Run en la consola de Cloud para revisar la revisión nueva. Ten en cuenta que el 90% del tráfico se enruta a producción, el 10% a la versión canary y el 0% a las revisiones de la rama.

Revisa las líneas clave de main-cloudbuild.yaml que implementan la lógica de la implementación de versiones canary.

De las líneas 39 a 45 implementan la revisión nueva y usan la marca de etiqueta para enrutar el tráfico desde la URL Canary única:

gcloud run deploy ${_SERVICE_NAME} \
--platform managed \
--region ${_REGION} \
--image gcr.io/${PROJECT_ID}/${_SERVICE_NAME} \
--tag=canary \
--no-traffic

La línea 61 agrega una etiqueta estática a la revisión que indica el SHA corto de Git de la implementación:

gcloud beta run services update-traffic ${_SERVICE_NAME} --update-tags=sha-$SHORT_SHA=$${CANARY} --platform managed --region ${_REGION}

La línea 62 actualiza el tráfico para enrutar el 90% a la producción y el 10% a la versión canary:

gcloud run services update-traffic ${_SERVICE_NAME} --to-revisions=$${PROD}=90,$${CANARY}=10 --platform managed --region ${_REGION}
  1. En Cloud Shell, obtén la URL única para la revisión canary:

    CANARY_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.traffic[] | select (.tag==\"canary\")|.url")
    
    echo $CANARY_URL
    
  2. Revisa directamente el extremo de la versión canary:

    curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $CANARY_URL
    
  3. Para ver las respuestas basadas en porcentajes, realiza una serie de solicitudes:

    LIVE_URL=$(gcloud run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    for i in {0..20};do
      curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $LIVE_URL; echo \n
    done
    

De lanzamiento a producción

Una vez que la implementación de versiones canary se valida con un pequeño subconjunto de tráfico, libera la implementación en el resto del tráfico en vivo.

En esta sección, configurarás un activador que se activa cuando creas una etiqueta en el repositorio. El activador migra el 100% del tráfico a la revisión ya implementada según la confirmación de SHA de la etiqueta. Usar SHA de confirmación garantiza que la revisión validada con el tráfico de versiones canary sea la revisión que se usa para el resto del tráfico de producción.

  1. En Cloud Shell, configura el activador de etiquetas:

    gcloud alpha builds triggers create github \
      --name=tagtrigger \
      --repository=$REPO_NAME \
      --tag-pattern=. \
      --build-config=labs/cloudrun-progression/tag-cloudbuild.yaml \
      --region=us-central1
    
  2. Para revisar el activador nuevo, ve a la página Activadores de Cloud Build en la consola de Cloud.

  3. En Cloud Shell, crea una etiqueta nueva y envíala al repositorio remoto:

    git tag 1.1
    git push origin 1.1
    
  4. Para revisar la compilación en curso, ve a la pantalla del historial de compilación de Cloud Build en la consola de Cloud.

  5. Una vez que se complete la compilación, ve a la página Revisiones de Cloud Run en la consola de Cloud para revisar la revisión nueva. Ten en cuenta que la revisión se actualiza para indicar la etiqueta de producción y entrega el 100% del tráfico en vivo.

  6. En Cloud Shell, realiza una serie de solicitudes para ver respuestas basadas en porcentajes:

    LIVE_URL=$(gCloud Run services describe hello-cloudrun --platform managed --region us-central1 --format=json | jq --raw-output ".status.url")
    
    for i in {0..20};do
      curl -H "Authorization: Bearer $(gcloud auth print-identity-token)" $LIVE_URL; echo \n
    done
    
  7. Revisa las líneas de tag-cloudbuild.yaml que implementan la lógica de implementación de producción.

    La línea 37 actualiza la revisión canary mediante la adición de la etiqueta de producción. La revisión implementada ahora está etiquetada para producción y la versión canary:

    gcloud beta run services update-traffic ${_SERVICE_NAME} --update-tags=prod=$${CANARY} --platform managed --region ${_REGION}
    

    La línea 39 actualiza el tráfico de la URL del servicio base para enrutar el 100% del tráfico a la revisión etiquetada como producción:

    gcloud run services update-traffic ${_SERVICE_NAME} --to-revisions=$${NEW_PROD}=100 --platform managed --region ${_REGION}
    

Limpia

Para evitar que se apliquen cargos a tu cuenta de Google Cloud por los recursos usados en este instructivo, borra el proyecto que contiene los recursos o conserva el proyecto y borra los recursos individuales.

  1. En la consola de Google Cloud, ve a la página Administrar recursos.

    Ir a Administrar recursos

  2. En la lista de proyectos, elige el proyecto que quieres borrar y haz clic en Borrar.
  3. En el diálogo, escribe el ID del proyecto y, luego, haz clic en Cerrar para borrar el proyecto.

¿Qué sigue?