Dockerを使用してDockerイメージをビルドします。

GitLab CI/CD with Dockerを使ってDockerイメージを作成することができます。例えば、アプリケーションのDockerイメージを作成してテストし、コンテナレジストリにプッシュすることができます。

CI/CDジョブでDockerコマンドを実行するには、docker コマンドをサポートするようにGitLab Runnerを設定する必要があります。この方法にはprivileged モードが必要です。

Runnerでprivileged モードを有効にせずにDockerイメージをビルドしたい場合は、Dockerの代替を使うことができます。

CI/CDジョブでDockerコマンドを有効にします。

CI/CDジョブでDockerコマンドを有効にするには、次のようにします:

シェルエグゼキュータを使う

CI/CDジョブにDockerコマンドを含めるには、shell Executorを使用するようにRunnerを設定します。この設定では、gitlab-runner ユーザーが Docker コマンドを実行しますが、実行には権限が必要です。

  1. GitLab Runnerをインストールします。
  2. Runner を登録します。shell の Executor を選択します。例えば

    sudo gitlab-runner register -n \
      --url "https://gitlab.com/" \
      --registration-token REGISTRATION_TOKEN \
      --executor shell \
      --description "My Runner"
    
  3. GitLab Runnerがインストールされているサーバーに、Docker Engineをインストールします。サポートされているプラットフォームのリストを表示します。

  4. gitlab-runner ユーザーをdocker グループに追加します:

    sudo usermod -aG docker gitlab-runner
    
  5. gitlab-runner がDockerにアクセスできることを確認します:

    sudo -u gitlab-runner -H docker info
    
  6. GitLabで、docker info.gitlab-ci.yml に追加し、Dockerが動作していることを確認します:

    default:
      before_script:
        - docker info
       
    build_image:
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    

これでdocker コマンドが使えるようになります(必要であれば Docker Composer もインストールします)。

docker グループにgitlab-runner を追加すると、事実上gitlab-runner に完全な root 権限が付与されます。詳細については、docker グループのセキュリティを参照してください。

Docker-in-Dockerを使用します。

“Docker-in-Docker”(dind )とは:

Dockerイメージにはdocker のツールが全て含まれており、イメージのコンテキストでジョブスクリプトを特権モードで実行することができます。

GitLab.comの共有RunnerでサポートされているTLSを有効にしてDocker-in-Dockerを使用する必要があります。

docker:24.0.5 のように、常に特定のバージョンのイメージをピン留めする必要があります。docker:latest のようなタグを使用すると、どのバージョンが使用されるかを制御できません。これは、新しいバージョンがリリースされたときに互換性の問題を引き起こす可能性があります。

Docker-in-DockerでDocker Executorを使用します。

Docker executorを使ってDockerコンテナ内でジョブを実行することができます。

Docker executorでTLSを有効にしたDocker-in-Docker

GitLab Runner 11.11で導入されました。

DockerデーモンはTLSでの接続をサポートします。Docker 19.03.12以降ではTLSがデフォルトです。

caution
このタスクは--docker-privileged を有効にします。これはコンテナのセキュリティメカニズムを実質的に無効にし、ホストを特権昇格にさらすことになります。このアクションはコンテナの脱走を引き起こす可能性があります。詳細については、実行時特権とLinux機能を参照してください。

TLSを有効にしてDocker-in-Dockerを使用するには:

  1. GitLab Runnerをインストールします
  2. GitLab Runnerをコマンドラインから登録します。dockerprivileged モードを使用します:

    sudo gitlab-runner register -n \
      --url "https://gitlab.com/" \
      --registration-token REGISTRATION_TOKEN \
      --executor docker \
      --description "My Docker Runner" \
      --docker-image "docker:24.0.5" \
      --docker-privileged \
      --docker-volumes "/certs/client"
    
    • このコマンドは、docker:24.0.5 イメージを使用する新しいランナーを登録します(ジョブレベルで何も指定されていない場合)。ビルドとサービスコンテナを起動するには、privileged モードを使用します。Docker-in-Dockerを使用する場合は、Dockerコンテナで常にprivileged = true
    • このコマンドは、サービスコンテナとビルドコンテナ用に/certs/client 。これは、Dockerクライアントがそのディレクトリ内の証明書を使用するために必要です。詳細については、Dockerイメージのドキュメントを参照してください。

    前のコマンドは、次の例と同様のconfig.toml エントリを作成します:

    [[runners]]
      url = "https://gitlab.com/"
      token = TOKEN
      executor = "docker"
      [runners.docker]
        tls_verify = false
        image = "docker:24.0.5"
        privileged = true
        disable_cache = false
        volumes = ["/certs/client", "/cache"]
      [runners.cache]
        [runners.cache.s3]
        [runners.cache.gcs]
    
  3. ジョブスクリプトでdocker を使用することができます。docker:24.0.5-dind サービスも含める必要があります:

    default:
      image: docker:24.0.5
      services:
        - docker:24.0.5-dind
      before_script:
        - docker info
       
    variables:
      # When you use the dind service, you must instruct Docker to talk with
      # the daemon started inside of the service. The daemon is available
      # with a network connection instead of the default
      # /var/run/docker.sock socket. Docker 19.03 does this automatically
      # by setting the DOCKER_HOST in
      # https://github.com/docker-library/docker/blob/d45051476babc297257df490d22cbd806f1b11e4/19.03/docker-entrypoint.sh#L23-L29
      #
      # The 'docker' hostname is the alias of the service container as described at
      # https://docs.gitlab.com/ee/ci/services/#accessing-the-services.
      #
      # Specify to Docker where to create the certificates. Docker
      # creates them automatically on boot, and creates
      # `/certs/client` to share between the service and job
      # container, thanks to volume mount from config.toml
      DOCKER_TLS_CERTDIR: "/certs"
       
    build:
      stage: build
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    
Docker-in-Docker (TLSは無効)をDocker Executorに含める必要があります。

TLSを無効にする正当な理由がある場合もあります。例えば、使用しているGitLab Runnerの設定をコントロールできない場合などです。

Runner のconfig.toml が似たようなものだと仮定します:

[[runners]]
  url = "https://gitlab.com/"
  token = TOKEN
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "docker:24.0.5"
    privileged = true
    disable_cache = false
    volumes = ["/cache"]
  [runners.cache]
    [runners.cache.s3]
    [runners.cache.gcs]

ジョブスクリプトでdocker を使用することができます。docker:24.0.5-dind サービスも含める必要があります:

default:
  image: docker:24.0.5
  services:
    - docker:24.0.5-dind
  before_script:
    - docker info

variables:
  # When using dind service, you must instruct docker to talk with the
  # daemon started inside of the service. The daemon is available with
  # a network connection instead of the default /var/run/docker.sock socket.
  #
  # The 'docker' hostname is the alias of the service container as described at
  # https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#accessing-the-services
  #
  # If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
  # the variable must be set to tcp://localhost:2375 because of how the
  # Kubernetes executor connects services to the job container
  # DOCKER_HOST: tcp://localhost:2375
  #
  DOCKER_HOST: tcp://docker:2375
  #
  # This instructs Docker not to start over TLS.
  DOCKER_TLS_CERTDIR: ""

build:
  stage: build
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests

Docker-in-DockerでKubernetes Executorを使用します。

Kubernetes executorを使ってDockerコンテナ内でジョブを実行することができます。

KubernetesでTLSを有効にしたDocker-in-Docker

GitLab Runner Helm Chart 0.23.0で導入されました

KubernetesでTLSを有効にしてDocker-in-Dockerを使用するには:

  1. Helmチャートを使用して、values.yml ファイル を更新し、ボリュームマウントを指定します。

    runners:
      config: |
        [[runners]]
          [runners.kubernetes]
            image = "ubuntu:20.04"
            privileged = true
          [[runners.kubernetes.volumes.empty_dir]]
            name = "docker-certs"
            mount_path = "/certs/client"
            medium = "Memory"
    
  2. ジョブスクリプトでdocker を使用することができます。docker:24.0.5-dind サービスも含める必要があります:

    default:
      image: docker:24.0.5
      services:
        - docker:24.0.5-dind
      before_script:
        - docker info
       
    variables:
      # When using dind service, you must instruct Docker to talk with
      # the daemon started inside of the service. The daemon is available
      # with a network connection instead of the default
      # /var/run/docker.sock socket.
      DOCKER_HOST: tcp://docker:2376
      #
      # The 'docker' hostname is the alias of the service container as described at
      # https://docs.gitlab.com/ee/ci/services/#accessing-the-services.
      # If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
      # the variable must be set to tcp://localhost:2376 because of how the
      # Kubernetes executor connects services to the job container
      # DOCKER_HOST: tcp://localhost:2376
      #
      # Specify to Docker where to create the certificates. Docker
      # creates them automatically on boot, and creates
      # `/certs/client` to share between the service and job
      # container, thanks to volume mount from config.toml
      DOCKER_TLS_CERTDIR: "/certs"
      # These are usually specified by the entrypoint, however the
      # Kubernetes executor doesn't run entrypoints
      # https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125
      DOCKER_TLS_VERIFY: 1
      DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
       
    build:
      stage: build
      script:
        - docker build -t my-docker-image .
        - docker run my-docker-image /script/to/run/tests
    

Docker-in-Dockerの既知のイシュー

Docker-in-Dockerは推奨される設定ですが、以下のイシューに注意する必要があります:

  • ** docker-compose コマンド** :このコマンドはデフォルトではこの設定では使用できません。ジョブスクリプトでdocker-compose を使用するには、Docker Composerのインストール手順に従ってください。
  • キャッシュ:各ジョブは新しい環境で実行されます。すべてのビルドがDockerエンジンのインスタンスを取得するため、同時実行のジョブが競合を引き起こすことはありません。しかし、レイヤのキャッシュがないため、ジョブの実行速度が遅くなる可能性があります。Dockerレイヤーキャッシングを参照してください。
  • ストレージドライバ:デフォルトでは、Dockerの以前のバージョンはvfs ストレージドライバを使用し、各ジョブのファイルシステムをコピーします。Docker 17.09以降では、推奨のストレージドライバである--storage-driver overlay2 。詳細はOverlayFSドライバの使用を参照してください。
  • ルートファイルシステムdocker:24.0.5-dind コンテナと Runner コンテナはルートファイルシステムを共有しないため、ジョブの作業ディレクトリを子コンテナのマウントポイントとして使用できます。例えば、子コンテナと共有したいファイルがある場合、/builds/$CI_PROJECT_PATH の下にサブディレクトリを作成し、それをマウントポイントとして使用することができます。より詳しい説明は、イシュー#41227 を参照してください。

     variables:
       MOUNT_POINT: /builds/$CI_PROJECT_PATH/mnt
     script:
       - mkdir -p "$MOUNT_POINT"
       - docker run -v "$MOUNT_POINT:/mnt" my-docker-image
    

DockerソケットバインディングでDocker Executorを使用します。

CI/CDジョブでDockerコマンドを使用するには、/var/run/docker.sock をコンテナにバインドマウントします。すると、イメージのコンテキストでDockerが利用できるようになります。

Dockerソケットをバインドし、GitLab Runner 11.11以降を使用している場合、docker:24.0.5-dind をサービスとして使用できなくなります。ボリュームバインディングはサービスにも影響し、互換性がなくなります。

イメージのコンテキストでDockerを利用できるようにするには、/var/run/docker.sock を起動したコンテナにマウントする必要があります。これをDocker Executorで行うには、[runners.docker] セクション](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#volumes-in-the-runnersdocker-section) の[ボリュームに"/var/run/docker.sock:/var/run/docker.sock" を追加します。

設定はこの例のようになります:

[[runners]]
  url = "https://gitlab.com/"
  token = RUNNER_TOKEN
  executor = "docker"
  [runners.docker]
    tls_verify = false
    image = "docker:24.0.5"
    privileged = false
    disable_cache = false
    volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
  [runners.cache]
    Insecure = false

Runnerの登録中に/var/run/docker.sock をマウントするには、以下のオプションを含めます:

sudo gitlab-runner register -n \
  --url "https://gitlab.com/" \
  --registration-token REGISTRATION_TOKEN \
  --executor docker \
  --description "My Docker Runner" \
  --docker-image "docker:24.0.5" \
  --docker-volumes /var/run/docker.sock:/var/run/docker.sock

Code ClimateでCode Qualityチェックを実行するために必要なような、より複雑なDocker-in-Docker設定を使用するには、ホスト上とDockerコンテナ内でビルドディレクトリへのパスが同じであることを確認する必要があります。詳細については、非公開ランナーを使用してCode Qualityのパフォーマンスを向上させるを参照してください。

docker:dind サービスのレジストリミラーを有効にします。

サービスコンテナ内でDockerデーモンが起動すると、デフォルトの設定が使用されます。パフォーマンスを向上させ、Docker Hubのレート制限を超えないようにするために、レジストリミラーを設定することをお勧めします。

.gitlab-ci.yml ファイル内のサービス

dind サービスに追加の CLI フラグを追加して、レジストリミラーを設定することができます:

services:
  - name: docker:24.0.5-dind
    command: ["--registry-mirror", "https://registry-mirror.example.com"]  # Specify the registry mirror to use
GitLab Runner 設定ファイルのサービス

GitLab Runner 13.6で導入されました

GitLab Runnerの管理者であれば、command を指定してDockerデーモンのレジストリミラーを設定することができます。dind サービスがDockerまたはKubernetes Executor用に定義されている必要があります。

Docker:

[[runners]]
  ...
  executor = "docker"
  [runners.docker]
    ...
    privileged = true
    [[runners.docker.services]]
      name = "docker:24.0.5-dind"
      command = ["--registry-mirror", "https://registry-mirror.example.com"]

Kubernetes:

[[runners]]
  ...
  name = "kubernetes"
  [runners.kubernetes]
    ...
    privileged = true
    [[runners.kubernetes.services]]
      name = "docker:24.0.5-dind"
      command = ["--registry-mirror", "https://registry-mirror.example.com"]
GitLab Runner設定ファイルのDocker Executor

GitLab Runnerの管理者であれば、dind サービスごとにミラーを使用することができます。ボリュームマウントを指定するように設定を更新してください。

例えば、以下の内容の/opt/docker/daemon.json ファイルがある場合:

{
  "registry-mirrors": [
    "https://registry-mirror.example.com"
  ]
}

config.toml ファイルを更新して、ファイルを/etc/docker/daemon.json にマウントします。 これにより、GitLab Runner によって作成されるすべてのコンテナに対してファイルがマウントされます。この設定は、dind サービスによって検出されます。

[[runners]]
  ...
  executor = "docker"
  [runners.docker]
    image = "alpine:3.12"
    privileged = true
    volumes = ["/opt/docker/daemon.json:/etc/docker/daemon.json:ro"]
GitLab Runner設定ファイルのKubernetes Executor

GitLab Runner 13.6で導入されました

GitLab Runner の管理者であれば、dind サービスごとにミラーを使用することができます。ConfigMap ボリュームマウントを指定するように設定を更新してください。

例えば、以下の内容の/tmp/daemon.json ファイルがある場合:

{
  "registry-mirrors": [
    "https://registry-mirror.example.com"
  ]
}

このファイルの内容でConfigMapを作成します。のようなコマンドで実行できます:

kubectl create configmap docker-daemon --namespace gitlab-runner --from-file /tmp/daemon.json
note
GitLab Runner用のKubernetes Executorがジョブポッドを作成するために使用する名前空間を使用する必要があります。

ConfigMapが作成されたら、config.toml ファイルを更新して、/etc/docker/daemon.json 。この更新は、GitLab Runnerによって作成されるすべてのコンテナに対してファイルをマウントします。dind サービスはこの設定を検出します。

[[runners]]
  ...
  executor = "kubernetes"
  [runners.kubernetes]
    image = "alpine:3.12"
    privileged = true
    [[runners.kubernetes.volumes.config_map]]
      name = "docker-daemon"
      mount_path = "/etc/docker/daemon.json"
      sub_path = "daemon.json"

Dockerソケットバインディングの既知のイシュー

Dockerソケットバインディングを使用すると、特権モードでDockerを実行することを避けることができます。しかし、この方法の意味するところは

  • Dockerデーモンを共有することで、コンテナのセキュリティ機構をすべて効果的に無効にし、ホストを特権昇格にさらすことになります。これはコンテナの脱走を引き起こす可能性があります。例えば、あるプロジェクトがdocker rm -f $(docker ps -a -q) 、GitLab Runnerコンテナを削除したとします。
  • 同時実行ジョブはうまくいかないかもしれません。テストが特定の名前のコンテナを作成すると、お互いに衝突する可能性があります。
  • Dockerコマンドによって作成されたコンテナは、Runnerの子ではなく兄弟になります。これはワークフローを複雑にするかもしれません。
  • ソースリポジトリからコンテナへのファイルやディレクトリの共有は、期待通りに動作しないかもしれません。ボリュームのマウントは、ビルドコンテナではなくホストマシンのコンテキストで行われます。例えば

     docker run --rm -t -i -v $(pwd)/src:/home/app/src test-image:latest run_app_tests
    

Docker-in-Dockerエクゼキュータを使用するときのように、docker:24.0.5-dind サービスをインクルードする必要はありません:

default:
  image: docker:24.0.5
  before_script:
    - docker info

build:
  stage: build
  script:
    - docker build -t my-docker-image .
    - docker run my-docker-image /script/to/run/tests

Docker-in-Dockerでレジストリを使って認証します。

Docker-in-Doッカーを使用する場合、サービスと共に新しいDockerデーモンが起動されるため、標準の認証方法は機能しません。レジストリで認証する必要があります。

DockerレイヤーキャッシングでDocker-in-Dockerビルドを高速化します。

Docker-in-Dockerを使用している場合、Dockerはビルドを作成するたびにイメージのすべてのレイヤをダウンロードします。Dockerレイヤーキャッシングでビルドを高速化できます。

OverlayFS ドライバの使用

note
GitLab.comの共有ランナーはデフォルトでoverlay2 ドライバを使用します。

デフォルトでは、docker:dind 、Dockerはvfs ストレージドライバを使用し、実行毎にファイルシステムをコピーします。別のドライバ、例えばoverlay2を使用することで、このディスク負荷の高いオペレーションを避けることができます。

要件

  1. 最近のカーネル(できれば>= 4.2 )を使用していること。
  2. overlay モジュールがロードされているか確認してください:

    sudo lsmod | grep overlay
    

    結果が表示されない場合、モジュールはロードされていません。モジュールをロードするには

    sudo modprobe overlay
    

    モジュールがロードされた場合、再起動時にモジュールがロードされることを確認する必要があります。Ubuntuシステムでは、次の行を/etc/modules

    overlay
    

プロジェクトごとにOverlayFSドライバ使用

.gitlab-ci.ymlDOCKER_DRIVER CI/CD 変数を使用すると、プロジェクトごとにドライバを有効にできます:

variables:
  DOCKER_DRIVER: overlay2

すべてのプロジェクトでのOverlayFSドライバ使用

独自のRunnerを使用する場合、config.toml ファイル](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-runners-section)の[[[runners]] セクションにDOCKER_DRIVER 環境変数を設定することで、すべてのプロジェクトでドライバを有効にすることができます:

environment = ["DOCKER_DRIVER=overlay2"]

複数のRunnerを実行している場合、すべての設定ファイルを変更する必要があります。

Runnerの設定と OverlayFSストレージドライバの使用についての詳細をお読みください。

Dockerの代替案

Runnerで特権モードを有効にせずにDockerイメージをビルドするには、以下の選択肢の1つを使用できます:

例えば、buildah

# Some details from https://major.io/2019/05/24/build-containers-in-gitlab-ci-with-buildah/

build:
  stage: build
  image: quay.io/buildah/stable:v1.31.0
  variables:
    # Use vfs with buildah. Docker offers overlayfs as a default, but buildah
    # cannot stack overlayfs on top of another overlayfs filesystem.
    STORAGE_DRIVER: vfs
    # Write all image metadata in the docker format, not the standard OCI format.
    # Newer versions of docker can handle the OCI format, but older versions, like
    # the one shipped with Fedora 30, cannot handle the format.
    BUILDAH_FORMAT: docker
    # You may need this workaround for some errors: https://stackoverflow.com/a/70438141/1233435
    BUILDAH_ISOLATION: chroot
    FQ_IMAGE_NAME: "$CI_REGISTRY_IMAGE/test"
  before_script:
    # Log in to the GitLab container registry
    - export REGISTRY_AUTH_FILE=$HOME/auth.json
    - echo "$CI_REGISTRY_PASSWORD" | buildah login -u "$CI_REGISTRY_USER" --password-stdin $CI_REGISTRY
  script:
    - buildah images
    - buildah build -t $FQ_IMAGE_NAME
    - buildah images
    - buildah push $FQ_IMAGE_NAME

GitLab コンテナレジストリを使用します。

Dockerイメージをビルドしたら、それをGitLabコンテナレジストリにプッシュすることができます。

トラブルシューティング

docker: Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?

これはDocker-in-Dockerv19.03以降を使用している場合によく発生するエラーです。

このエラーは、Dockerが自動的にTLSで起動するために発生します。

このエラーは、Kubernetes Executorが完全に起動する前にDocker-in-Dockerサービスにアクセスしようとした場合にも発生する可能性があります。より詳細な説明については、イシュー27215を参照してください。

Dockerno such host エラー

docker: error during connect: Post https://docker:2376/v1.40/containers/create: dial tcp: lookup docker on x.x.x.x:53: no such host というエラーが出るかもしれません。

このイシューは、サービスのイメージ名にレジストリホスト名が含まれている場合に発生します。例えば

default:
  image: docker:24.0.5
  services:
    - registry.hub.docker.com/library/docker:24.0.5-dind

サービスのホスト名は完全なイメージ名から派生します。しかし、より短いサービスホスト名がdocker 期待さ dockerれます。docker サービスの解決とアクセスを可能にするには、サービス名に明示的なエイリアスを追加 dockerしてください:

default:
  image: docker:24.0.5
  services:
    - name: registry.hub.docker.com/library/docker:24.0.5-dind
      alias: docker

Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

dind サービスにアクセスするためにdocker コマンドを実行しようとすると、次のようなエラーが出るかもしれません:

$ docker ps
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

ジョブがこれらの環境変数を定義していることを確認してください:

  • DOCKER_HOST
  • DOCKER_TLS_CERTDIR (オプション)
  • DOCKER_TLS_VERIFY (オプション)

Dockerクライアントを提供するイメージも更新してください。例えば、docker/compose のイメージは廃止された であり、dockerに置き換える必要があります。

ランナーのイシュー30944で説明されているように、このエラーは、ジョブが以前、Dockerの--link パラメータDOCKER_PORT_2375_TCPのような非推奨に由来する環境変数に依存していた場合に発生する可能性があります。以下の場合、ジョブはこのエラーで失敗します:

  • CI/CD イメージがDOCKER_PORT_2375_TCP のようなレガシー変数に依存している場合。
  • Runner 機能フラグFF_NETWORK_PER_BUILDtrue に設定されています。
  • DOCKER_HOST が明示的に設定されていません。

エラー:Error response from daemon: Get "https://registry-1.docker.io/v2/": unauthorized: incorrect username or password

このエラーは、非推奨変数CI_BUILD_TOKEN を使用したときに表示されます。ユーザーがこのエラーを受け取らないようにするには、次のようにしてください:

  • 代わりにCI_JOB_TOKENを使用してください。
  • gitlab-ci-token/CI_BUILD_TOKEN から$CI_REGISTRY_USER/$CI_REGISTRY_PASSWORD に変更してください。

エラー:error during connect: Post "https://docker:2376/v1.24/auth": dial tcp: lookup docker on 127.0.0.11:53: no such host

このエラーは、dind サービスの起動に失敗した場合に表示されます。ジョブログでmount: permission denied (are you root?) が表示されているか確認してください。例えば

Service container logs:
2023-08-01T16:04:09.541703572Z Certificate request self-signature ok
2023-08-01T16:04:09.541770852Z subject=CN = docker:dind server
2023-08-01T16:04:09.556183222Z /certs/server/cert.pem: OK
2023-08-01T16:04:10.641128729Z Certificate request self-signature ok
2023-08-01T16:04:10.641173149Z subject=CN = docker:dind client
2023-08-01T16:04:10.656089908Z /certs/client/cert.pem: OK
2023-08-01T16:04:10.659571093Z ip: can't find device 'ip_tables'
2023-08-01T16:04:10.660872131Z modprobe: can't change directory to '/lib/modules': No such file or directory
2023-08-01T16:04:10.664620455Z mount: permission denied (are you root?)
2023-08-01T16:04:10.664692175Z Could not mount /sys/kernel/security.
2023-08-01T16:04:10.664703615Z AppArmor detection and --privileged mode might break.
2023-08-01T16:04:10.665952353Z mount: permission denied (are you root?)

これはGitLab Runnerがdind サービスを開始する権限を持っていないことを示しています:

  1. config.tomlprivileged = true が設定されているか確認してください。
  2. CIジョブがこれらの特権ランナーを使用するための正しいRunnerタグを持っていることを確認してください。

エラー:cgroups: cgroup mountpoint does not exist: unknown

Docker Engine 20.10には既知の非互換性があります。

ホストがDocker Engine 20.10以降を使用している場合、20.10より古いバージョンのdocker:dind サービスは期待通りに動作しません。

サービス自体は問題なく起動しますが、コンテナイメージを構築しようとするとエラーが発生します:

cgroups: cgroup mountpoint does not exist: unknown

このイシューを解決するには、docker:dind コンテナをバージョン 20.10.x 以上に更新してください(例:docker:24.0.5-dind )。

逆の設定(docker:24.0.5-dind サービスとホスト上のDocker Engineのバージョンが19.06.x以上)は問題なく動作します。最良の戦略のためには、ジョブ環境のバージョンを頻繁にテストし、最新のものに更新する必要があります。これにより、新機能やセキュリティが向上し、ランナーのホスト上のDocker Engineのアップグレードがジョブに対して透過的になります。