在 Cloud Run worker 集區中執行及擴充自行託管的 GitHub 執行器

本教學課程說明如何在工作站集區中使用自行代管的 GitHub 執行器,執行 GitHub 存放區中定義的工作流程,並使用 Cloud Run 外部指標自動調度 (CREMA) 調整工作站集區的資源配置。

關於自行託管的 GitHub 執行器

在 GitHub Actions 工作流程中,執行器是執行工作的機器。舉例來說,執行器可以在本機複製存放區、安裝測試軟體,然後執行評估程式碼的指令。

您可以使用自行託管的執行程式,在 Cloud Run 工作人員集區執行個體上執行 GitHub Actions。本教學課程說明如何根據執行中和未排程的工作數量,自動調整執行器集區的資源配置。

目標

在這個教學課程中,您將執行下列操作:

費用

在本文件中,您會使用下列 Google Cloud的計費元件:

您可以使用 Pricing Calculator,根據預測用量估算費用。

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

事前準備

  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. 安裝並初始化 gcloud CLI
  8. 更新元件:
    gcloud components update
  9. 設定本教學課程中使用的 CREMA 相關設定變數:
    PROJECT_ID=PROJECT_ID
    CREMA_SERVICE_ACCOUNT_NAME=crema-service-account@$PROJECT_ID.iam.gserviceaccount.com
    CREMA_REPO_NAME=crema
    AR_REGION=us-central1
    PROJECT_ID 替換為專案 ID。 Google Cloud
  10. 系統會根據您觸發擴充的頻率,收取 Cloud Run 擴充服務的費用。如要瞭解詳情,請使用定價計算機估算費用。
  11. 必要的角色

    如要取得完成本教學課程所需的權限,請要求管理員在專案中授予您下列 IAM 角色:

    如要進一步瞭解如何授予角色,請參閱「管理專案、資料夾和組織的存取權」。

    您或許也能透過自訂角色或其他預先定義的角色,取得必要權限。

    您必須具備編輯 GitHub 存放區設定的權限,才能設定自架主機代管的執行器。存放區可以是使用者擁有的存放區,也可以是機構擁有的存放區。

    GitHub 建議只搭配私人存放區使用自架主機代管的執行器。

    建立自訂服務帳戶

    本教學課程會使用自訂服務帳戶,並授予使用已佈建資源所需的最低權限。如要設定服務帳戶,請按照下列步驟操作:

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

新增自行託管的 GitHub 執行器

如要新增自行代管的 GitHub 執行器,請按照 GitHub 說明文件中的新增自行代管的執行器操作說明進行。

找出 GitHub 存放區

在本教學課程中,GITHUB_REPO 變數代表存放區名稱。這是個人使用者存放區和機構存放區中,網域名稱後方的名稱部分。例如:

  • 如果網域網址是 https://github.com/myuser/myrepo,則 GITHUB_REPOmyuser/myrepo
  • 如果網域網址是 https://github.com/mycompany/ourrepo,則 GITHUB_REPOmycompany/ourrepo

建立存取權杖

建立 GitHub 存取權杖,與所選存放區互動,動態新增及移除執行器。如要在 GitHub 上建立存取權杖,並將其儲存至 Secret Manager,請按照下列步驟操作:

  1. 確認你已登入 GitHub 帳戶。
  2. 前往 GitHub 的「Settings > Developer Settings > Personal Access Tokens > Tokens (classic)」頁面。
  3. 點選「Generate new token」,然後選取「Generate new token (classic)」
  4. 在權杖範圍中,選取「repo」核取方塊。
  5. 點選「Generate token」
  6. 複製產生的權杖。

如要進一步瞭解存取權杖,請參閱 GitHub 文件中的「驗證需求」。

使用 Secret Manager 為存取權杖建立密鑰

取得您在上一個步驟中建立的密鑰權杖,並儲存在 Secret Manager 中。如要設定存取權限,請按照下列步驟操作:

  1. 在 Secret Manager 中建立密鑰:

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

    GITHUB_TOKEN 替換成您從 GitHub 複製的值。

  2. roles/secretmanager.secretAccessor 授予自訂服務帳戶,以便存取新建立的密鑰:

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

部署工作站集區

建立 Cloud Run worker 集區,處理 GitHub 動作。這個集區會使用以 GitHub 建立的 actions/runner 映像檔為基礎的映像檔。如要部署工作站集區,請按照下列步驟操作:

  1. 將範例存放區複製到本機電腦,即可擷取要使用的程式碼範例:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples
    
  2. 變更為包含 Cloud Run 範例程式碼的目錄:

    cd cloud-run-samples/github-runner/worker-pool-container
    
  3. 部署工作站集區:

    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
    

    更改下列內容:

    • WORKER_POOL_NAME:工作站集區的名稱
    • WORKER_POOL_LOCATION:工作站集區的區域
    • GITHUB_REPOGitHub 存放區名稱

    如果您是第一次在這個專案中使用 Cloud Run 來源部署,Cloud Run 會提示您建立預設的 Artifact Registry 存放區。

瞭解程式碼範例

worker 集區會使用以 GitHub 建立的 actions/runner 映像檔為基礎的 Dockerfile 進行設定:

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

這個輔助指令碼會在容器啟動時執行,使用您建立的權杖,將自身註冊為設定存放區中的暫時執行個體。

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

使用工作站集區接受 GitHub Actions 的工作

工作站集區執行個體已準備好接受 GitHub Actions 的工作。

如果存放區尚未有任何 GitHub 動作,請按照快速入門導覽課程中的指示建立第一個工作流程

如果存放區有 GitHub 動作,請在存放區中叫用 GitHub 動作,確認您已完成自架主機執行器的設定。

如果 GitHub 動作未使用自架主機執行器,請將 GitHub 動作的工作runs-on 值變更為 self-hosted

設定動作以使用自架主機代管的執行器後,請執行動作。

在 GitHub 介面中確認動作已順利完成

部署自動配置器 CREMA 服務

您在原始集區中部署了一個工作站,因此一次只能處理一個動作。視持續整合 (CI) 的使用情況而定,您可能需要擴充集區,以處理大量待完成的工作。

使用有效的 GitHub 執行器部署工作站集區後,請設定 CREMA 自動調度器,根據動作佇列中的工作狀態佈建工作站執行個體。

這項實作會監聽 workflow_job 事件。建立工作流程工作時,系統會擴大工作站集區,工作完成後則會縮減。不會將集區擴展到您設定的執行個體數量上限,且所有執行中的工作完成後,會縮減至零。

您可以根據工作負載調整 CREMA。

設定自動配置器

本教學課程使用參數管理工具儲存 CREMA 的 YAML 設定檔。

  1. 在 Parameter Manager 中建立參數,儲存 CREMA 的參數版本:

    PARAMETER_ID=crema-config
    PARAMETER_REGION=global
    gcloud parametermanager parameters create $PARAMETER_ID --location=$PARAMETER_REGION --parameter-format=YAML
    
  2. 在父項目錄中建立 YAML 檔案 my-crema-config.yaml,定義自動調整資源設定:

    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
    
    

    更改下列內容:

    • PROJECT_ID: Google Cloud 專案 ID
    • WORKER_POOL_NAME:您部署的工作站集區名稱
    • GITHUB_RUNNER:您設定的 GitHub 執行器名稱
    • REPOSITORY_OWNER:GitHub 存放區的擁有者
    • REPOSITORY_NAME:GitHub 存放區名稱
  3. 上傳本機 YAML 檔案做為新的參數版本:

    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
    

將額外權限授予自訂服務帳戶

如要擴充 YAML 設定中指定的工作站集區,請在自訂服務帳戶中授予下列權限:

  1. 授予 CREMA 服務帳戶讀取 Parameter Manager 的權限:

    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
      --role="roles/parametermanager.parameterViewer"
    
  2. 將工作站集區的 roles/run.developer 角色授予 CREMA 服務帳戶:

    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"
    

    WORKER_POOL_NAME 替換為工作站集區的名稱。

  3. 授予 CREMA 服務帳戶寫入指標的權限:

     gcloud projects add-iam-policy-binding $PROJECT_ID \
       --member="serviceAccount:$CREMA_SERVICE_ACCOUNT_NAME" \
       --role="roles/monitoring.metricWriter"
    
  4. 將服務帳戶使用者角色授予 CREMA 服務帳戶:

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

部署服務來調度工作負載資源

如要部署服務來調整工作站集區的資源配置,請使用預先建構的容器映像檔執行下列指令:

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 密鑰值

如要建立密鑰值來存取 GitHub Webhook,請按照下列步驟操作:

  1. 建立 Secret Manager 密鑰,管理 GitHub Webhook 的存取權。

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

    WEBHOOK_SECRET 改為任意字串值。

  2. 將密鑰存取權授予自動調整服務帳戶:

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

建立 GitHub Webhook

如要建立 GitHub Webhook,請按照下列步驟操作:

  1. 確認你已登入 GitHub 帳戶。
  2. 前往 GitHub 存放區。
  3. 按一下「設定」
  4. 在「程式碼和自動化」下方,按一下「Webhook」
  5. 按一下 [Add Webhook]
  6. 輸入下列指令:

    1. 在「Payload URL」中,輸入您部署的 Cloud Run CREMA 服務網址 my-crema-service
    2. 在「Content type」中,選取「application/json」
    3. 在「Secret」部分,輸入您先前建立的 WEBHOOK_SECRET 值。
    4. 在「SSL verification」部分,選取「Enable SSL verification」
    5. 在「您要透過哪些事件觸發這個 Webhook?」中,選取「讓我選取個別事件」
    6. 在事件選取畫面中,選取「工作流程工作」。取消選取其他選項。
    7. 按一下 [Add Webhook]

測試 CREMA 服務

如要確認自動調整服務是否正常運作,請查看 Cloud Run 服務的「記錄」分頁

每次指標重新整理時,您應該都會在服務記錄中看到下列記錄:

每則記錄訊息都會標示發出訊息的元件。

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

清除所用資源

為避免系統向您的 Google Cloud 帳戶收取額外費用,請刪除您在本教學課程中部署的所有資源。

刪除專案

如果您是為了這個教學課程建立新專案,請刪除該專案。如果您使用現有專案,並想保留專案,但不要本教學課程新增的變更,請刪除為本教學課程建立的資源

如要避免付費,最簡單的方法就是刪除您為了本教學課程所建立的專案。

刪除專案的方法如下:

  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.

刪除教學課程資源

  1. 刪除您在本教學課程中部署的 Cloud Run 服務。Cloud Run 服務收到要求後才會開始計費。

    如要刪除 Cloud Run 服務,請執行下列指令:

    gcloud run services delete SERVICE-NAME

    SERVICE-NAME 改為您的服務名稱。

    您也可以從Google Cloud 控制台刪除 Cloud Run 服務。

  2. 移除您在教學課程設定期間新增的 gcloud 預設區域設定:

     gcloud config unset run/region
    
  3. 移除專案設定:

     gcloud config unset project
    
  4. 刪除在本教學課程中建立的其他 Google Cloud 資源:

後續步驟