このチュートリアルでは、ワーカープールでセルフホスト型 GitHub ランナーを使用して、GitHub リポジトリで定義されたワークフローを実行する方法について説明します。
このワークロードを処理するために Cloud Run ワーカープールをデプロイし、必要に応じてワーカープールのスケーリングをサポートするために Cloud Run 関数をデプロイします。
セルフホスト型 GitHub ランナーについて
GitHub Actions ワークフローでは、ランナーはジョブを実行するマシンです。たとえば、ランナーはリポジトリをローカルにクローンし、テスト ソフトウェアをインストールしてから、コードを評価するコマンドを実行できます。
セルフホスト型ランナーを使用すると、Cloud Run ワーカー プール インスタンスで GitHub Actions を実行できます。このチュートリアルでは、実行中のジョブとスケジュールされていないジョブの数に基づいてランナーのプールを自動的にスケーリングする方法について説明します。ジョブがない場合は、プールをゼロにスケーリングすることもできます。
コードサンプルを取得する
使用するコードサンプルを取得するには:
ローカルマシンにサンプル リポジトリのクローンを作成します。
git clone https://github.com/GoogleCloudPlatform/cloud-run-samples
Cloud Run のサンプルコードが含まれているディレクトリに移動します。
cd cloud-run-samples/github-runner
コアコードについて
このサンプルは、以下のようにワーカープールとオートスケーラーとして実装されます。
ワーカープール
ワーカープールは、GitHub で作成された actions/runner イメージに基づく Dockerfile で構成されています。
このイメージには、小さなヘルパースクリプトを除き、すべてのロジックが含まれています。
このヘルパースクリプトは、コンテナの起動時に実行され、作成するトークンを使用して、構成されたリポジトリにエフェメラル インスタンスとして登録されます。このスクリプトでは、コンテナがスケールダウンされたときに実行するアクションも定義します。
オートスケーラー
オートスケーラーは、キューに新しいジョブがある場合はワーカー プールをスケールアップし、ジョブが完了した場合はスケールダウンする関数です。Cloud Run API を使用してプール内の現在のワーカー数を確認し、必要に応じてその値を調整します。
IAM を構成する
このチュートリアルでは、プロビジョニングされたリソースを使用するために必要な最小権限を持つカスタム サービス アカウントを使用します。サービス アカウントを設定するには、次の操作を行います。
gcloud
でプロジェクト ID を設定します。gcloud config set project PROJECT_ID
PROJECT_ID は、実際のプロジェクト ID に置き換えます。
新しい 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.serviceAccountUser
PROJECT_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 Runner Autoscaler をデプロイする
元のプールに 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 ../autoscaler
Cloud 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.developer
PROJECT_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 はサービスをデプロイしたリージョンです。[コンテンツ タイプ] で、[application/json] を選択します。
[Secret] に、前に作成した WEBHOOK_SECRET の値を入力します。
[SSL 認証] で、[SSL 認証を有効にする] を選択します。
[どのイベントでこの Webhook をトリガーしたいですか?] で、[個別のイベントを選択] を選択します。
イベントの選択で、[ワークフロー ジョブ] を選択します。他のオプションの選択を解除します。
[Add webhook] をクリックします。
ワーカープールをスケールダウンする
Webhook が配置されたため、プールに永続的なワーカーを配置する必要はありません。これにより、作業がないときに実行中のワーカーがなくなるため、コストを削減できます。
プールを調整してゼロにスケーリングします。
gcloud beta run worker-pools update WORKER_POOL_NAME \ --region WORKER_POOL_LOCATION \ --scaling 0
自動スケーリング ランナーを使用する
自動スケーリング ランナーが正しく機能していることを確認するには、以前に runs-on: self-hosted
に構成したアクションを実行します。
GitHub Actions の進行状況は、リポジトリの [アクション] タブで確認できます。
Webhook 関数とワーカープールの実行状況は、Cloud Run 関数と Cloud Run ワーカープールの [ログ] タブでそれぞれ確認できます。