概要
このエントリは、「Enterprise "hello, world" 2018 Advent Calendar 2018」の12/23向けのものです。このAdvent Calendarでは、複数個のエントリにまたがる話の流れも鑑みつつ、なるべく1エントリで1つのトピックをカバーできるようにする予定です。
このエントリで記載するトピックは、GitLab Runnerでprivate repositoryにpushすることです。
下図のような環境で、GitLabにpushしたコードからGitLab runnerが起動され、GitLab RunnerがDocker in Dockerのデーモンを使ってテストとビルドを実行し、結果として出来上がったコンテナをprivate registryにpushするまでを扱います。
前提
おことわり
- このEnterpfise "hello, world"シリーズは、ネタのためのエントリです。実環境でそのまま利用ことを目的とはしていません。
- 動かしやすさを優先してセキュリティを意図的に低くする設定など入れてありますのでご注意ください。
想定読者
「Enterprise "hello, world" 2018」的なネタとしては、下記のような状況を想定しています。
GitLab runnerでテスト実行まではできているので、次はコンテナ化が必要だ
関係するエントリ
以下が特に関係します。
- CI/CDのためにGitLab RunnerをDockerで動かす準備~EHW2018「環境整備⑧」
ぼやき
エントリ執筆時点で、EHW2018のシリーズで用意している環境においては、GitLab runnerの機能で「service」を利用してDocker-in-Dockerを実現する際、なかなかうまくいかない部分がありました(なんとなく、こちらと似たような状況。。などを含み、他との絡みもあり)。この部分はあきらめて、docker-composeでrunnerの外側にdindを用意しています。
動かすまで
GitLab runnerの準備
GitLab runnerは、どのジョブを実行するかについて「タグ」を付与しておくことができます。以前のエントリでは、タグとして「test」だけを使っていましたが、今回の目的のため「container」も増やしておきます(下図)。
(参考)
タグで適切なものが見つからないと、GitLab runnerのジョブがスタックします(下図)
。
Docker in Docker用のサービスを上げる
Docker in Docker(DinD)は、Docker内でDockerを動かすための仕組みです。公式サイトの説明
今回のシリーズでこの構成にした理由は、ホスト側の環境とCI用の環境を別にしたかったためです。GitLab RunnerのジョブからDockerを使用する際、ホスト側のDockerを使ってしまうとビルド時のゴミがホスト側にも見えてしまってわかりにくくなってしまうため、CIで使うものはすべてこのDinD環境で実行するようにしています。
docker-compose.ymlに以下を追加します。
補足:privileged: trueにすると、コンテナがホスト側の資源に触れるものが増えてしまっていろいろ危険である面があり悩ましいところですが、今回は目をつぶっています。
dind:
image: docker:dind
networks:
- extnet
privileged: true
links:
- samba
- registry
CIのパイプラインにジョブを増やす
以前のエントリで作ったものに対して、下図のように、stagesにジョブを2つ追加します。
以下が、ちょっとしたポイントです。
- Dockerのプライベートレジストリは、dockerのプライベートレジストリに作ったコンテナを格納する~EHW2018「MVPをコンテナ化③」で作ったものです。DockerホストのネットワークアダプタのIP上にポートを指定しています。Rancherで、別ホストのk8s環境に対してデプロイをするときにも使いたいためです。
- GitLab runnerのvariablesとして、「DOCKER_HOST」を指定しています。
image: node:8-alpine
variables:
DOCKER_HOST: tcp://dind.ehw2018.local:2375/
DOCKER_DRIVER: overlay2
before_script:
- ifconfig -a
- cat /etc/hosts
- apk update
- apk add docker
- docker info
stages:
- test
- containerize
- ship
exec_test:
stage: test
tags:
- test
script:
- npm install
- npm run test
containerize:
stage: containerize
tags:
- container
script:
- docker build -t front-test .
ship:
stage: ship
tags:
- container
script:
- docker tag front-test 10.0.2.15:5443/front-test:latest
- docker push 10.0.2.15:5443/front-test:latest
Registryにpushする準備
これまでの手順だけでは、DinDからPrivate Registryにpushしようとしたときに証明書のエラーが出てしまいます。
お使いの環境(ホスト名やIPアドレス)に合わせ、Private Registryの証明書をDinDのコンテナにも格納しておきます。
パスは、下記です。
/etc/docker/certs.d/{Private Registryのアドレス}:{ポート}/ca.crt
実行
ここまでの手順を踏むことで、GitLabのmasterブランチにコードをプッシュすると、3つのジョブが実行されるようになります。
- testジョブは、以前のエントリの通りの動作です。
- containerizeジョブは、以前のエントリのDockerfileを使ってビルドしています。
- shipジョブは、出来上がったコンテナをPrivate Registryにpushしています。
まとめ
このエントリでは、「Enterprise "hello, world" 2018 Advent Calendar 2018」(EHW2018)の23日目として、GitLab Runnerでprivate repositoryにpushすることをトピックとして取り上げました。
EHW2018のネタとしては、pushしたイメージを使って環境にデプロイすることを考えています。