Ejecuta y escala ejecutores de GitHub autoalojados en grupos de trabajadores de Cloud Run

En este instructivo, se muestra cómo usar ejecutores de GitHub autohospedados en grupos de trabajadores para ejecutar los flujos de trabajo definidos en tu repositorio de GitHub y cómo ajustar la escala de tu grupo de trabajadores con el ajuste de escala automático basado en métricas externas de Cloud Run (CREMA).

Acerca de los ejecutores de GitHub autoalojados

En un flujo de trabajo de GitHub Actions, los ejecutores son las máquinas que ejecutan trabajos. Por ejemplo, un ejecutor puede clonar tu repositorio de forma local, instalar software de prueba y, luego, ejecutar comandos que evalúen tu código.

Puedes usar ejecutores autoalojados para ejecutar acciones de GitHub en instancias del grupo de trabajadores de Cloud Run. En este instructivo, se muestra cómo escalar automáticamente un grupo de ejecutores según la cantidad de trabajos en ejecución y no programados.

Objetivos

En este instructivo, podrás:

Costos

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

Para obtener 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 cumplan con los requisitos para acceder a una prueba gratuita.

Antes de comenzar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

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

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. Enable the Cloud Run, Secret Manager, Parameter Manager, Artifact Registry, and Cloud Build APIs.

    Roles required to enable APIs

    To enable APIs, you need the Service Usage Admin IAM role (roles/serviceusage.serviceUsageAdmin), which contains the serviceusage.services.enable permission. Learn how to grant roles.

    Enable the APIs

  7. Instala y, luego, inicializa gcloud CLI.
  8. Actualiza los componentes, como se indica a continuación:
    gcloud components update
  9. Establece las siguientes variables de configuración para CREMA que se usan en este instructivo:
    PROJECT_ID=PROJECT_ID
    CREMA_SERVICE_ACCOUNT_NAME=crema-service-account@$PROJECT_ID.iam.gserviceaccount.com
    CREMA_REPO_NAME=crema
    AR_REGION=us-central1
    Reemplaza PROJECT_ID por el ID de tu proyecto Google Cloud .
  10. Se te cobrarán cargos por tu servicio de escalamiento de Cloud Run según la frecuencia con la que actives el escalamiento. Para obtener más información, calcula los costos con la calculadora de precios.
  11. Roles obligatorios

    Si quieres obtener los permisos que necesitas para completar el instructivo, pídele a tu administrador que te otorgue los siguientes roles de IAM en tu proyecto:

    Para obtener más información sobre cómo otorgar roles, consulta Administra el acceso a proyectos, carpetas y organizaciones.

    También puedes obtener los permisos necesarios mediante roles personalizados o cualquier otro rol predefinido.

    Necesitas permiso para editar la configuración de un repositorio de GitHub y configurar los ejecutores autoalojados. El repositorio puede ser propiedad del usuario o de una organización.

    GitHub recomienda usar ejecutores autoalojados solo con repositorios privados.

    Crea una cuenta de servicio personalizada

    En este instructivo, se usa una cuenta de servicio personalizada con los permisos mínimos requeridos para usar los recursos aprovisionados. Para configurar la cuenta de servicio, haz lo siguiente:

    gcloud iam service-accounts create crema-service-account \
      --display-name="CREMA Service Account"
    

Agrega ejecutores de GitHub autoalojados

Para agregar ejecutores de GitHub autohospedados, sigue las instrucciones en cómo agregar ejecutores autohospedados en la documentación de GitHub.

Identifica el repositorio de GitHub

En este instructivo, la variable GITHUB_REPO representa el nombre del repositorio. Esta es la parte del nombre que se encuentra después del nombre de dominio, tanto para los repositorios de usuarios personales como para los de organizaciones. Por ejemplo:

  • Si la URL de tu dominio es https://github.com/myuser/myrepo, el GITHUB_REPO es myuser/myrepo.
  • Si la URL de tu dominio es https://github.com/mycompany/ourrepo, el GITHUB_REPO es mycompany/ourrepo.

Crea un token de acceso

Crea un token de acceso de GitHub para agregar y quitar ejecutores de forma dinámica interactuando con el repositorio seleccionado. Para crear un token de acceso en GitHub y guardarlo en Secret Manager, sigue estos pasos:

  1. Asegúrate de haber accedido a tu cuenta de GitHub.
  2. Navega a la página Configuración > Configuración para desarrolladores > Tokens de acceso personal > Tokens (clásicos) de GitHub.
  3. Haz clic en Generate new token y selecciona Generate new token (classic).
  4. En el alcance del token, selecciona la casilla de verificación repo.
  5. Haz clic en Generate token.
  6. Copia el token generado.

Para obtener más información sobre los tokens de acceso, consulta los requisitos de autenticación en la documentación de GitHub.

Crea un secreto para tu token de acceso con Secret Manager

Toma el token secreto que creaste en el paso anterior y almacénalo en Secret Manager. Para configurar los permisos de acceso, sigue estos pasos:

  1. Crea el secreto en Secret Manager:

    echo -n "GITHUB_TOKEN" | gcloud secrets create github_runner_token --data-file=-
    

    Reemplaza GITHUB_TOKEN por el valor que copiaste de GitHub.

  2. Otorga el permiso roles/secretmanager.secretAccessor a tu cuenta de servicio personalizada para acceder al secreto recién creado:

    gcloud secrets add-iam-policy-binding github_runner_token \
      --member "serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role "roles/secretmanager.secretAccessor"
    

Implementa un grupo de trabajadores

Crea un grupo de trabajadores de Cloud Run para procesar acciones de GitHub. Este grupo usará una imagen basada en la imagen actions/runner creada por GitHub. Para implementar un grupo de trabajadores, sigue estos pasos:

  1. Clona el repositorio de muestra en tu máquina local para recuperar la muestra de código que usarás:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples
    
  2. Ve al directorio que contiene el código de muestra de Cloud Run:

    cd cloud-run-samples/github-runner/worker-pool-container
    
  3. Implementa el grupo de trabajadores:

    gcloud beta run worker-pools deploy WORKER_POOL_NAME \
      --region us-central1 \
      --source . \
      --instances 1 \
      --set-env-vars GITHUB_REPO=GITHUB_REPO \
      --set-secrets GITHUB_TOKEN=github_runner_token:latest \
      --service-account $CREMA_SERVICE_ACCOUNT_NAME \
      --memory 2Gi \
      --cpu 4
    

    Reemplaza lo siguiente:

    • WORKER_POOL_NAME: El nombre del grupo de trabajadores
    • WORKER_POOL_LOCATION: la región del grupo de trabajadores
    • GITHUB_REPO: El nombre del repositorio de GitHub

    Si es la primera vez que usas implementaciones desde la fuente de Cloud Run en este proyecto, Cloud Run te solicitará que crees un repositorio predeterminado de Artifact Registry.

Comprende el muestra de código

El grupo de trabajadores se configura con un Dockerfile basado en la imagen actions/runner creada por GitHub:

FROM ghcr.io/actions/actions-runner:2.330.0

# Add scripts with right permissions.
USER root
# hadolint ignore=DL3045
COPY start.sh start.sh
RUN chmod +x start.sh

# Add start entrypoint with right permissions.
USER runner
ENTRYPOINT ["./start.sh"]

Esta secuencia de comandos auxiliar se ejecuta cuando se inicia el contenedor y se registra en el repositorio configurado como una instancia efímera con un token que creas.

# Configure the current runner instance with URL, token and name.
mkdir /home/docker/actions-runner && cd /home/docker/actions-runner
echo "GitHub Repo: ${GITHUB_REPO_URL} for ${RUNNER_PREFIX}-${RUNNER_SUFFIX}"
./config.sh --unattended --url ${GITHUB_REPO_URL} --pat ${GH_TOKEN} --name ${RUNNER_NAME}

# Function to cleanup and remove runner from Github.
cleanup() {
   echo "Removing runner..."
   ./config.sh remove --unattended --pat ${GH_TOKEN}
}

# Trap signals.
trap 'cleanup; exit 130' INT
trap 'cleanup; exit 143' TERM

# Run the runner.
./run.sh & wait $!

Usa el grupo de trabajadores para aceptar trabajos de las acciones de GitHub

Tu instancia del grupo de trabajadores está lista para aceptar trabajos de las acciones de GitHub.

Si tu repo aún no tiene ninguna acción de GitHub, sigue las instrucciones de la guía de inicio rápido para crear tu primer flujo de trabajo.

Si tu repo tiene acciones de GitHub, invoca una acción de GitHub en tu repositorio para verificar que completaste la configuración de tu ejecutor autoalojado.

Si tu acción de GitHub no usa ejecutores autoalojados, cambia el trabajo de tu acción de GitHub del valor runs-on a self-hosted.

Una vez que hayas configurado una acción para usar los ejecutores autohospedados, ejecútala.

Confirma que la acción se complete correctamente en la interfaz de GitHub.

Implementa el servicio CREMA del escalador automático

Implementaste un trabajador en tu grupo original, lo que permite procesar una acción a la vez. Según tu uso de la integración continua (CI), es posible que debas escalar tu grupo para controlar una afluencia de trabajo por hacer.

Una vez que implementes el grupo de trabajadores con un ejecutor de GitHub activo, configura el escalador automático de CREMA para aprovisionar instancias de trabajadores según el estado del trabajo en la cola de acciones.

Esta implementación escucha un evento workflow_job. Cuando creas un trabajo de flujo de trabajo, se aumenta la cantidad de trabajadores del grupo y, una vez que se completa el trabajo, se reduce nuevamente. No se ajustará más allá de la cantidad máxima de instancias que configures y se reducirá a cero cuando se completen todos los trabajos en ejecución.

Puedes adaptar CREMA según tus cargas de trabajo.

Configurar el escalador automático

En este instructivo, se usa Parameter Manager para almacenar el archivo de configuración YAML de CREMA.

  1. Crea un parámetro en el Administrador de parámetros para almacenar versiones de parámetros de CREMA:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. Crea un archivo YAML, my-crema-config.yaml, en el directorio principal para definir la configuración del ajuste automático de escala:

    apiVersion: crema/v1
    kind: CremaConfig
    metadata:
      name: gh-demo
    spec:
      pollingInterval: 10
      triggerAuthentications:
        - metadata:
            name: github-trigger-auth
          spec:
            gcpSecretManager:
              secrets:
                - parameter: personalAccessToken
                  id: github_runner_token
                  version: latest
      scaledObjects:
        - spec:
            scaleTargetRef:
              name: projects/PROJECT_ID/locations/us-central1/workerpools/WORKER_POOL_NAME
            triggers:
              - type: github-runner
                name: GITHUB_RUNNER
                metadata:
                  owner: REPOSITORY_OWNER
                  runnerScope: repo
                  repos: REPOSITORY_NAME
                  targetWorkflowQueueLength: 1
                authenticationRef:
                  name: github-trigger-auth
            advanced:
              horizontalPodAutoscalerConfig:
                behavior:
                  scaleDown:
                    stabilizationWindowSeconds: 10
                    policies:
                      - type: Pods
                        value: 100
                        periodSeconds: 10
                  scaleUp:
                    stabilizationWindowSeconds: 10
                    policies:
                      - type: Pods
                        value: 2
                        periodSeconds: 10
    
    

    Reemplaza lo siguiente:

    • PROJECT_ID: Es el ID del proyecto de Google Cloud .
    • WORKER_POOL_NAME: El nombre del grupo de trabajadores que implementaste
    • GITHUB_RUNNER: El nombre del ejecutor de GitHub que configuraste
    • REPOSITORY_OWNER: El propietario del repositorio de GitHub
    • REPOSITORY_NAME: El nombre del repositorio de GitHub
  3. Sube tu archivo YAML local como una nueva versión del parámetro:

    LOCAL_YAML_CONFIG_FILE=my-crema-config.yaml
    PARAMETER_VERSION=1
    
    gcloud parametermanager parameters versions create $PARAMETER_VERSION \
      --location=$PARAMETER_REGION \
      --parameter=$PARAMETER_ID \
      --payload-data-from-file=$LOCAL_YAML_CONFIG_FILE
    

Otorga permisos adicionales a tu cuenta de servicio personalizada

Para escalar el grupo de trabajadores que especificaste en tu configuración de YAML, otorga los siguientes permisos en la cuenta de servicio personalizada:

  1. Otorga permiso a tu cuenta de servicio de CREMA para leer desde Parameter Manager:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role="roles/parametermanager.parameterViewer"
    
  2. Otorga a tu cuenta de servicio de CREMA el rol de roles/run.developer en el grupo de trabajadores:

    WORKER_POOL_NAME=WORKER_POOL_NAME
    WORKER_POOL_REGION=us-central1
    gcloud beta run worker-pools add-iam-policy-binding $WORKER_POOL_NAME \
      --region=$WORKER_POOL_REGION \
      --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role="roles/run.developer"
    

    Reemplaza WORKER_POOL_NAME por el nombre del grupo de trabajadores.

  3. Otorga permiso a tu cuenta de servicio de CREMA para escribir métricas:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
       --role="roles/monitoring.metricWriter"
    
  4. Otorga a tu cuenta de servicio de CREMA el rol de usuario de la cuenta de servicio:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role="roles/iam.serviceAccountUser"
    

Implementa el servicio para escalar tus cargas de trabajo

Para implementar el servicio y escalar tu grupo de trabajadores, ejecuta el siguiente comando con una imagen de contenedor compilada previamente:

SERVICE_NAME=my-crema-service
SERVICE_REGION=us-central1

CREMA_CONFIG_PARAM_VERSION=projects/$PROJECT_ID/locations/$PARAMETER_REGION/parameters/$PARAMETER_ID/versions/$PARAMETER_VERSION
IMAGE=us-central1-docker.pkg.dev/cloud-run-oss-images/crema-v1/autoscaler:1.0

gcloud beta run deploy $SERVICE_NAME \
  --image=${IMAGE} \
  --region=${SERVICE_REGION} \
  --service-account="${CREMA_SERVICE_ACCOUNT_NAME}" \
  --no-allow-unauthenticated \
  --no-cpu-throttling \
  --base-image=us-central1-docker.pkg.dev/serverless-runtimes/google-22/runtimes/java21 \
  --labels=created-by=crema \
  --set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True"

Crea un valor secreto de webhook

Para crear un valor secreto que permita acceder al webhook de GitHub, haz lo siguiente:

  1. Crea un secreto de Secret Manager para administrar el acceso a tu webhook de GitHub.

    echo -n "WEBHOOK_SECRET" | gcloud secrets create github_webhook_secret --data-file=-
    

    Reemplaza WEBHOOK_SECRET por un valor de cadena arbitrario.

  2. Otorga acceso al secreto a la cuenta de servicio del escalador automático:

    gcloud secrets add-iam-policy-binding github_webhook_secret \
      --member "serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role "roles/secretmanager.secretAccessor"
    

Crea un webhook de GitHub

Para crear el webhook de GitHub, sigue estos pasos:

  1. Asegúrate de haber accedido a tu cuenta de GitHub.
  2. Navega a tu repositorio de GitHub.
  3. Haz clic en Configuración.
  4. En Código y automatización, haz clic en Webhooks.
  5. Haz clic en Add webhook (Agregar webhook).
  6. Ingresa lo siguiente:

    1. En URL de carga útil, ingresa la URL del servicio de CREMA de Cloud Run que implementaste, my-crema-service.
    2. En Content type, selecciona application/json.
    3. En Secret, ingresa el valor de WEBHOOK_SECRET que creaste antes.
    4. En Verificación de SSL, selecciona Habilitar la verificación de SSL.
    5. En ¿Qué eventos deseas que activen este webhook?, selecciona Permítanme seleccionar eventos individuales.
    6. En la selección de eventos, elige Trabajos de flujo de trabajo. Anula la selección de cualquier otra opción.
    7. Haz clic en Add webhook (Agregar webhook).

Prueba tu servicio de CREMA

Para verificar que tu servicio de ajuste de escala automático funcione correctamente, consulta la pestaña Registros del servicio de Cloud Run.

Deberías ver los siguientes registros en los registros de tu servicio cada vez que se actualicen las métricas:

Cada mensaje de registro está etiquetado con el componente que lo emitió.

[INFO] [METRIC-PROVIDER] Starting metric collection cycle
[INFO] [METRIC-PROVIDER] Successfully fetched scaled object metrics ...
[INFO] [METRIC-PROVIDER] Sending scale request ...
[INFO] [SCALER] Received ScaleRequest ...
[INFO] [SCALER] Current instances ...
[INFO] [SCALER] Recommended instances ...

Realiza una limpieza

Para evitar cargos adicionales en tu cuenta de Google Cloud , borra todos los recursos que implementaste con este instructivo.

Borra el proyecto

Si creaste un proyecto nuevo para este instructivo, bórralo. Si usaste un proyecto existente y necesitas conservarlo sin los cambios que agregaste en este instructivo, borra los recursos que creaste para el instructivo.

La manera más fácil de eliminar la facturación es borrar el proyecto que creaste para el instructivo.

Para borrar el proyecto, sigue los pasos que se indican más abajo:

  1. In the Google Cloud console, go to the Manage resources page.

    Go to Manage resources

  2. In the project list, select the project that you want to delete, and then click Delete.
  3. In the dialog, type the project ID, and then click Shut down to delete the project.

Elimina recursos de instructivos

  1. Borra el servicio de Cloud Run que implementaste en este instructivo. Los servicios de Cloud Run no generan costos hasta que reciben solicitudes.

    Para borrar tu servicio de Cloud Run, ejecuta el siguiente comando:

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME por el nombre del servicio

    También puedes borrar los servicios de Cloud Run desde la consola deGoogle Cloud .

  2. Quita la configuración de región predeterminada de gcloud que agregaste durante la configuración del instructivo:

     gcloud config unset run/region
    
  3. Quita la configuración del proyecto:

     gcloud config unset project
    
  4. Borra otros recursos Google Cloud que creaste en este instructivo:

¿Qué sigue?