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

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

關於自行託管的 GitHub 執行器

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

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

目標

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

費用

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

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

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

事前準備

  1. 登入 Google Cloud 帳戶。如果您未曾使用過 Google Cloud,歡迎 建立帳戶,親自體驗實際使用我們產品的成效。新客戶還能獲得價值 $300 美元的免費抵免額,用於執行、測試及部署工作負載。
  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. 啟用 Cloud Run、Secret Manager、Parameter Manager、Artifact Registry 和 Cloud Build API (如有尚未啟用的 API)。

    啟用 API 所需的角色

    您必須具備 serviceusage.services.enable 權限,才能啟用 API。如果您建立了專案,可能已透過「擁有者」角色 (roles/owner) 取得這項權限。否則,您可以透過「Service Usage 管理員」角色 (roles/serviceusage.serviceUsageAdmin) 取得這項權限。瞭解如何授予角色。

    啟用 API

  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 替換為 Google Cloud 專案 ID。
  10. Cloud Run 擴充服務的費用取決於觸發擴充的頻率。如要瞭解詳情,請使用 Pricing Calculator 估算費用。

必要的角色

如要取得完成教學課程所需的權限,請要求管理員在專案中授予您下列 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_REPO 就是 myuser/myrepo。
  • 如果網域網址是 https://github.com/mycompany/ourrepo,GITHUB_REPO 就是 mycompany/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"
    

部署 worker 集區

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

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

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

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

    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
    

    更改下列內容:

    • WORKER_POOL_NAME:worker 集區的名稱
    • WORKER_POOL_LOCATION:worker 集區的區域
    • GITHUB_REPO:GitHub 存放區名稱

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

瞭解程式碼範例

工作站集區是使用 Dockerfile 設定,該檔案是以 GitHub 建立的 actions/runner 映像檔為基礎:

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

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

# 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 集區接受 GitHub Actions 的工作

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

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

如果存放區有 GitHub 動作,請在存放區叫用 GitHub 動作,確認自行託管的執行器已完成設定。

如果 GitHub 動作未使用自行託管的執行器,請將 GitHub 動作的工作從 runs-on 值變更為 self-hosted。

將動作設為使用自行託管的執行器後,請執行動作。

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

部署自動配置器 CREMA 服務

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

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

這個實作會監聽 workflow_job 事件。建立工作流程工作時,系統會擴充 worker 集區,並在工作完成後縮減集區。集區資源調度不會超過您設定的執行個體數量上限,且所有執行中的工作完成後,資源調度率會降至零。

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

設定自動配置器

本教學課程會使用Parameter Manager,儲存 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. 將 worker 集區的 roles/run.developer 角色授予 CREMA 服務帳戶:

    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"
    

    將 WORKER_POOL_NAME 替換為 worker 集區的名稱。

  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"
    

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

如要部署服務來擴充 worker 集區,請使用預先建構的容器映像檔執行下列指令:

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"

測試 CREMA 服務

如要確認自動調度資源服務是否正常運作,請查看 Cloud Run 服務的「Logs」(記錄) 分頁。

每次重新整理指標時,服務記錄中應會顯示下列記錄:

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

[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. 前往 Google Cloud 控制台的「Manage resources」(管理資源) 頁面。

    前往「Manage resources」(管理資源)

  2. 在專案清單中選取要刪除的專案,然後點選「Delete」(刪除)。
  3. 在對話方塊中輸入專案 ID,然後按一下 [Shut down] (關閉) 以刪除專案。

刪除教學課程資源

  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 資源:

後續步驟