Executar e escalonar executores auto-hospedados do GitHub em pools de workers do Cloud Run

Neste tutorial, mostramos como usar executores autohospedados do GitHub em pools de workers para executar os fluxos de trabalho definidos no seu repositório do GitHub e escalonar o pool de workers com o escalonamento automático de métricas externas do Cloud Run (CREMA).

Sobre executores auto-hospedados do GitHub

Em um fluxo de trabalho do GitHub Actions, os executores são as máquinas que executam jobs. Por exemplo, um executor pode clonar seu repositório localmente, instalar um software de teste e executar comandos que avaliam seu código.

É possível usar executores auto-hospedados para executar ações do GitHub em instâncias de pool de trabalhadores do Cloud Run. Neste tutorial, mostramos como escalonar automaticamente um pool de executores com base no número de jobs em execução e não programados.

Objetivos

Com este tutorial, você vai:

Custos

Neste documento, você vai usar os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na sua projeção de uso, utilize a calculadora de preços.

Novos usuários do Google Cloud podem estar qualificados para um teste sem custo financeiro.

Antes de começar

  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. Instale e inicialize a gcloud CLI.
  8. Atualize os componentes:
    gcloud components update
  9. Defina as seguintes variáveis de configuração para o CREMA usado neste tutorial:
    PROJECT_ID=PROJECT_ID
    CREMA_SERVICE_ACCOUNT_NAME=crema-service-account@$PROJECT_ID.iam.gserviceaccount.com
    CREMA_REPO_NAME=crema
    AR_REGION=us-central1
    Substitua PROJECT_ID pelo ID do seu projeto do Google Cloud .
  10. Você recebe cobranças pelo serviço de escalonamento do Cloud Run com base na frequência com que aciona o escalonamento. Para mais informações, estime os custos com a calculadora de preços.
  11. Funções exigidas

    Para conseguir as permissões necessárias para concluir o tutorial, peça ao administrador para conceder a você os seguintes papéis do IAM no seu projeto:

    Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

    Também é possível conseguir as permissões necessárias por meio de papéis personalizados ou de outros papéis predefinidos.

    Você precisa de permissão para editar as configurações de um repositório do GitHub e configurar os executores autohospedados. O repositório pode ser de propriedade do usuário ou de uma organização.

    O GitHub recomenda usar executores auto-hospedados apenas com repositórios privados.

    Criar uma conta de serviço personalizada

    Este tutorial usa uma conta de serviço personalizada com as permissões mínimas necessárias para usar os recursos provisionados. Para configurar a conta de serviço, faça o seguinte:

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

Adicionar executores auto-hospedados do GitHub

Para adicionar executores do GitHub autohospedados, siga as instruções em Adicionar executores autohospedados na documentação do GitHub.

Identificar o repositório do GitHub

Neste tutorial, a variável GITHUB_REPO representa o nome do repositório. Essa é a parte do nome que você encontra depois do nome de domínio para repositórios de usuários pessoais e de organizações. Exemplo:

  • Se o URL do seu domínio for https://github.com/myuser/myrepo, o GITHUB_REPO será myuser/myrepo.
  • Se o URL do seu domínio for https://github.com/mycompany/ourrepo, o GITHUB_REPO será mycompany/ourrepo.

Criar token de acesso

Crie um token de acesso do GitHub para adicionar e remover executores dinamicamente interagindo com o repositório selecionado. Para criar um token de acesso no GitHub e salvá-lo no Secret Manager, siga estas etapas:

  1. Confira se você fez login na sua conta do GitHub.
  2. Navegue até a página Configurações > Configurações do desenvolvedor > Tokens de acesso pessoal > Tokens (clássico) do GitHub.
  3. Clique em Gerar novo token e selecione Gerar novo token (clássico).
  4. Para o escopo do token, marque a caixa de seleção repo.
  5. Clique em Gerar token.
  6. Copie o token gerado.

Para mais informações sobre tokens de acesso, consulte Requisitos de autenticação na documentação do GitHub.

Criar um secret para seu token de acesso usando o Secret Manager

Pegue o token secreto que você criou na etapa anterior e armazene-o no Secret Manager. Para definir permissões de acesso, siga estas etapas:

  1. Crie o secret no Secret Manager:

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

    Substitua GITHUB_TOKEN pelo valor que você copiou do GitHub.

  2. Conceda o roles/secretmanager.secretAccessor à sua conta de serviço personalizada para acessar o secret recém-criado:

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

Implantar um pool de workers

Crie um pool de workers do Cloud Run para processar ações do GitHub. Esse pool vai usar uma imagem baseada na imagem actions/runner criada pelo GitHub. Para implantar um pool de trabalhadores, siga estas etapas:

  1. Clone o repositório de amostra na máquina local para recuperar o exemplo de código para uso:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples
    
  2. Mude para o diretório que contém o código de amostra do Cloud Run:

    cd cloud-run-samples/github-runner/worker-pool-container
    
  3. Implante o pool de workers:

    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
    

    Substitua:

    Se esta for a primeira vez que você usa implantações de origem do Cloud Run neste projeto, o Cloud Run vai pedir que você crie um repositório padrão do Artifact Registry.

Entender o exemplo de código

O pool de workers é configurado com um Dockerfile baseado na imagem actions/runner criada pelo 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"]

Esse script auxiliar é executado quando o contêiner é iniciado, registrando-se no repositório configurado como uma instância efêmera, usando um token criado por você.

# 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 $!

Usar o pool de workers para aceitar jobs do GitHub Actions

Sua instância de pool de trabalhadores está pronta para aceitar jobs das ações do GitHub.

Se o repositório ainda não tiver nenhuma ação do GitHub, siga as instruções no início rápido para criar seu primeiro fluxo de trabalho.

Se o repositório tiver ações do GitHub, verifique se você concluiu a configuração do executor autohospedado invocando uma ação do GitHub no repositório.

Se a ação do GitHub não usar executores auto-hospedados, mude o job da ação do GitHub do valor runs-on para self-hosted.

Depois de configurar uma ação para usar os executores autohospedados, execute-a.

Confirme se a ação foi concluída com sucesso na interface do GitHub.

Implante o serviço CREMA do escalonador automático

Você implantou um worker no pool original, o que permite o processamento de uma ação por vez. Dependendo do seu uso de integração contínua (CI), talvez seja necessário escalonar o pool para lidar com um aumento de trabalho a ser feito.

Depois de implantar o pool de workers com um runner do GitHub ativo, configure o escalonador automático do CREMA para provisionar instâncias de worker com base no status do job na fila de ações.

Essa implementação detecta um evento workflow_job. Quando você cria um job de fluxo de trabalho, ele aumenta o pool de workers e, quando o job é concluído, ele diminui novamente. Ele não vai escalonar o pool além do número máximo de instâncias configuradas e será reduzido a zero quando todos os jobs em execução forem concluídos.

É possível adaptar o CREMA com base nas suas cargas de trabalho.

Configurar o autoescalador

Neste tutorial, usamos o Gerenciador de parâmetros para armazenar o arquivo de configuração YAML do CREMA.

  1. Crie um parâmetro no Gerenciador de parâmetros para armazenar versões de parâmetros para o CREMA:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. Crie um arquivo YAML, my-crema-config.yaml, no diretório pai para definir a configuração do escalonador automático:

    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
    
    

    Substitua:

    • PROJECT_ID: o ID do projeto Google Cloud
    • WORKER_POOL_NAME: o nome do pool de workers implantado
    • GITHUB_RUNNER: o nome do executor do GitHub que você configurou
    • REPOSITORY_OWNER: o proprietário do repositório do GitHub
    • REPOSITORY_NAME: o nome do repositório do GitHub
  3. Faça upload do arquivo YAML local como uma nova versão de 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
    

Conceder outras permissões à sua conta de serviço personalizada

Para escalonar o pool de workers especificado na configuração YAML, conceda as seguintes permissões na conta de serviço personalizada:

  1. Conceda à sua conta de serviço do CREMA permissão para ler do Gerenciador de parâmetros:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role="roles/parametermanager.parameterViewer"
    
  2. Conceda à conta de serviço do CREMA o papel roles/run.developer no pool de workers:

    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"
    

    Substitua WORKER_POOL_NAME pelo nome do pool de workers.

  3. Conceda à sua conta de serviço do CREMA permissão para gravar métricas:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
       --role="roles/monitoring.metricWriter"
    
  4. Conceda à sua conta de serviço do CREMA o função do usuário da conta de serviço:

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

Implante o serviço para escalonar suas cargas de trabalho

Para implantar o serviço e escalonar o pool de workers, execute o seguinte comando com uma imagem de contêiner pré-criada:

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"

Criar valor de secret do webhook

Para criar um valor secreto e acessar o webhook do GitHub, faça o seguinte:

  1. Crie um secret do Secret Manager para gerenciar o acesso ao webhook do GitHub.

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

    Substitua WEBHOOK_SECRET por um valor de string arbitrário.

  2. Conceda acesso ao secret para a conta de serviço do escalonador automático:

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

Criar webhook do GitHub

Para criar o webhook do GitHub, siga estas etapas:

  1. Confira se você fez login na sua conta do GitHub.
  2. Navegue até seu repositório do GitHub.
  3. Clique em Configurações.
  4. Em Código e automação, clique em Webhooks.
  5. Clique em Add webhook.
  6. Digite o seguinte:

    1. Em URL de payload, insira o URL do serviço CREMA do Cloud Run que você implantou, my-crema-service.
    2. Em Tipo de conteúdo, selecione application/json.
    3. Em Secret, insira o valor de WEBHOOK_SECRET criado anteriormente.
    4. Em Verificação SSL, selecione Ativar verificação SSL.
    5. Em Quais eventos você quer que acionem este webhook?, selecione Quero selecionar eventos individuais.
    6. Na seleção de eventos, escolha Jobs de fluxo de trabalho. Desmarque qualquer outra opção.
    7. Clique em Add webhook.

Testar seu serviço do CREMA

Para verificar se o serviço de escalonamento automático está funcionando corretamente, confira a guia Registros do serviço do Cloud Run.

Os seguintes registros vão aparecer nos registros do serviço sempre que as métricas forem atualizadas:

Cada mensagem de registro é rotulada com o componente que a emitiu.

[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 ...

Limpar

Para evitar cobranças extras na sua conta do Google Cloud , exclua todos os recursos implantados com este tutorial.

Excluir o projeto

Se você criou um novo projeto para este tutorial, exclua-o. Se você usou um projeto atual e precisa mantê-lo sem as mudanças adicionadas neste tutorial, exclua os recursos criados para o tutorial.

O jeito mais fácil de evitar cobranças é excluindo o projeto que você criou para o tutorial.

Para excluir o projeto:

  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.

Excluir recursos do tutorial

  1. Exclua o serviço do Cloud Run que você implantou neste tutorial. Os serviços do Cloud Run não geram custos até receberem solicitações.

    Para excluir o serviço do Cloud Run, execute o seguinte comando:

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME pelo nome do serviço;

    Também é possível excluir os serviços do Cloud Run no console doGoogle Cloud .

  2. Remova a configuração da região padrão do gcloud que você adicionou durante a configuração do tutorial:

     gcloud config unset run/region
    
  3. Remova a configuração do projeto:

     gcloud config unset project
    
  4. Exclua outros recursos do Google Cloud criados neste tutorial:

A seguir