Selbst gehostete GitHub-Runner in Cloud Run-Worker-Pools ausführen und skalieren

In dieser Anleitung erfahren Sie, wie Sie selbst gehostete GitHub-Runner in Worker-Pools verwenden, um die in Ihrem GitHub-Repository definierten Workflows auszuführen, und wie Sie Ihren Worker-Pool mit Cloud Run External Metrics Autoscaling (CREMA) skalieren.

Selbst gehostete GitHub-Runner

In einem GitHub Actions-Workflow sind Runner die Maschinen, auf denen Jobs ausgeführt werden. Ein Runner kann beispielsweise Ihr Repository lokal klonen, Testsoftware installieren und dann Befehle ausführen, mit denen Ihr Code ausgewertet wird.

Sie können selbst gehostete Runner verwenden, um GitHub Actions auf Cloud Run-Workerpool-Instanzen auszuführen. In dieser Anleitung wird gezeigt, wie Sie einen Pool von Runnern automatisch auf Grundlage der Anzahl der laufenden und nicht geplanten Jobs skalieren.

Ziele

In dieser Anleitung wird Folgendes beschrieben:

Kosten

In diesem Dokument verwenden Sie die folgenden kostenpflichtigen Komponenten von Google Cloud:

Mit dem Preisrechner können Sie eine Kostenschätzung für Ihre voraussichtliche Nutzung vornehmen.

Neuen Nutzern von Google Cloud steht möglicherweise eine kostenlose Testversion zur Verfügung.

Hinweis

  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. Installieren und initialisieren Sie die gcloud CLI.
  8. Aktualisieren Sie die Komponenten:
    gcloud components update
  9. Legen Sie die folgenden Konfigurationsvariablen für CREMA fest, die in dieser Anleitung verwendet werden:
    PROJECT_ID=PROJECT_ID
    CREMA_SERVICE_ACCOUNT_NAME=crema-service-account@$PROJECT_ID.iam.gserviceaccount.com
    CREMA_REPO_NAME=crema
    AR_REGION=us-central1
    Ersetzen Sie PROJECT_ID durch die ID Ihres Google Cloud Projekts.
  10. Die Kosten für Ihren Cloud Run-Skalierungsdienst richten sich danach, wie oft Sie die Skalierung auslösen. Weitere Informationen finden Sie im Preisrechner.
  11. Erforderliche Rollen

    Bitten Sie Ihren Administrator, Ihnen die folgenden IAM-Rollen für Ihr Projekt zuzuweisen, um die Berechtigungen zu erhalten, die Sie zum Ausführen der Anleitung benötigen:

    Weitere Informationen zum Zuweisen von Rollen finden Sie unter Zugriff auf Projekte, Ordner und Organisationen verwalten.

    Sie können die erforderlichen Berechtigungen auch über benutzerdefinierte Rollen oder andere vordefinierte Rollen erhalten.

    Sie benötigen die Berechtigung zum Bearbeiten der Einstellungen für ein GitHub-Repository, um die selbstgehosteten Runner zu konfigurieren. Das Repository kann einem Nutzer oder einer Organisation gehören.

    GitHub empfiehlt, selbst gehostete Runner nur mit privaten Repositories zu verwenden.

    Benutzerdefiniertes Dienstkonto erstellen

    In dieser Anleitung wird ein benutzerdefiniertes Dienstkonto mit den erforderlichen Mindestberechtigungen für die Verwendung der bereitgestellten Ressourcen verwendet. So richten Sie das Dienstkonto ein:

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

Selbst gehostete GitHub-Runner hinzufügen

Wenn Sie selbst gehostete GitHub-Runner hinzufügen möchten, folgen Sie der Anleitung zum Hinzufügen selbst gehosteter Runner in der GitHub-Dokumentation.

GitHub-Repository identifizieren

In dieser Anleitung steht die Variable GITHUB_REPO für den Namen des Repositorys. Dies ist der Teil des Namens, der nach dem Domainnamen für persönliche Nutzer-Repositories und Organisations-Repositories steht. Beispiel:

  • Wenn Ihre Domain-URL https://github.com/myuser/myrepo lautet, ist GITHUB_REPO myuser/myrepo.
  • Wenn Ihre Domain-URL https://github.com/mycompany/ourrepo lautet, ist GITHUB_REPO mycompany/ourrepo.

Zugriffstoken erstellen

Erstellen Sie ein GitHub-Zugriffstoken, um Runner dynamisch hinzuzufügen und zu entfernen, indem Sie mit dem ausgewählten Repository interagieren. So erstellen Sie ein Zugriffstoken auf GitHub und speichern es in Secret Manager:

  1. Melden Sie sich in Ihrem GitHub-Konto an.
  2. Rufen Sie die Seite Einstellungen > Entwicklereinstellungen > Persönliche Zugriffstokens > Tokens (classic) von GitHub auf.
  3. Klicken Sie auf Neues Token erstellen und wählen Sie Neues Token erstellen (klassisch) aus.
  4. Wählen Sie für den Tokenbereich das Kästchen Repository aus.
  5. Klicken Sie auf Generate token (Token generieren).
  6. Kopieren Sie das generierte Token.

Weitere Informationen zu Zugriffstokens finden Sie in der GitHub-Dokumentation unter Authentifizierungsanforderungen.

Secret für Ihr Zugriffstoken mit Secret Manager erstellen

Nehmen Sie das Secret-Token, das Sie im vorherigen Schritt erstellt haben, und speichern Sie es in Secret Manager. So legen Sie Zugriffsberechtigungen fest:

  1. Erstellen Sie das Secret in Secret Manager:

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

    Ersetzen Sie GITHUB_TOKEN durch den Wert, den Sie aus GitHub kopiert haben.

  2. Gewähren Sie dem benutzerdefinierten Dienstkonto die roles/secretmanager.secretAccessor, damit es auf das neu erstellte Secret zugreifen kann:

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

Worker-Pool bereitstellen

Cloud Run-Worker-Pool zum Verarbeiten von GitHub-Aktionen erstellen Für diesen Pool wird ein Image verwendet, das auf dem von GitHub erstellten actions/runner-Image basiert. So stellen Sie einen Worker-Pool bereit:

  1. Klonen Sie das Beispiel-Repository auf Ihren lokalen Computer, um das Codebeispiel abzurufen:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples
    
  2. Wechseln Sie in das Verzeichnis, das den Cloud Run-Beispielcode enthält:

    cd cloud-run-samples/github-runner/worker-pool-container
    
  3. Stellen Sie den Worker-Pool bereit:

    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
    

    Ersetzen Sie Folgendes:

    • WORKER_POOL_NAME: der Name des Worker-Pools
    • WORKER_POOL_LOCATION: die Region des Worker-Pools
    • GITHUB_REPO: der Name des GitHub-Repositorys

    Wenn Sie Cloud Run-Quellbereitstellungen zum ersten Mal in diesem Projekt verwenden, werden Sie von Cloud Run aufgefordert, ein Standard-Artifact Registry-Repository zu erstellen.

Codebeispiel verstehen

Der Worker-Pool wird mit einem Dockerfile konfiguriert, das auf dem von GitHub erstellten Image actions/runner basiert:

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"]

Dieses Hilfsskript wird beim Start des Containers ausgeführt und registriert sich mit einem von Ihnen erstellten Token als temporäre Instanz im konfigurierten Repository.

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

Worker-Pool verwenden, um Jobs von GitHub-Aktionen anzunehmen

Ihre Worker-Pool-Instanz ist bereit, Jobs von GitHub Actions anzunehmen.

Wenn Ihr Repository noch keine GitHub-Aktionen enthält, folgen Sie der Anleitung in der Kurzanleitung zum Erstellen Ihres ersten Workflows.

Wenn Ihr Repository GitHub Actions enthält, prüfen Sie, ob Sie die Einrichtung Ihres selbst gehosteten Runners abgeschlossen haben, indem Sie eine GitHub Action in Ihrem Repository aufrufen.

Wenn für Ihre GitHub-Aktion keine selbst gehosteten Runner verwendet werden, ändern Sie den Job Ihrer GitHub-Aktion vom Wert runs-on in self-hosted.

Nachdem Sie eine Aktion für die Verwendung der selbstgehosteten Runner konfiguriert haben, führen Sie die Aktion aus.

Prüfen Sie in der GitHub-Oberfläche, ob die Aktion erfolgreich abgeschlossen wurde.

CREMA-Autoscaling-Dienst bereitstellen

Sie haben einen Worker in Ihrem ursprünglichen Pool bereitgestellt, sodass jeweils nur eine Aktion verarbeitet werden kann. Je nachdem, wie Sie Continuous Integration (CI) verwenden, müssen Sie Ihren Pool möglicherweise skalieren, um eine große Menge an Arbeit zu bewältigen.

Nachdem Sie den Worker-Pool mit einem aktiven GitHub-Runner bereitgestellt haben, konfigurieren Sie den CREMA-Autoscaler so, dass Worker-Instanzen basierend auf dem Jobstatus in der Aktionswarteschlange bereitgestellt werden.

Bei dieser Implementierung wird auf ein workflow_job-Ereignis gewartet. Wenn Sie einen Workflow-Job erstellen, wird der Worker-Pool skaliert. Sobald der Job abgeschlossen ist, wird er wieder skaliert. Der Pool wird nicht über die von Ihnen konfigurierte maximale Anzahl von Instanzen hinaus skaliert und wird auf null skaliert, wenn alle laufenden Jobs abgeschlossen sind.

Sie können CREMA an Ihre Arbeitslasten anpassen.

Autoscaling konfigurieren

In dieser Anleitung wird der Parameter Manager verwendet, um die YAML-Konfigurationsdatei für CREMA zu speichern.

  1. Erstellen Sie einen Parameter in Parameter Manager, um Parameterversionen für CREMA zu speichern:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. Erstellen Sie im übergeordneten Verzeichnis eine YAML-Datei (my-crema-config.yaml), um die Autoscaler-Konfiguration zu definieren:

    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
    
    

    Ersetzen Sie Folgendes:

    • PROJECT_ID: die Google Cloud Projekt-ID
    • WORKER_POOL_NAME: der Name des bereitgestellten Worker-Pools
    • GITHUB_RUNNER: Der Name des von Ihnen konfigurierten GitHub-Runners.
    • REPOSITORY_OWNER: der Inhaber des GitHub-Repositorys
    • REPOSITORY_NAME: Der Name des GitHub-Repositorys
  3. Laden Sie Ihre lokale YAML-Datei als neue Parameterversion hoch:

    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
    

Zusätzliche Berechtigungen für Ihr benutzerdefiniertes Dienstkonto erteilen

Wenn Sie den in Ihrer YAML-Konfiguration angegebenen Worker-Pool skalieren möchten, gewähren Sie dem benutzerdefinierten Dienstkonto die folgenden Berechtigungen:

  1. Gewähren Sie Ihrem CREMA-Dienstkonto die Berechtigung zum Lesen aus Parameter Manager:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role="roles/parametermanager.parameterViewer"
    
  2. Weisen Sie Ihrem CREMA-Dienstkonto die Rolle roles/run.developer für den Worker-Pool zu:

    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"
    

    Ersetzen Sie WORKER_POOL_NAME durch den Namen des Worker-Pools.

  3. Gewähren Sie Ihrem CREMA-Dienstkonto die Berechtigung zum Schreiben von Messwerten:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
       --role="roles/monitoring.metricWriter"
    
  4. Weisen Sie Ihrem CREMA-Dienstkonto die Rolle „Dienstkontonutzer“ zu:

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

Dienst bereitstellen, um Arbeitslasten zu skalieren

Führen Sie den folgenden Befehl mit einem vorgefertigten Container-Image aus, um den Dienst bereitzustellen und den Worker-Pool zu skalieren:

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"

Webhook-Secret-Wert erstellen

So erstellen Sie einen geheimen Wert für den Zugriff auf den GitHub-Webhook:

  1. Erstellen Sie ein Secret Manager-Secret, um den Zugriff auf Ihren GitHub-Webhook zu verwalten.

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

    Ersetzen Sie WEBHOOK_SECRET durch einen beliebigen Stringwert.

  2. Gewähren Sie dem Autoscaler-Dienstkonto Zugriff auf das Secret:

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

GitHub-Webhook erstellen

So erstellen Sie den GitHub-Webhook:

  1. Melden Sie sich in Ihrem GitHub-Konto an.
  2. Rufen Sie Ihr GitHub-Repository auf.
  3. Klicken Sie auf Einstellungen.
  4. Klicken Sie unter Code und Automatisierung auf Webhooks.
  5. Klicken Sie auf Add webhook (Webhook hinzufügen).
  6. Geben Sie Folgendes ein:

    1. Geben Sie unter Nutzlast-URL die URL des Cloud Run-CREMA-Dienstes ein, den Sie bereitgestellt haben: my-crema-service.
    2. Wählen Sie für Inhaltstyp die Option application/json aus.
    3. Geben Sie für Secret den zuvor erstellten Wert WEBHOOK_SECRET ein.
    4. Wählen Sie für SSL-Überprüfung die Option SSL-Überprüfung aktivieren aus.
    5. Wählen Sie für Welche Ereignisse sollen diesen Webhook auslösen? die Option Ich möchte einzelne Ereignisse auswählen aus.
    6. Wählen Sie bei der Ereignisauswahl Workflow-Jobs aus. Heben Sie die Auswahl aller anderen Optionen auf.
    7. Klicken Sie auf Add webhook (Webhook hinzufügen).

CREMA-Dienst testen

Um zu prüfen, ob der Autoscaling-Dienst richtig funktioniert, sehen Sie sich den Tab Logs des Cloud Run-Dienstes an.

In den Logs Ihres Dienstes sollten jedes Mal, wenn die Messwerte aktualisiert werden, die folgenden Logs angezeigt werden:

Jede Lognachricht ist mit der Komponente gekennzeichnet, die sie ausgegeben hat.

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

Bereinigen

Damit Ihrem Google Cloud Konto keine zusätzlichen Kosten in Rechnung gestellt werden, löschen Sie alle Ressourcen, die Sie mit dieser Anleitung bereitgestellt haben.

Projekt löschen

Wenn Sie ein neues Projekt für diese Anleitung erstellt haben, löschen Sie das Projekt. Wenn Sie ein vorhandenes Projekt verwendet haben und es beibehalten möchten, ohne die Änderungen in dieser Anleitung hinzuzufügen, löschen Sie die für die Anleitung erstellten Ressourcen.

Am einfachsten vermeiden Sie weitere Kosten, wenn Sie das zum Ausführen der Anleitung erstellte Projekt löschen.

So löschen Sie das Projekt:

  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.

Anleitungsressourcen löschen

  1. Löschen Sie den Cloud Run-Dienst, den Sie in dieser Anleitung bereitgestellt haben. Für Cloud Run-Dienste fallen erst Kosten an, wenn sie Anfragen empfangen.

    Führen Sie den folgenden Befehl aus, um Ihren Cloud Run-Dienst zu löschen:

    gcloud run services delete SERVICE-NAME

    Ersetzen Sie SERVICE-NAME durch den Namen Ihres Dienstes.

    Sie können Cloud Run-Dienste auch über die Google Cloud Console löschen.

  2. Entfernen Sie die Konfiguration der Standardregion gcloud, die Sie während der Einrichtung für die Anleitung hinzugefügt haben:

     gcloud config unset run/region
    
  3. Entfernen Sie die Projektkonfiguration:

     gcloud config unset project
    
  4. Löschen Sie andere Google Cloud Ressourcen, die in dieser Anleitung erstellt wurden:

Nächste Schritte