GitLab RunnerのKubernetes ExecutorでDockerイメージを作成する方法

Tips
2019年09月12日 10:00

概要

GitLabでCI/CDを行うためのものとして、GitLab Runnerがあります。

GitLab Runnerは、Dockerを使って動かすことができるのですが、Dockerに関連してKubernetesでも動かすことができます。

今回は、GitLab RunnerをKubernetesで動かす際に、Docker in Dockerを行う方法について紹介します。

環境

  • Kubernets 1.14
  • GitLab Runner 12.2

Docker in Docker

KubernetesでGitLab Runnerを動かす際には、基本的に公式サイトの説明通りにやっていればすぐに動きます。

しかし、GitLab RunnerでDockerのイメージを作成するなどのDockerの中でDockerを扱うようなDocker in Dockerと言われる処理をする際には、そのままではうまく動きません。

そこで、いくつかの設定をすることでDocker in Dockerの処理をすることができるので、その設定について説明します。

設定について

KubernetesでGitLab Runnerを動かす際には、GitLab RunnerにDockerのソケットを追加する必要があります。

次にGitLab RunnerをKubernetesにデプロイするyamlファイルを載せます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitlab-runner
spec:
  selector:
    matchLabels:
      app: gitlab-runner
  template:
    metadata:
      labels:
        app: gitlab-runner
    spec:
      containers:
      - args:
        - run
        image: gitlab/gitlab-runner:alpine-v12.2.0
        imagePullPolicy: Always
        name: gitlab-runner
        volumeMounts:
        - mountPath: /etc/gitlab-runner
          name: config
      restartPolicy: Always
      volumes:
      - configMap:
          name: gitlab-runner
        name: config

次に、GitLabの設定ファイルとして作成するconfig mapを次に載せます。

apiVersion: v1
kind: ConfigMap
metadata:
  name: gitlab-runner
data:
  config.toml: |
    concurrent = 0
    listen_address = "0.0.0.0:9252"

    [session_server]
      session_timeout = 1800

    [[runners]]
      name = "***"
      url = "https://*****"
      token = "*****"
      executor = "kubernetes"
      [runners.cache]
      [runners.kubernetes]
        host = ""
        bearer_token_overwrite_allowed = false
        image = "ubuntu:18.04"
        namespace_overwrite_allowed = ""
        privileged = true
        service_account_overwrite_allowed = ""
        pod_annotations_overwrite_allowed = ""
        [runners.kubernetes.volumes]

ここに載せている設定はあくまでも一例で、いくつかの設定を伏せています。Docker単体などで動かしたGitLab Runner上でgitlab-registerコマンドなどを使って設定を作成し、それをコピペした方が良いでしょう。

この時、設定ファイルではprivileged = trueとする必要があります。こうすることで、Docker in DockerができるRunnerであるということを設定しています。逆にDocker in Dockerをしたくない場合はfalseを設定します。

実行

GitLab Runnerを実行させるには、プロジェクトのリポジトリで.gitlab-runner.ymlという名前で設定ファイルを置いておく必要があります。

その設定ファイルでは、実行するコマンドを列挙しているわけですが、普通にDockerを使うように実行するだけではうまくできません。

次のように、docker:dindイメージを使い特定の環境変数を設定する必要があります。
次に、Dockerイメージを作成する.gitlab-ci.ymlファイルを載せます。

image: docker:dind

variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: ""
  CONTAINER_RELEASE_IMAGE: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_NAME
  CONTAINER_LATEST_IMAGE: $CI_REGISTRY_IMAGE:latest

stages:
  - build

build:
  stage: build
  script:
    - export DOCKER_HOST="tcp://localhost:2375"
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker build -t $CONTAINER_RELEASE_IMAGE -f Dockerfile .
    - docker tag $CONTAINER_RELEASE_IMAGE $CONTAINER_LATEST_IMAGE
    - docker push $CONTAINER_RELEASE_IMAGE
    - docker push $CONTAINER_LATEST_IMAGE

設定しなければいけない環境変数はDOCKER_HOSTとDOCKER_TLS_CERTDIRです。上のように設定すれば大丈夫です。

これで、Kubernetesで動かしているGitLab RunnerでDocker in Dockerができました。

さいごに

ここまでするのにかなり時間がかかりました。

同じことをしたいような人の参考になれば幸いです。