15
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Actions Runner Controllerで構築したSelf-hosted RunnerでDockerが使える仕組み ~DinDによる安全な実行環境~

Posted at

はじめに

Actions Runner Controller (ARC) は、Kubernetesクラスタ上でGitHub ActionsのSelf-hosted runnerの環境を構築するためのツールです。自動スケーリングにも対応しています。
ARCで構築したSelf-hosted runner上でDockerコマンドが実行できる仕組みについて少し調べる機会があったので、その共有です。

本記事では、内部でDinD (Docker in Docker)を利用するレガシー版ARCを扱います。新しいGitHub公式版については公式ドキュメントをご参照ください。

アーキテクチャ概要

img.png

ARCでは、各runnerのPod内に以下の2つのコンテナが起動します:

  • runnerコンテナ: CI/CDジョブを実行する環境
  • dindコンテナ: Docker Daemonが動作する環境

各コンテナで使用されるデフォルトのイメージは以下の通りです:

動作の仕組み

  1. dindコンテナ内でDocker Daemonが起動
  2. dindコンテナの /var/run/docker.sock を共有ストレージを通してrunnerコンテナにマウント
  3. runnerコンテナにインストールされたDocker CLIが、マウントされたソケット経由でDocker Daemonと通信

これにより、runnerコンテナからDockerコマンドを実行すると、実際の処理はdindコンテナ内のDocker Daemonで行われます。

なぜDinD(2コンテナ構成)を採用しているのか

「1つのコンテナ内でDocker Daemonも起動すれば、構成がシンプルになるのでは?」と思われるかもしれません。確かに技術的には可能ですが、セキュリティ上の重大なリスクがあるため推奨されません。

特権モードのリスク

コンテナ内でDocker Daemonを起動するには、--privileged オプションによる特権モードが必要です。これは、Docker Daemonがホストのcgroupなどのリソースにアクセスする必要があるためです。

しかし、特権モードではコンテナに以下の権限が付与されます:

  • ホストのLinuxカーネルへのフルアクセス
  • ホストの全てのデバイスへのアクセス
  • ホストで実行可能なほぼ全ての操作

ARCにおけるセキュリティリスク

ARCの特性上、Self-hosted runnerは複数のユーザーやワークフローから利用されます。特権モードでrunnerを起動すると、全てのユーザーにホストへの完全な権限を与えることになり、これは重大なセキュリティホールとなります。

DinDによる権限分離

そこでARCでは、Docker APIを介した通信のみを許可することで、権限を最小限に抑えています:

  • runnerコンテナ → Docker API経由でのみdindと通信
  • dindコンテナ → 特権モードで起動(分離された環境)
  • 直接的なホストアクセスを防止

カスタムイメージの設定方法

runnerとdindのバージョン互換性を保つため、カスタムイメージを指定したい場合があります。

デフォルトでは、dindコンテナのDocker Server(Daemon)は最新版ですが、runnerコンテナのDocker Client(CLI)が古いバージョンの場合、互換性の問題が発生する可能性があります。ここでは、両方のイメージを明示的に指定する方法を解説します。

前提条件

本設定では、ARCが提供するCRD(Custom Resource Definitions)のactions.summerwind.dev/v1alpha1 APIを使用します。

設定項目の確認

RunnerDeploymentのAPI仕様から、主要な設定項目は以下の通りです:

runnerコンテナのイメージ

  • 設定項目: RunnerSpec.Image

dindコンテナの設定

  • 自動設定: RunnerSpec.DockerEnabled: true で最新のdindイメージを自動使用
  • 手動設定: RunnerSpec.SidecarContainers でカスタムイメージを指定

今回はイメージのバージョンを明示的に指定するため、RunnerSpec.DockerEnabledfalseに設定し、RunnerSpec.SidecarContainersで手動設定を行います。

SidecarContainersContainer型の配列で、Container.Imageフィールドでdindコンテナのイメージを指定できます。

必要な追加設定

SidecarContainersでイメージを指定するだけでは不十分です。以下の設定も必要になります:

  1. 特権モードの有効化: dindコンテナにprivileged: trueを設定
  2. Unixソケットの共有: emptyDirボリュームで/var/run/docker.sockを共有
  3. 環境変数の設定: DOCKER_HOSTを明示的に指定

完成したマニフェスト

上記を踏まえた設定例は以下の通りです:

apiVersion: actions.summerwind.dev/v1alpha1
kind: RunnerDeployment
metadata:
  name: example-runnerdeploy
spec:
  replicas: 1
  template:
    spec:
      # ...(省略)...
      image: <runnerのDockerイメージ>
      dockerEnabled: false
      volumeMounts:
      - name: docker-sock
        mountPath: /var/run/docker.sock
      volumes:
      - name: docker-sock
        emptyDir: {}
      env:
      - name: DOCKER_HOST
        value: unix:///var/run/docker.sock
      sidecarContainers:
      - name: docker
        image: <dindのDockerイメージ>
        securityContext:
          privileged: true
        volumeMounts:
        - name: docker-sock
          mountPath: /var/run/docker.sock
        env:
        - name: DOCKER_HOST
          value: unix:///var/run/docker.sock

まとめ

今回はActions Runner Controllerで構築したSelf-hosted runnerでDockerコマンドが使える仕組みとカスタムイメージの設定について解説しました。

ポイント

  • ARCはDinD(2コンテナ構成)を採用し、セキュリティリスクを低減
  • runnerコンテナはDocker API経由でのみdindコンテナと通信
  • カスタムイメージを使う場合は、バージョン互換性と必要な設定に注意

普段何気なく使っているCI/CD環境も、裏側ではセキュリティとユーザビリティを両立させるための工夫が凝らされています。こうした仕組みを理解することで、より適切な運用や設定が可能になります。

参考

15
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?