このチュートリアルでは、ワーカープールでセルフホスト型 GitHub ランナーを使用して、GitHub リポジトリで定義されたワークフローを実行する方法について説明します。
このワークロードを処理するために Cloud Run ワーカープールをデプロイし、必要に応じてワーカープールのスケーリングをサポートするために Cloud Run 関数をデプロイします。
セルフホスト型 GitHub ランナーについて
GitHub Actions ワークフローでは、ランナーはジョブを実行するマシンです。たとえば、ランナーはリポジトリのクローンをローカルに作成し、テスト ソフトウェアをインストールしてから、コードを評価するコマンドを実行できます。
セルフホスト型ランナーを使用して、Cloud Run ワーカープール インスタンスで GitHub Actions を実行できます。このチュートリアルでは、実行中のジョブとスケジュールされていないジョブの数に基づいてランナーのプールを自動的にスケーリングする方法について説明します。ジョブがない場合は、プールをゼロにスケーリングすることもできます。
目標
このチュートリアルの内容は次のとおりです。
- Cloud Run ワーカープールを Cloud Run にデプロイする。
- ワーカープールのスケーリングをサポートする Cloud Run 関数をデプロイする。
- Secret Manager のシークレットを作成して、トークンとシークレットを安全に保存する。
- GitHub リポジトリをサポートするセルフホスト型 GitHub ランナーをデプロイする。
費用
このドキュメントでは、課金対象である次の Google Cloudコンポーネントを使用します。
料金計算ツールを使うと、予想使用量に基づいて費用の見積もりを生成できます。
始める前に
- 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.
-
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
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
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
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
-
Enable the Cloud Run, Secret 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 theserviceusage.services.enablepermission. Learn how to grant roles. -
Artifact Registry リポジトリ管理者(
roles/artifactregistry.repoAdmin) -
Cloud Build 編集者(
roles/cloudbuild.builds.editor) -
Cloud Run 管理者(
roles/run.admin) -
サービス アカウントの作成(
roles/iam.serviceAccountCreator) -
Secret Manager 管理者(
roles/secretmanager.admin) -
サービス アカウント ユーザー(
roles/iam.serviceAccountUser) -
Service Usage ユーザー(
roles/serviceusage.serviceUsageConsumer)
必要なロール
チュートリアルを完了するために必要な権限を取得するには、プロジェクトに対する次の IAM ロールを付与するよう管理者に依頼してください。
ロールの付与については、プロジェクト、フォルダ、組織に対するアクセス権の管理をご覧ください。
必要な権限は、カスタムロールや他の事前定義ロールから取得することもできます。
セルフホスト型ランナーを構成するには、GitHub リポジトリの設定を編集する権限が必要です。リポジトリは、ユーザー所有のリポジトリにすることも組織所有のリポジトリにすることもできます。
コードサンプルを取得する
使用するコードサンプルを取得するには:
ローカルマシンにサンプル リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/cloud-run-samplesCloud Run のサンプルコードが含まれているディレクトリに移動します。
cd cloud-run-samples/github-runner
コアコードについて
このサンプルは、以下のようにワーカープールとオートスケーラーとして実装されます。
ワーカープール
ワーカープールは、GitHub で作成された actions/runner イメージに基づく Dockerfile で構成されています。
このイメージには、小さなヘルパー スクリプトを除き、すべてのロジックが含まれています。
このヘルパー スクリプトはコンテナの起動時に実行され、作成するトークンを使用して、構成されたリポジトリにエフェメラル インスタンスとして登録されます。このスクリプトでは、コンテナがスケールダウンされたときに実行するアクションも定義します。
オートスケーラー
オートスケーラーは、キューに新しいジョブがあるときにワーカープールをスケールアップし、ジョブが完了したときにスケールダウンする関数です。Cloud Run API を使用してプール内の現在のワーカー数を確認し、必要に応じてその値を調整します。
IAM を構成する
このチュートリアルでは、プロビジョニングされたリソースを使用するために必要な最小権限を持つカスタム サービス アカウントを使用します。サービス アカウントを設定するには、次の操作を行います。
gcloudでプロジェクト ID を設定します。gcloud config set project PROJECT_IDPROJECT_ID は、実際のプロジェクト ID に置き換えます。
Cloud Identity and Access Management サービス アカウントを作成します。
gcloud iam service-accounts create gh-runnersプロジェクトでサービス アカウントとして動作する権限をサービス アカウントに付与します。
gcloud projects add-iam-policy-binding PROJECT_ID \ --member "serviceAccount:gh-runners@PROJECT_ID.iam.gserviceaccount.com" \ --role=roles/iam.serviceAccountUserPROJECT_ID は、実際のプロジェクト ID に置き換えます。
GitHub 情報を取得する
セルフホスト型ランナーの追加に関する GitHub のドキュメントでは、GitHub ウェブサイトからランナーを追加し、認証に使用する特定のトークンを取得することを推奨しています。
このチュートリアルでは、ランナーを動的に追加および削除するため、静的 GitHub トークンが必要です。
このチュートリアルを完了するには、選択したリポジトリとやり取りするためのアクセス権を持つ GitHub トークンを作成する必要があります。
GitHub リポジトリを特定する
このチュートリアルでは、GITHUB_REPO 変数はリポジトリ名を表します。これは、個人ユーザー リポジトリと組織リポジトリの両方で、ドメイン名の後に続く GitHub リポジトリ名の部分です。
ユーザー所有のリポジトリと組織所有のリポジトリの両方で、ドメイン名の後に続くリポジトリ名を参照します。
このチュートリアルの内容:
https://github.com/myuser/myrepoの場合、GITHUB_REPO はmyuser/myrepoです。https://github.com/mycompany/ourrepoの場合、GITHUB_REPO はmycompany/ourrepoです。
アクセス トークンを作成する
GitHub でアクセス トークンを作成し、Secret Manager に安全に保存する必要があります。
- GitHub アカウントにログインしていることを確認します。
- GitHub の [Settings] > [Developer Settings] > [Personal Access Tokens] ページに移動します。
- [Generate new token] をクリックし、[Generate new token (classic)] を選択します。
- 「repo」スコープで新しいトークンを作成します。
- [Generate token] をクリックします。
- 生成されたトークンをコピーします。
シークレット値を作成する
作成したシークレット トークンを取得して Secret Manager に保存し、アクセス権限を設定します。
Secret Manager でシークレットを作成します。
echo -n "GITHUB_TOKEN" | gcloud secrets create github_runner_token --data-file=-GITHUB_TOKEN は、GitHub からコピーした値に置き換えます。
新しく作成したシークレットへのアクセス権を付与します。
gcloud secrets add-iam-policy-binding github_runner_token \ --member "serviceAccount:gh-runners@PROJECT_ID.iam.gserviceaccount.com" \ --role "roles/secretmanager.secretAccessor"
ワーカープールをデプロイする
GitHub アクションを処理する Cloud Run ワーカープールを作成します。このプールは、GitHub で作成された actions/runner イメージに基づくイメージを使用します。
Cloud Run ワーカープールを設定する
ワーカープールのサンプルコードに移動します。
cd worker-pool-containerワーカープールをデプロイします。
gcloud beta run worker-pools deploy WORKER_POOL_NAME \ --region WORKER_POOL_LOCATION \ --source . \ --scaling 1 \ --set-env-vars GITHUB_REPO=GITHUB_REPO \ --set-secrets GITHUB_TOKEN=github_runner_token:latest \ --service-account gh-runners@PROJECT_ID.iam.gserviceaccount.com \ --memory 2Gi \ --cpu 4次のように置き換えます。
- WORKER_POOL_NAME: ワーカープールの名前
- WORKER_POOL_LOCATION: ワーカープールのリージョン
- GITHUB_REPO: 特定された GitHub リポジトリ名
- PROJECT_ID: Google Cloud プロジェクト ID
このプロジェクトで Cloud Run ソースのデプロイを初めて使用する場合は、デフォルトの Artifact Registry リポジトリの作成を求めるメッセージが表示されます。
ワーカープールの使用
これで、ワーカープールに単一のインスタンスが作成され、GitHub Actions からのジョブを受け入れる準備が整いました。
セルフホスト型ランナーの設定が完了したことを確認するには、リポジトリで GitHub アクションを呼び出します。
アクションでセルフホスト型ランナーを使用するには、GitHub アクションのジョブを変更する必要があります。ジョブで、runs-on の値を self-hosted に変更します。
リポジトリにアクションがまだない場合は、GitHub Actions のクイックスタートをご覧ください。
セルフホスト型ランナーを使用するようにアクションを構成したら、アクションを実行します。
GitHub インターフェースでアクションが正常に完了したことを確認します。
GitHub ランナーのオートスケーラーをデプロイする
元のプールに 1 つのワーカーをデプロイしました。これにより、一度に 1 つのアクションを処理できます。CI の使用状況によっては、実行する作業の急増に対応するためにプールをスケーリングする必要があります。
アクティブな GitHub ランナーを使用してワーカープールをデプロイしたら、アクション キュー内のジョブのステータスに基づいてワーカー インスタンスをプロビジョニングするようにオートスケーラーを構成します。
この実装は workflow_job イベントをリッスンします。ワークフロー ジョブが作成されると、ワーカープールがスケールアップされ、ジョブが完了するとスケールダウンされます。構成されたインスタンスの最大数を超えてプールをスケーリングすることはありません。実行中のすべてのジョブが完了すると、ゼロにスケーリングされます。
このオートスケーラーは、ワークロードに基づいて調整できます。
Webhook シークレット値を作成する
Webhook のシークレット値を作成する手順は次のとおりです。
任意の文字列値を含む Secret Manager シークレットを作成します。
echo -n "WEBHOOK_SECRET" | gcloud secrets create github_webhook_secret --data-file=-WEBHOOK_SECRET は任意の文字列値に置き換えます。
オートスケーラーのサービス アカウントにシークレットへのアクセス権を付与します。
gcloud secrets add-iam-policy-binding github_webhook_secret \ --member "serviceAccount:gh-runners@PROJECT_ID.iam.gserviceaccount.com" \ --role "roles/secretmanager.secretAccessor"
Webhook リクエストを受信する関数をデプロイする
Webhook リクエストを受信する関数をデプロイする手順は次のとおりです。
Webhook のサンプルコードに移動します。
cd ../autoscalerCloud Run functions の関数をデプロイします。
gcloud run deploy github-runner-autoscaler \ --function github_webhook_handler \ --region WORKER_POOL_LOCATION \ --source . \ --set-env-vars GITHUB_REPO=GITHUB_REPO \ --set-env-vars WORKER_POOL_NAME=WORKER_POOL_NAME \ --set-env-vars WORKER_POOL_LOCATION=WORKER_POOL_LOCATION \ --set-env-vars MAX_RUNNERS=5 \ --set-secrets GITHUB_TOKEN=github_runner_token:latest \ --set-secrets WEBHOOK_SECRET=github_webhook_secret:latest \ --service-account gh-runners@PROJECT_ID.iam.gserviceaccount.com \ --allow-unauthenticated次のように置き換えます。
- GITHUB_REPO: ドメイン名の後の GitHub リポジトリ名の部分
- WORKER_POOL_NAME: ワーカープールの名前
- WORKER_POOL_LOCATION: ワーカープールのリージョン
- REPOSITORY_NAME: GitHub リポジトリ名
サービスがデプロイされた URL をメモします。これは後の手順で使用します。
ワーカープールを更新する権限をサービス アカウントに付与します。
gcloud alpha run worker-pools add-iam-policy-binding WORKER_POOL_NAME \ --member "serviceAccount:gh-runners@PROJECT_ID.iam.gserviceaccount.com" \ --role=roles/run.developerPROJECT_ID は、実際のプロジェクト ID に置き換えます。
GitHub Webhook を作成する
GitHub Webhook を作成する手順は次のとおりです。
- GitHub アカウントにログインしていることを確認します。
- GitHub リポジトリに移動します。
- [設定] をクリックします。
- 「コードと自動化」で [Webhook] をクリックします。
- [Add webhook] をクリックします。
次の情報を入力します。
[Payload URL] に、前にデプロイした Cloud Run 関数の URL を入力します。
URL は
https://github-runner-autoscaler-PROJECTNUM.REGION.run.appのようになります。ここで、PROJECTNUM はプロジェクトの一意の数値識別子、REGION はサービスをデプロイしたリージョンです。[Content type] で、[application/json] を選択します。
[Secret] に、前に作成した WEBHOOK_SECRET の値を入力します。
[SSL verification] で、[Enable SSL verification] を選択します。
「Which events would you like to trigger this webhook?」に対して、[Let me select individual events] を選択します。
イベントの選択で、[Workflow jobs] を選択します。他のオプションの選択を解除します。
[Add webhook] をクリックします。
ワーカープールをスケールダウンする
Webhook が配置されたため、プールに永続的なワーカーを配置する必要はありません。これにより、作業がないときに実行中のワーカーがなくなるため、コストを削減できます。
プールを調整してゼロにスケーリングします。
gcloud beta run worker-pools update WORKER_POOL_NAME \ --region WORKER_POOL_LOCATION \ --scaling 0
自動スケーリング ランナーを使用する
自動スケーリング ランナーが正しく機能していることを確認するには、以前に runs-on: self-hosted に構成したアクションを実行します。
GitHub Actions の進行状況は、リポジトリの [Actions] タブで確認できます。
Webhook 関数とワーカープールの実行状況は、Cloud Run 関数と Cloud Run ワーカープールの [ログ] タブでそれぞれ確認できます。
クリーンアップ
Google Cloud アカウントで追加料金が発生しないようにするには、このチュートリアルでデプロイしたすべてのリソースを削除します。
プロジェクトを削除する
このチュートリアル用に新規プロジェクトを作成した場合は、そのプロジェクトを削除します。既存のプロジェクトを使用し、このチュートリアルで行った変更を加えずに残す場合は、チュートリアル用に作成したリソースを削除します。
課金をなくす最も簡単な方法は、チュートリアル用に作成したプロジェクトを削除することです。
プロジェクトを削除するには:
- In the Google Cloud console, go to the Manage resources page.
- In the project list, select the project that you want to delete, and then click Delete.
- In the dialog, type the project ID, and then click Shut down to delete the project.
チュートリアル リソースを削除する
このチュートリアルでデプロイした Cloud Run サービスを削除します。Cloud Run サービスの費用は、リクエストを受け取るまでは発生しません。
Cloud Run サービスを削除するには、次のコマンドを実行します。
gcloud run services delete SERVICE-NAME
SERVICE-NAME は、サービスの名前に置き換えます。
Cloud Run サービスは Google Cloud コンソールで削除することもできます。
チュートリアルの設定時に追加した
gcloudのデフォルトのリージョン構成を削除します。gcloud config unset run/regionプロジェクト構成を削除します。
gcloud config unset projectこのチュートリアルで作成した他の Google Cloud リソースを削除します。
次のステップ
- Cloud Run ワーカープールの詳細を確認する
- 他の Cloud Run のデモ、チュートリアル、サンプルを確認する。