GitLab CI で kaniko を使ってコンテナイメージを build / push

CI パイプラインは Docker コンテナ Runner で実行することが一般的なので、パイプラインの中で docker build するには privileged モードで Runner のコンテナを実行する必要があります。いわゆる DinD (Docker in Docker) です。

build:
  image: docker:latest
  script:
    - docker build -t registry.gitlab.com/kondoumh/sandbox -f Dockerfile .
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD registry.gitlab.com
    - docker push registry.gitlab.com/kondoumh/sandbox
  services:
    - docker:dind

kaniko は Google 謹製のコンテナイメージビルドツールです*1

github.com

Docker daemon に依存せず、コンテナ内、もしくは Kubernetes cluster の Pod 内で Dockerfile からイメージをビルドできるため、DinD を回避しセキュアに運用できます。

GitLab CI でも kaniko の利用ガイドがありました。

Building images with kaniko and GitLab CI/CD | GitLab

/kaniko/.docker/config.json に Container Registry とそのユーザー名、パスワードを設定し、kaniko executer に Dockerfile や push 先などのコンテキストを渡して実行します。kaniko のイメージは debug タグを指定する必要があります。

build:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  script:
    - echo "{\"auths\":{\"registry.gitlab.com\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json
    - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG

docker:dind を services に指定する必要はありません。実行するとちゃんとイメージが push されました。

f:id:kondoumh:20191228145020p:plain

gitlab.com もいつの間にか Container Registry 提供していたんですね。

*1:蟹工船に由来するネーミング?