Skip to main content

アクション ランナー コントローラーを使用してランナー スケール セットをデプロイする

Actions Runner Controller を使用してランナー スケール セットをデプロイし、詳細な構成オプションを使用して、ニーズに合わせて Actions Runner Controller を調整する方法について説明します。

法的通知

ランナー スケール セットについて

ランナー スケール セットは、GitHub Actions からジョブを割り当てることができる同種ランナーのグループです。 ランナー スケール セットが所有するアクティブなランナーの数は、Actions Runner Controller (ARC) などの自動スケーリング ランナー ソリューションによって制御できます。

ランナー グループを使用してランナー スケール セットを管理できます。 セルフホステッド ランナーと同様に、ランナー スケール セットを既存のランナー グループに追加できます。 ただし、ランナー スケール セットは一度に 1 つのランナー グループにしか属すことができず、1 つのラベルしか割り当てることができません。 ランナー グループについて詳しくは、「グループを使用してセルフホストランナーへのアクセスを管理する」を参照してください。

ランナー スケール セットにジョブを割り当てるには、ランナー スケール セットの名前を参照するようにワークフローを構成する必要があります。 詳しくは、「ワークフローでの Actions Runner Controller の使用」を参照してください。

ランナー スケール セットをデプロイする

ランナー スケール セットをデプロイするには、ARC が動作している必要があります。 詳しくは、「アクション ランナー コントローラーのクイック スタート」を参照してください。

ランナー スケール セットは、ARC の Helm チャートを使用するか、必要なマニフェストをデプロイすることでデプロイできます。 お勧めの方法は、ARC の Helm チャートを使用することです。これまでに ARC を使用した経験がない場合は特にそうです。

Note

  • セキュリティのベスト プラクティスとして、オペレーター ポッドを含む名前空間とは異なる名前空間にランナー ポッドを作成します。
  • セキュリティのベスト プラクティスとして、Kubernetes シークレットを作成し、シークレット参照を渡します。 CLI を介してプレーンテキストでシークレットを渡すと、セキュリティ上のリスクが生じる可能性があります。
  • 運用環境のワークロードを分離して実行することをお勧めします。 GitHub Actions ワークフローは任意のコードを実行するように設計されており、運用ワークロードに共有の Kubernetes クラスターを使用すると、セキュリティ上のリスクが生じる可能性があります。
  • コントローラー、リスナー、一時的ランナーからログを収集して保持する方法が実装されていることを確認します。
  1. ランナー スケール セットを構成するには、ARC 構成の値を使用して、ターミナルで次のコマンドを実行します。

    コマンドを実行するときは、次の点に注意してください。

    • INSTALLATION_NAME の値は慎重に更新してください。 インストール名は、ワークフローで runs-on の値として使用することになります。

    • NAMESPACE の値を、ランナー ポッドを作成する場所に更新します。

    • GITHUB_CONFIG_URL の値を、リポジトリ、Organization、または Enterprise の URL に設定します。 これはランナーが属するエンティティです。

    • このコマンド例では、最新バージョンの Helm チャートをインストールしています。 特定のバージョンをインストールするには、インストールするチャートのバージョンを指定した --version 引数を渡します。 actions-runner-controller リポジトリにリリースの一覧があります。

      Bash
      INSTALLATION_NAME="arc-runner-set"
      NAMESPACE="arc-runners"
      GITHUB_CONFIG_URL="http(s)://<HOSTNAME>/<'enterprises/your_enterprise'/'org'/'org/repo'>"
      GITHUB_PAT="<PAT>"
      helm install "${INSTALLATION_NAME}" \
          --namespace "${NAMESPACE}" \
          --create-namespace \
          --set githubConfigUrl="${GITHUB_CONFIG_URL}" \
          --set githubConfigSecret.github_token="${GITHUB_PAT}" \
          oci://ghcr.io/actions/actions-runner-controller-charts/gha-runner-scale-set
      

      その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

  2. インストールをチェックするには、ターミナルで次のコマンドを実行します。

    Bash
    helm list -A
    

    次のような出力が表示されます。

    NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART                                       APP VERSION
    arc             arc-systems     1               2023-04-12 11:45:59.152090536 +0000 UTC deployed        gha-runner-scale-set-controller-0.4.0       0.4.0
    arc-runner-set  arc-systems     1               2023-04-12 11:46:13.451041354 +0000 UTC deployed        gha-runner-scale-set-0.4.0                  0.4.0
    
  3. マネージャー ポッドをチェックするには、ターミナルで次のコマンドを実行します。

    Bash
    kubectl get pods -n arc-systems
    

    インストールが成功した場合、ポッドに Running の状態が表示されます。

    NAME                                                   READY   STATUS    RESTARTS   AGE
    arc-gha-runner-scale-set-controller-594cdc976f-m7cjs   1/1     Running   0          64s
    arc-runner-set-754b578d-listener                       1/1     Running   0          12s
    

インストールが成功しなかった場合、トラブルシューティング情報については、「Actions Runner Controller エラーのトラブルシューティング」を参照してください。

詳細な構成オプションを使用する

ARC には、いくつかの詳細な構成オプションが用意されています。

ランナー スケール セット名を構成する

Note

ランナー スケール セット名は、属するランナー グループ内で一意です。 複数のランナー スケール セットを同じ名前でデプロイする場合は、それらが異なるランナー グループに属している必要があります。

ランナー スケール セット名を構成するには、values.yaml ファイルのコピーで、INSTALLATION_NAME を定義するか、runnerScaleSetName の値を設定します。

## The name of the runner scale set to create, which defaults to the Helm release name
runnerScaleSetName: "my-runners"

helm install コマンドで values.yaml ファイルを必ず渡してください。 詳しくは、「Helm のインストール」のドキュメントを参照してください。

ランナーのデプロイ先を選ぶ

ランナー スケール セットは、リポジトリ、Organization、または Enterprise レベルでデプロイできます。

Note

personal access token (classic) 認証を使用する場合にのみ、Enterprise レベルでランナー スケール セットを配置できます。

ランナー スケール セットを特定のレベルにデプロイするには、values.yaml のコピー内で githubConfigUrl の値をリポジトリ、Organization、または Enterprise の URL に設定します。

次の例は、octo-org/octo-repo にランナーを追加するように ARC を構成する方法を示しています。

githubConfigUrl: "http(s)://<HOSTNAME>/<'enterprises/your_enterprise'/'org'/'org/repo'>"

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

認証に GitHub App を使用する

Enterprise レベルのランナーを使用していない場合は、GitHub Apps を使用して、GitHub API によって認証できます。 詳しくは、「GitHub API に対する認証を行う」を参照してください。

Note

ディスク上のファイル内でプレーンテキストの秘密キーを公開することに関連するセキュリティ リスクがあるため、代わりに Kubernetes シークレットを作成し、参照を渡すことをお勧めします。

Kubernetes シークレットを作成するか、values.yaml ファイル内で値を指定できます。

GitHub App を作成したら、Kubernetes シークレットを作成し、values.yaml ファイルのコピー内でそのシークレットへの参照を渡します。

Note

gha-runner-scale-set グラフがインストールされているのと同じ名前空間にシークレットを作成します。 この例では、名前空間は arc-runners クイックスタート ドキュメントと一致します。 詳しくは、「アクション ランナー コントローラーのクイック スタート」を参照してください。

kubectl create secret generic pre-defined-secret \
  --namespace=arc-runners \
  --from-literal=github_app_id=123456 \
  --from-literal=github_app_installation_id=654321 \
  --from-literal=github_app_private_key='-----BEGIN RSA PRIVATE KEY-----********'

values.yaml のコピー内で、シークレット名を参照として渡します。

githubConfigSecret: pre-defined-secret

オプション 2: values.yaml ファイル内に値を指定する

または、values.yaml ファイルのコピー内に app_idinstallation_idprivate_key の値を指定することもできます。

## githubConfigSecret is the Kubernetes secret to use when authenticating with GitHub API.
## You can choose to use a GitHub App or a personal access token (classic)
githubConfigSecret:
  ## GitHub Apps Configuration
  ## IDs must be strings, use quotes
  github_app_id: "123456"
  github_app_installation_id: "654321"
  github_app_private_key: |
    -----BEGIN RSA PRIVATE KEY-----
    ...
    HkVN9...
    ...
    -----END RSA PRIVATE KEY-----

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

ランナー グループを使ってアクセスを管理する

ランナー グループを使用して、どの Organization またはリポジトリがランナー スケール セットにアクセスできるかを制御できます。 ランナー グループについて詳しくは、「グループを使用してセルフホストランナーへのアクセスを管理する」を参照してください。

ランナー スケール セットをランナー グループに追加するには、ランナー グループが既に作成されている必要があります。 次に、values.yaml ファイルのコピー内で runnerGroup プロパティを設定します。 次の例では、ランナー スケール セットを Octo-Group ランナー グループに追加しています。

runnerGroup: "Octo-Group"

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

送信プロキシを構成する

コントローラーとランナーの HTTP トラフィックが送信プロキシを通過するように強制するには、Helm チャートで次のプロパティを設定します。

proxy:
  http:
    url: http://proxy.com:1234
    credentialSecretRef: proxy-auth # a Kubernetes secret with `username` and `password` keys
  https:
    url: http://proxy.com:1234
    credentialSecretRef: proxy-auth # a Kubernetes secret with `username` and `password` keys
  noProxy:
    - example.com
    - example.org

ARC では、匿名または認証済みのプロキシの使用がサポートされています。 認証済みプロキシを使用する場合は、Kubernetes シークレットを参照するように credentialSecretRef 値を設定する必要があります。 次のコマンドにより、プロキシ資格情報を使用してシークレットを作成できます。

Note

gha-runner-scale-set グラフがインストールされているのと同じ名前空間にシークレットを作成します。 この例では、名前空間は arc-runners クイックスタート ドキュメントと一致します。 詳しくは、「アクション ランナー コントローラーのクイック スタート」を参照してください。

Bash
  kubectl create secret generic proxy-auth \
    --namespace=arc-runners \
    --from-literal=username=proxyUsername \
    --from-literal=password=proxyPassword \

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

ランナーの最大数と最小数を設定する

maxRunners および minRunners プロパティには、ARC セットアップをカスタマイズするためのさまざまなオプションが用意されています。

Note

ARC では、スケジュールされた最大と最小の構成はサポートされていません。 cronjob またはその他のスケジューリング ソリューションを使用して、スケジュールに従って構成を更新できます。

例: 無制限のランナー数

maxRunnersminRunners の両方のプロパテをコメントアウトすると、ARC はランナー スケール セットに割り当てられたジョブの数までスケールアップし、アクティブなジョブがない場合は 0 にスケールダウンします。

## maxRunners is the max number of runners the auto scaling runner set will scale up to.
# maxRunners: 0

## minRunners is the min number of idle runners. The target number of runners created will be
## calculated as a sum of minRunners and the number of jobs assigned to the scale set.
# minRunners: 0

例: ランナーの最小数

minRunners プロパティは任意の数に設定でき、ARC は、指定された数のランナーがアクティブで、ランナー スケール セットに割り当てられたジョブをいつでも引き受けることができるようにします。

## maxRunners is the max number of runners the auto scaling runner set will scale up to.
# maxRunners: 0

## minRunners is the min number of idle runners. The target number of runners created will be
## calculated as a sum of minRunners and the number of jobs assigned to the scale set.
minRunners: 20

例: ランナーの最大数と最小数を設定する

この構成では、Actions Runner Controller は最大 30 ランナーまでスケールアップされ、ジョブが完了すると 20 ランナーにスケールダウンされます。

Note

maxRunners がコメントアウトされていない限り、minRunnersmaxRunners を超える値にできません。

## maxRunners is the max number of runners the auto scaling runner set will scale up to.
maxRunners: 30

## minRunners is the min number of idle runners. The target number of runners created will be
## calculated as a sum of minRunners and the number of jobs assigned to the scale set.
minRunners: 20

例: ジョブ キューのドレイン

特定のシナリオでは、ジョブ キューをドレインして問題のトラブルシューティングを行ったり、クラスターに対するメンテナンスを実行したりできます。 両方のプロパティを 0 に設定すると、新しいジョブが使用可能になり割り当てられたときに、Actions Runner Controller で新しいランナー ポッドは作成されません。

## maxRunners is the max number of runners the auto scaling runner set will scale up to.
maxRunners: 0

## minRunners is the min number of idle runners. The target number of runners created will be
## calculated as a sum of minRunners and the number of jobs assigned to the scale set.
minRunners: 0

カスタム TLS 証明書

Note

Debian ディストリビューションに基づかないカスタム ランナー イメージを使用している場合、次の手順は機能しません。

一部の環境では、カスタム証明機関 (CA) によって署名された TLS 証明書が必要です。 カスタム証明機関の証明書はコントローラーまたはランナー コンテナーにバンドルされていないため、それぞれの信頼ストアに取り込む必要があります。

githubServerTLS:
  certificateFrom:
    configMapKeyRef:
      name: config-map-name
      key: ca.crt
  runnerMountPath: /usr/local/share/ca-certificates/

これを行う場合は、Privacy Enhanced Mail (PEM) 形式を使用していること、および証明書の拡張子が .crt であることを確認します。 それ以外は無視されます。

コントローラーで次のアクションが実行されます。

  • certificateFrom で指定された証明書を含む github-server-tls-cert ボリュームを作成します。
  • そのボリュームをパス runnerMountPath/<certificate name> にマウントします。
  • NODE_EXTRA_CA_CERTS 環境変数をその同じパスに設定します。
  • RUNNER_UPDATE_CA_CERTS 環境変数を 1 に設定します (バージョン 2.303.0 の時点では、これにより、ホストで証明書を再読み込みするようランナーに指示します)。

ARC はランナー ポッド テンプレートで設定された値を優先し、上書きしません。

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

プライベート コンテナー レジストリを使用する

Warning

この Actions Runner Controller のカスタマイズ オプションは、GitHub Support によるサポート対象の範囲外である場合があり、正しく構成されていないと予期しない動作を引き起こす可能性があります。

GitHub Support が支援できる内容の詳細については、「アクション ランナー コントローラーのサポートについて」を参照してください。

プライベート コンテナー レジストリを使用するには、コントローラー イメージとランナー イメージをプライベート コンテナー レジストリにコピーします。 次に、それらのイメージへのリンクを構成し、imagePullPolicyimagePullSecrets の値を設定します。

コントローラー イメージを構成する

values.yaml ファイルのコピーを更新し、image プロパティを次のように設定できます。

image:
  repository: "custom-registry.io/gha-runner-scale-set-controller"
  pullPolicy: IfNotPresent
  # Overrides the image tag whose default is the chart appVersion.
  tag: "0.4.0"

imagePullSecrets:
  - name: <registry-secret-name>

リスナー コンテナーは、コントローラーに対して定義された imagePullPolicy を継承します。

ランナー イメージを構成する

values.yaml ファイルのコピーを更新し、template.spec プロパティを次のように設定できます。

template:
  spec:
    containers:
      - name: runner
        image: "custom-registry.io/actions-runner:latest"
        imagePullPolicy: Always
        command: ["/home/runner/run.sh"]
    imagePullSecrets:
      - name: <registry-secret-name>

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

ランナー ポッドのポッド仕様を更新する

Warning

この Actions Runner Controller のカスタマイズ オプションは、GitHub Support によるサポート対象の範囲外である場合があり、正しく構成されていないと予期しない動作を引き起こす可能性があります。

GitHub Support が支援できる内容の詳細については、「アクション ランナー コントローラーのサポートについて」を参照してください。

ランナー ポッドの PodSpec を完全にカスタマイズできます。指定した構成がコントローラーによって適用されます。 ポッドの仕様の例を次に示します。

template:
  spec:
    containers:
      - name: runner
        image: ghcr.io/actions/actions-runner:latest
        command: ["/home/runner/run.sh"]
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
        securityContext:
          readOnlyRootFilesystem: true
          allowPrivilegeEscalation: false
          capabilities:
            add:
              - NET_ADMIN

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

リスナー ポッドのポッド仕様を更新する

Warning

この Actions Runner Controller のカスタマイズ オプションは、GitHub Support によるサポート対象の範囲外である場合があり、正しく構成されていないと予期しない動作を引き起こす可能性があります。

GitHub Support が支援できる内容の詳細については、「アクション ランナー コントローラーのサポートについて」を参照してください。

リスナー ポッドの PodSpec を完全にカスタマイズできます。指定した構成がコントローラーによって適用されます。 ポッドの仕様の例を次に示します。

Note

リスナー コンテナーの listenerTemplate.spec.containers.name 値を変更しないことが重要です。 変更した場合、指定した構成が新しいサイドカー コンテナーに適用されます。

listenerTemplate:
  spec:
    containers:
    # If you change the name of the container, the configuration will not be applied to the listener,
    # and it will be treated as a side-car container.
    - name: listener
      securityContext:
        runAsUser: 1000
      resources:
        limits:
          cpu: "1"
          memory: 1Gi
        requests:
          cpu: "1"
          memory: 1Gi

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

コンテナーに Docker-in-Docker または Kubernetes モードを使用する

Warning

この Actions Runner Controller のカスタマイズ オプションは、GitHub Support によるサポート対象の範囲外である場合があり、正しく構成されていないと予期しない動作を引き起こす可能性があります。

GitHub Support が支援できる内容の詳細については、「アクション ランナー コントローラーのサポートについて」を参照してください。

コンテナー ジョブとサービスまたはコンテナー アクションを使用している場合は、containerMode 値を dind または kubernetes に設定する必要があります。

Docker-in-Docker モードを使用する

Note

Docker-in-Docker コンテナーには特権モードが必要です。 詳しくは、Kubernetes ドキュメントの「ポッドまたはコンテナーのセキュリティ コンテキストを構成する」を参照してください。

既定では、dind コンテナーは Docker デーモンをルートとして実行する docker:dind イメージを使用します。 「既知の制限事項」を認識し、--privileged モードでポッドを実行している限り、このイメージを docker:dind-rootless に置き換えることができます。 Docker-in-Docker 構成をカスタマイズする方法については、「コンテナー モードのカスタマイズ」を参照してください。

Docker-in-Docker モードは、Docker コンテナー内部で Docker を実行できる構成です。 この構成では、作成されたランナー ポッドごとに、ARC で次のコンテナーが作成されます。

  • init コンテナー
  • runner コンテナー
  • dind コンテナー

Docker-in-Docker モードを有効にするには、次のように containerMode.typedind に設定します。

containerMode:
  type: "dind"

template.spec は、次の既定の構成に更新されます。

template:
  spec:
    initContainers:
      - name: init-dind-externals
        image: ghcr.io/actions/actions-runner:latest
        command:
          ["cp", "-r", "/home/runner/externals/.", "/home/runner/tmpDir/"]
        volumeMounts:
          - name: dind-externals
            mountPath: /home/runner/tmpDir
    containers:
      - name: runner
        image: ghcr.io/actions/actions-runner:latest
        command: ["/home/runner/run.sh"]
        env:
          - name: DOCKER_HOST
            value: unix:///var/run/docker.sock
        volumeMounts:
          - name: work
            mountPath: /home/runner/_work
          - name: dind-sock
            mountPath: /var/run
      - name: dind
        image: docker:dind
        args:
          - dockerd
          - --host=unix:///var/run/docker.sock
          - --group=$(DOCKER_GROUP_GID)
        env:
          - name: DOCKER_GROUP_GID
            value: "123"
        securityContext:
          privileged: true
        volumeMounts:
          - name: work
            mountPath: /home/runner/_work
          - name: dind-sock
            mountPath: /var/run
          - name: dind-externals
            mountPath: /home/runner/externals
    volumes:
      - name: work
        emptyDir: {}
      - name: dind-sock
        emptyDir: {}
      - name: dind-externals
        emptyDir: {}

template.spec の 値は自動的に挿入され、オーバーライドできません。 このセットアップをカスタマイズする場合は、設定 containerMode.type を解除してから、この構成をコピーし、values.yaml ファイルのコピーに直接適用する必要があります。

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

Kubernetes モードを使用する

Kubernetes モードでは、ARC はランナー コンテナー フックを使用して同じ名前空間に新しいポッドを作成し、サービス、コンテナー ジョブ、またはアクションを実行します。

前提条件

Kubernetes モードは、ランナー ポッドとコンテナー ジョブ ポッドの間でジョブの詳細を共有するために、永続ボリュームに依存しています。 詳しくは、Kubernetes ドキュメントの「永続ボリューム」セクションを参照してください。

Kubernetes モードを使用するには、次のことを行う必要があります。

  • ランナー ポッドが要求できる永続ボリュームを作成します。
  • ソリューションを使用して、必要に応じて永続ボリュームを自動的にプロビジョニングします。

テスト用には、OpenEBS などのソリューションを使用できます。

Kubernetes モードを構成する

Kubernetes モードを有効にするには、values.yaml ファイルで containerMode.typekubernetes に設定します。

containerMode:
  type: "kubernetes"
  kubernetesModeWorkVolumeClaim:
    accessModes: ["ReadWriteOnce"]
    storageClassName: "dynamic-blob-storage"
    resources:
      requests:
        storage: 1Gi

その他の Helm 構成のオプションについては、ARC リポジトリの values.yaml を参照してください。

Note

Kubernetes モードが有効になっている場合、コンテナー ジョブで構成されていないワークフローは、次のようなエラーで失敗します。

Jobs without a job container are forbidden on this runner, please add a 'container:' to your job or contact your self-hosted runner administrator.

ジョブ コンテナーのないジョブの実行を許可するには、ランナー コンテナーで ACTIONS_RUNNER_REQUIRE_JOB_CONTAINERfalse に設定します。 これにより、ランナーにこのチェックを無効にするよう指示されます。

template:
  spec:
    containers:
      - name: runner
        image: ghcr.io/actions/actions-runner:latest
        command: ["/home/runner/run.sh"]
        env:
          - name: ACTIONS_RUNNER_REQUIRE_JOB_CONTAINER
            value: "false"

コンテナー モードのカスタマイズ

gha-runner-scale-set Helm チャートvalues.yaml ファイルで containerMode を設定する場合は、次のいずれかの値を使用できます。

  • dind または
  • kubernetes

containerMode に対して設定した値に応じて、gha-runner-scale-set Helm チャート用 values.yaml ファイルの template セクションに構成が自動的に挿入されます。

仕様をカスタマイズするには、containerMode をコメントにするか削除 し、template セクションに必要な構成を追加します。

たとえば、dind-rootless を実行する場合

dind-rootless の実行を決定する前に、既知の制限事項を認識していることを確認してください。

## githubConfigUrl is the GitHub url for where you want to configure runners
## ex: https://<HOSTNAME>/enterprises/my_enterprise or https://<HOSTNAME>/myorg
githubConfigUrl: "https://<HOSTNAME>/actions/actions-runner-controller"

## githubConfigSecret is the k8s secrets to use when auth with GitHub API.
## You can choose to use GitHub App or a PAT token
githubConfigSecret: my-super-safe-secret

## maxRunners is the max number of runners the autoscaling runner set will scale up to.
maxRunners: 5

## minRunners is the min number of idle runners. The target number of runners created will be
## calculated as a sum of minRunners and the number of jobs assigned to the scale set.
minRunners: 0

runnerGroup: "my-custom-runner-group"

## name of the runner scale set to create. Defaults to the helm release name
runnerScaleSetName: "my-awesome-scale-set"

## template is the PodSpec for each runner Pod
## For reference: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec
template:
  spec:
    initContainers:
    - name: init-dind-externals
      image: ghcr.io/actions/actions-runner:latest
      command: ["cp", "-r", "/home/runner/externals/.", "/home/runner/tmpDir/"]
      volumeMounts:
        - name: dind-externals
          mountPath: /home/runner/tmpDir
    - name: init-dind-rootless
      image: docker:dind-rootless
      command:
        - sh
        - -c
        - |
          set -x
          cp -a /etc/. /dind-etc/
          echo 'runner:x:1001:1001:runner:/home/runner:/bin/ash' >> /dind-etc/passwd
          echo 'runner:x:1001:' >> /dind-etc/group
          echo 'runner:100000:65536' >> /dind-etc/subgid
          echo 'runner:100000:65536' >> /dind-etc/subuid
          chmod 755 /dind-etc;
          chmod u=rwx,g=rx+s,o=rx /dind-home
          chown 1001:1001 /dind-home
      securityContext:
        runAsUser: 0
      volumeMounts:
        - mountPath: /dind-etc
          name: dind-etc
        - mountPath: /dind-home
          name: dind-home
    containers:
    - name: runner
      image: ghcr.io/actions/actions-runner:latest
      command: ["/home/runner/run.sh"]
      env:
        - name: DOCKER_HOST
          value: unix:///var/run/docker.sock
      volumeMounts:
        - name: work
          mountPath: /home/runner/_work
        - name: dind-sock
          mountPath: /var/run
    - name: dind
      image: docker:dind-rootless
      args:
        - dockerd
        - --host=unix:///var/run/docker.sock
      securityContext:
        privileged: true
        runAsUser: 1001
        runAsGroup: 1001
      volumeMounts:
        - name: work
          mountPath: /home/runner/_work
        - name: dind-sock
          mountPath: /var/run
        - name: dind-externals
          mountPath: /home/runner/externals
        - name: dind-etc
          mountPath: /etc
        - name: dind-home
          mountPath: /home/runner
    volumes:
    - name: work
      emptyDir: {}
    - name: dind-externals
      emptyDir: {}
    - name: dind-sock
      emptyDir: {}
    - name: dind-etc
      emptyDir: {}
    - name: dind-home
      emptyDir: {}

runner-container-hooks の解釈

ランナーは、コンテナー ジョブ、サービス コンテナーまたは Docker アクションを使用するワークフローの実行を検出すると、runner-container-hooks を呼び出して新しいポッドを作成します。 ランナーは、runner-container-hooks に依存して Kubernetes API を呼び出し、ランナー ポッドと同じ名前空間に新しいポッドを作成します。 この新しく作成されたポッドは、コンテナー ジョブ、サービス コンテナーまたは Docker アクションの実行に使用されます。 詳細については、runner-container-hooks リポジトリを参照してください。

フック拡張機能を構成する

ARC バージョン 0.4.0 以降、runner-container-hooks ではフック拡張機能がサポートされています。 これらを使用して、runner-container-hooks によって作成されたポッドを構成できます。 たとえば、フック拡張機能を使用して、ポッドにセキュリティ コンテキストを設定できます。 フック拡張機能を使用すると、runner-container-hooks によって作成されたポッドの PodSpec を更新するために使用される YAML ファイルを指定できます。

フック拡張機能を構成するには、2 つのオプションがあります。

  • カスタム ランナー イメージに保存する。 PodSpec は、カスタム ランナー イメージ内の任意の場所にある YAML ファイルに格納できます。 詳しくは、「Actions Runner Controller について」を参照してください。
  • ConfigMap に格納する。 PodSpec を使用して構成マップを作成し、その構成マップをランナー コンテナーにマウントできます。 詳細については、Kubernetes ドキュメントの「ConfigMaps」を参照してください。

Note

どちらのオプションでも、ランナー コンテナーにマウントされている YAML ファイルのパスを指すように、ランナー コンテナー仕様の ACTIONS_RUNNER_CONTAINER_HOOK_TEMPLATE 環境変数を設定する必要があります。

例: 構成マップを使用して securityContext を設定する

ランナー ポッドと同じ名前空間に構成マップを作成します。 次に例を示します。

apiVersion: v1
kind: ConfigMap
metadata:
  name: hook-extension
  namespace: arc-runners
data:
  content: |
    metadata:
      annotations:
        example: "extension"
    spec:
      containers:
        - name: "$job" # Target the job container
          securityContext:
            runAsUser: 1000
  • キーが予約されていない限り、.metadata.labels フィールドと metadata.annotations フィールドはそのまま追加されます。 .metadata.name フィールドと metadata.namespace フィールドをオーバーライドすることはできません。
  • PodSpec フィールドの大部分は、指定されたテンプレートから適用され、Helm チャート values.yaml ファイルから渡された値をオーバーライドします。
  • 追加のボリュームを指定すると、ランナーによって指定されたデフォルトのボリュームに追加されます。
  • spec.containers は割り当てられた名前に基づいてマージされます。
    • コンテナーの名前が $job の場合:
      • spec.containers.name フィールドと spec.containers.image フィールドは無視されます。
      • spec.containers.envspec.containers.volumeMountsspec.containers.portsフィールドは、フックによって作成された既定のコンテナー仕様に追加されます。
      • 残りのフィールドは、指定されたとおりに適用されます。
    • コンテナーの名前が $job ではない場合、フィールドはポッド定義にそのまま追加されます。

メトリックの有効化

Note

ARC のメトリックは、バージョン gha-runner-scale-set-0.5.0 以降で使用できます。

ARC は、ランナー、ジョブ、ワークフローの実行に費やされた時間に関するメトリックを出力できます。 メトリックを使用すると、輻輳の特定、ARC デプロイの正常性の監視、使用状況の傾向の視覚化、リソース使用量の最適化などの多くのユース ケースを行うことができます。 メトリックは、コントローラー マネージャーポッドとリスナー ポッドによって Prometheus 形式で出力されます。 詳細については、 Prometheus ドキュメントの「表示形式」を参照してください。

ARC のメトリックを有効にするには、gha-runner-scale-set-controller グラフの values.yaml ファイルで metrics プロパティを構成します。

構成ファイルの例を次に示します。

metrics:
  controllerManagerAddr: ":8080"
  listenerAddr: ":8080"
  listenerEndpoint: "/metrics"

Note

metrics: オブジェクトが指定されていない場合、またはコメント アウトされている場合は、空の値を持つコントローラー マネージャーおよびリスナー ポッドに次のフラグが適用されます: --metrics-addr--listener-metrics-addr--listener-metrics-endpoint。 これにより、ARC のメトリックが無効になります。

これらのプロパティが構成されると、コントローラー マネージャーポッドとリスナー ポッドは、values.yaml ファイルで指定したポートにバインドされた listenerEndpoint を介してメトリックを出力します。 上記の例では、エンドポイントは/metrics で、ポートは :8080 です。 このエンドポイントを使用して、コントローラー マネージャーとリスナー ポッドからメトリックをスクレーピングできます。

メトリックをオフにするには、metrics: オブジェクトとそのプロパティを削除またはコメントアウトして values.yamlファイルを更新します。

ARCに使用可能なメトリックは次のとおりです。

次の表は、コントローラー マネージャーポッドとリスナー ポッドによって出力されるメトリックを示しています。

Note

コントローラー マネージャーが出力するメトリックはコントローラー ランタイムに関連しており、GitHub によって所有されていません。

Ownerメトリック説明
コントローラー マネージャーgha_controller_pending_ephemeral_runnersゲージ (gauge)保留中の状態のエフェメラル ランナーの数
コントローラー マネージャーgha_controller_running_ephemeral_runnersゲージ (gauge)実行中の状態のエフェメラル ランナーの数
コントローラー マネージャーgha_controller_failed_ephemeral_runnersゲージ (gauge)失敗状態のエフェメラル ランナーの数
コントローラー マネージャーgha_controller_running_listenersゲージ (gauge)実行状態のリスナーの数
listenergha_assigned_jobsゲージ (gauge)ランナー スケール セットに割り当てられたジョブの数
listenergha_running_jobsゲージ (gauge)実行中またはキューに登録されているジョブの数
listenergha_registered_runnersゲージ (gauge)ランナー スケール セットによって登録されたランナーの数
listenergha_busy_runnersゲージ (gauge)ジョブを現在実行している登録済みランナーの数
listenergha_min_runnersゲージ (gauge)ランナー スケール セット用に構成されたランナーの最小数
listenergha_max_runnersゲージ (gauge)ランナー スケール セット用に構成されたランナーの最大数
listenergha_desired_runnersゲージ (gauge)ランナー スケール セットに必要なランナーの数 (スケールアップ/スケールダウン ターゲット)
listenergha_idle_runnersゲージ (gauge)ジョブを実行していない登録済みランナーの数
listenergha_started_jobs_totalcounterリスナーの準備が [1] になった後に開始されたジョブの合計数
listenergha_completed_jobs_totalcounterリスナーの準備が [1] になった後に完了されたジョブの合計数
listenergha_job_startup_duration_secondshistogramランナー スケール セットが所有するランナーでワークフロー ジョブが開始されるのを待機するために費やされた秒数
listenergha_job_execution_duration_secondshistogramランナー スケール セットによるワークフロー ジョブの実行に費やされた秒数

[1]: Listener metrics that have the counter type are reset when the listener pod restarts.

ARC をDependabot と code scanning で使用する

Actions Runner Controller を使用して、GitHub Enterprise Server インスタンスの専用ランナーを作成し、Dependabot がEnterprise のリポジトリで使用される依存関係の保護と維持に使用できるようにします。 詳しくは、「エンタープライズでの Dependabot 更新プログラムのセルフホステッド ランナーの管理」を参照してください。

また、ARC をCodeQL と使うと、コード内の脆弱性とエラーを特定することができます。 詳しくは、「CodeQL によるコード スキャンについて」を参照してください。 既に code scanning を使用していて、既定のセットアップを使用するようにランナー スケール セットを構成する場合は、INSTALLATION_NAME=code-scanning を設定します。 code scanning の既定のセットアップについての詳細は、「コード スキャンの既定セットアップの構成」をご覧ください。

Actions Runner Controller では、複数のラベルを使用して特定のランナー スケール セットにジョブをルーティングしません。 代わりに、Dependabot の更新または code scanning と CodeQL のランナー スケールセットを指定するには、dependabotcode-scanning などの Helm チャートで説明的なインストール名を使用します。 その後、ワークフローの runs-on 値を単一のラベルでインストール名に設定し、指定されたランナー スケール セットを Dependabot の更新または code scanning ジョブに使用できます。

code scanning の既定の設定を使っている場合、分析ではインストール名 code-scanning でランナー スケール セットが自動的に検索されます。

Note

Dependabot アクションは、GitHub Actions 経由で Dependabot 更新を実行するために使用されます。 このアクションには、依存関係として Docker が必要です。 このため、Docker-in-Docker (DinD) モードが有効になっている場合にのみ、Actions Runner Controller を Dependabot で使用できます。 詳細については、「エンタープライズでの Dependabot 更新プログラムのセルフホステッド ランナーの管理」および「アクション ランナー コントローラーを使用してランナー スケール セットをデプロイする」を参照してください。

ARC のアップグレード

Helm を使用した CRD のアップグレードまたは削除はサポートされていないため、Helm を使用して ARC をアップグレードすることはできません。 詳細については、Helm ドキュメントの「リソース定義のカスタマイズ」を参照してください。 ARC を新しいバージョンにアップグレードするには、次の手順を実行する必要があります。

  1. gha-runner-scale-set のすべてのインストールをアンインストールします。
  2. リソースがクリーンアップされるまで待ちます。
  3. ARC をアンインストールします。
  4. 現在インストールしているバージョンからアップグレードされたバージョンに CRD に変更がある場合は、actions.github.com API グループに関連付けられているすべての CRD を削除します。
  5. ARC を再インストールします。

詳細については、「ランナー スケール セットのデプロイ」を参照してください。

ARC をアップグレードしたいが、ダウンタイムが懸念される場合は、高可用性構成で ARC をデプロイして、ランナーが常に使用可能なようにできます。 詳細については、「高可用性と自動フェールオーバー」を参照してください。

Note

コミュニティで サポートされているバージョンの ARC から GitHub でサポートされているバージョンへの移行は、アーキテクチャの大幅な変更です。 GitHub でサポートされているバージョンには、ARC の多くのコンポーネントの再設計が含まれます。 これは、ソフトウェアのマイナー アップグレードではありません。 このような理由から、まず運用環境に一致するステージング環境で新しいバージョンをテストすることをお勧めします。 これにより、運用環境にデプロイする前のセットアップの安定性と信頼性が確保されます。

カナリア イメージのデプロイ

コントローラー マネージャー コンテナー イメージのカナリア リリースを使用して、リリース前に機能をテストできます。 カナリア イメージはタグ形式 canary-SHORT_SHA で公開されます。 詳細については、Container registry の「gha-runner-scale-set-controller」をご覧ください。

Note

  • ローカル ファイル システムで Helm チャートを使用する必要があります。
  • リリースされた Helm チャートは使用できません。
  1. gha-runner-scale-set-controller values.yaml ファイル内の tag を次の内容に更新します。canary-SHORT_SHA
  2. gha-runner-scale-setChart.yaml ファイル内のフィールド appVersion を次のように更新します。canary-SHORT_SHA
  3. 更新された Helm チャートと values.yaml ファイルを使用して ARC を再インストールします。

高可用性/自動フェールオーバー

ARC は、高可用性 (アクティブ/アクティブ) 構成でデプロイできます。 2 つの異なる Kubernetes クラスターが別々のリージョンにデプロイされている場合は、両方のクラスターに ARC をデプロイし、同じ runnerScaleSetName クラスターを使用するようにランナー スケール セットを構成できます。 これを行うには、各ランナー スケール セットを個別のランナー グループに割り当てる必要があります。 たとえば、1 つのランナー スケール セットが runner-group-A に属し、もう 1 つのランナー スケール セットが runner-group-B に属している限り、arc-runner-set という名前で 2 つのランナー スケール セットを指定できます。 ランナー スケール セットをランナー グループに割り当てる方法については、「グループを使用してセルフホストランナーへのアクセスを管理する」を参照してください。

両方のランナー スケール セットがオンラインの場合、それらに割り当てられたジョブは任意に分散されます (割り当てレース)。 ジョブ割り当てアルゴリズムを構成することはできません。 クラスターの 1 つがダウンした場合、他のクラスターのランナー スケール セットは、介入や構成の変更なしで通常どおりジョブを取得し続けます。

Organization 間で ARC を使用する

Actions Runner Controller の単一インストールで 1 つまたは複数のランナー スケール セットを構成できます。 これらのランナー スケール セットは、リポジトリ、Organization、または Enterprise に登録できます。 ランナー グループを使用して、これらのランナー スケール セットの権限境界を制御することもできます。

ベスト プラクティスとして、Organization ごとに固有の名前空間を作成します。 また、ランナー グループごと、またはランナー スケール セットごとに名前空間を作成することもできます。 それぞれの名前空間に、必要な数だけランナー スケール セットをインストールできます。 これにより、最高レベルの分離が提供され、セキュリティが向上します。 認証には GitHub Apps を使用し、ランナー スケール セットごとにきめ細かいアクセス許可を定義できます。

Apache-2.0 ライセンスのもとで https://github.com/actions/actions-runner-controller/ から一部を引用しています。

Copyright 2019 Moto Ishizawa

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.