Ubuntu 18.04 上の GitLab CI で Docker イメージをビルドして GCP の Container Registry に登録するまで

環境

さくらVPSUbuntu 18.04 をOSカスタムインストールしていて、GitLab CE をインストールします。GitLab CI Runner も同ホストで動かします。 CI で Docker イメージをビルドして、Google Cloud Platform (GCP) の Container Registry にプッシュします。

GitLab のインストール

下記のページの通りです。EEとCEの差はライセンスを適用するかどうかで変わりますが、絶対にCEのままというならインストールスクリプトのURLを変えるとそちらでインストールされます。

about.gitlab.com

GitLab CI 機能の設定

Docker CE をインストール

単に apt からインストールもできますが、バージョンが古いと嵌りやすいので最新の Docker CE をインストールします。

docs.docker.com

GitLab Runner のインストール

こちらは、Dockerへのインストールではなく、リポジトリからインストールしました。GitLab Runner はほぼ CI Runner のコマンド管理ツールで、実際ジョブ処理する Runner (ないし Executor) は次でインストールという認識です。

docs.gitlab.com

実際の GitLab Runner(Executor) として動作するDockerコンテナを登録

下記の Building Docker images with GitLab CI/CD ページ内の Use docker-in-docker executor* を実行します。 https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#use-docker-in-docker-executor

リポジトリの CI 設定

GCP にストレージ管理者権限を持つサービスアカウントを作成し、JSONキーファイルを取得します。 https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file

Settings -> CI / CD -> Variables

  • GCLOUD_PROJECT_ID - GCP のプロジェクトID
  • GCLOUD_SERVICE_KEY - JSONキーファイルの中身を貼り付ける

.gitlab-ci.yml

下記のように設置する。例では gcr.io/<GCP project ID>/<repository group name>/<repository name> でイメージが push されます。

image: tilfin/gitlab-ci-to-gcr

services:
  - docker:dind

variables:
  DOCKER_DRIVER: overlay
  IMAGE_NAME: "$CI_PROJECT_PATH:latest"

before_script:
  - echo $GCLOUD_SERVICE_KEY > ${HOME}/gcr-key.json
  - gcloud auth activate-service-account --key-file ${HOME}/gcr-key.json
  - docker login -u _json_key --password-stdin https://gcr.io < ${HOME}/gcr-key.json

stages:
  - publish

publish:
  stage: publish
  script:
    - docker build -t $IMAGE_NAME .
    - docker tag $IMAGE_NAME "gcr.io/$GCLOUD_PROJECT_ID/$IMAGE_NAME"
    - docker push "gcr.io/$GCLOUD_PROJECT_ID/$IMAGE_NAME"
  only:
    - master
  • dindDocker IN Docker の略です。
  • overlay ストレージ・ドライバは Ubuntu 18.04 であれば利用できます。Docker 入れ子でもストレージは透過的にホストにアクセスすることでスピードが下がらないようにします。

補足) tilfin/gitlab-ci-to-gcr

tilfin/gitlab-ci-to-gcr イメージは、私が公式 Docker Hub にプッシュしてる docker:stableGoogle Cloud SDK と gcloud コマンドをインストールしたものです。

https://hub.docker.com/r/tilfin/gitlab-ci-to-gcr/

FROM docker:stable 
ARG CLOUD_SDK_VERSION=224.0.0
ENV CLOUD_SDK_VERSION=$CLOUD_SDK_VERSION

ENV PATH /google-cloud-sdk/bin:$PATH
RUN apk --no-cache add \
        curl \
        python \
        py-crcmod \
        bash \
        libc6-compat \
        openssh-client \
        git \
        gnupg \
    && curl -O https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-sdk-${CLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \
    tar xzf google-cloud-sdk-${CLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \
    rm google-cloud-sdk-${CLOUD_SDK_VERSION}-linux-x86_64.tar.gz && \
    ln -s /lib /lib64 && \
    gcloud components install kubectl && \
    gcloud config set core/disable_usage_reporting true && \
    gcloud config set component_manager/disable_update_check true && \
    gcloud config set metrics/environment github_docker_image && \
    gcloud --version
VOLUME ["/root/.config"]

総括

もともと Registry 機能自体も GitLab にありストレージだけ GCP を利用することもできます。しかし、マルチドメインでの運用でうまくいかない場合があったのと、可用性の面で直接 GCP の Registry を参照する方がいいため、このようにして使っています。