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

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

Sobre os 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 o GitHub Actions em instâncias do pool de workers 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, use 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. Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloudagora, crie uma conta para avaliar o desempenho dos nossos produtos em situações reais. Clientes novos também recebem US $300 em créditos para executar, testar e implantar cargas de trabalho sem custos financeiros.
  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. Ative as APIs Cloud Run, Secret Manager, Gerenciador de parâmetros, Artifact Registry e API Cloud Build, se ainda não estiverem ativadas.

    Funções necessárias para ativar APIs

    Para ativar APIs, você precisa da permissão serviceusage.services.enable. Se você criou o projeto, provavelmente já tem essa permissão pelo papel de proprietário (roles/owner). Caso contrário, é possível conseguir essa permissão pelo papel de administrador do Service Usage (roles/serviceusage.serviceUsageAdmin). Saiba como conceder papéis.

    Ativar as APIs

  7. Instale e inicialize a CLI gcloud.
  8. Atualize os componentes:
    gcloud components update
  9. Defina as seguintes variáveis de configuração para o CREMA usadas 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ê vai receber cobranças pelo serviço de escalonamento do Cloud Run com base na frequência com que aciona o escalonamento. Para mais informações, faça uma estimativa de custos com a calculadora de preços.

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 em um repositório do GitHub para configurar os executores auto-hospedados. O repositório pode ser de propriedade do usuário ou da organização.

O GitHub recomenda o uso de executores auto-hospedados apenas com repositórios particulares.

Criar uma conta de serviço personalizada

Neste tutorial, usamos 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 auto-hospedados do GitHub, siga as instruções em Como adicionar executores auto-hospedados 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 após o nome de domínio para repositórios de usuários pessoais e de organizações. Exemplo:

  • Se o URL do domínio for https://github.com/myuser/myrepo, o GITHUB_REPO será myuser/myrepo.
  • Se o URL do 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. Verifique se você fez login na sua conta do GitHub.
  2. Acesse 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 as 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 workers, 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 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 solicitar 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.332.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 temporária, usando um token que você cria.

# 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 do pool de workers está pronta para aceitar jobs de ações do GitHub.

Se o repositório ainda não tiver ações do GitHub, siga as instruções no guia de 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 auto-hospedado 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 auto-hospedados, execute a ação.

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

Implantar 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 uso da integração contínua (CI), talvez seja necessário escalonar o pool para lidar com um fluxo de trabalho.

Depois de implantar o pool de workers com um executor ativo do GitHub, 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, o reduz novamente. Ele não vai escalonar o pool além do número máximo de instâncias que você configurar e vai reduzir 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 escalonador automático

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 do parâmetro 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 do Google Cloud
    • WORKER_POOL_NAME: o nome do pool de workers que você implantou.
    • 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 do 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 à 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 à conta de serviço do CREMA permissão para ler o 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 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 à 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 à 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"
    

Implantar o serviço para escalonar as 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 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-24/runtimes/java25 \
  --labels=created-by=crema \
  --set-env-vars="CREMA_CONFIG=${CREMA_CONFIG_PARAM_VERSION},OUTPUT_SCALER_METRICS=True"

Testar o serviço CREMA

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

Você verá os seguintes registros 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 quer mantê-lo sem as alterações incluídas 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. No console Google Cloud , acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

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 de região padrão 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