🤖

🤖

:gijutsu_burogu:

Docker で立てた CI で Docker Build する -Docker in Docker と /var/run/docker.sock

はじめに

CI では毎回まっさらな環境でテストやビルドができます。 これには、多くは Docker が用いられています。 さらには、Docker で実現されたまっさらな環境でも Docker ビルドなど Docker を利用できます。

前提知識: Docker クライアントと dockerd

f:id:kotaroooo0:20200808201657p:plain
dockerクライアントとdockerd

アーキテクチャの理解 — Docker-docs-ja 1.11.0 ドキュメント

Docker コマンドとdockerdは別物で、API クライアントと API サーバーのような関係です。 dockerdは、Docker デーモンのことです。

例えば、Docker for Mac ではこのようなイメージです。 Docker は Linux カーネルを必要とするため、Mac 単体では動きません。 そこで、HyperKit を使い VM 上に LinuxKit を立ち上げています。 Mac のターミナルから、LinuxKit の dockerd に命令を送っています。

f:id:kotaroooo0:20200814112145p:plain
Docker for Mac

CI では Docker コンテナで Docker コマンドを使う

EC2 上で Docker により Jenkins を動かす時などでは Docker コンテナ内で Docker コマンドを使う必要があります。 docker build でイメージをビルドして、docker push でレジストリにイメージをプッシュすることが多々あります。 どのようにコンテナ上で Docker を利用するべきでしょうか。

docker in docker

docker in docker は以下のようなイメージです。

f:id:kotaroooo0:20200809125859p:plain

docker in docker は元々、Docker の開発自体のために作られました。 Docker インストール済みのコンテナを使用しコンテナ内でホストとは別に dockerd を動かす方法です。 dindと一般的に呼ばれています。

$ docker run --privileged --name dind -d docker:dind

--privileged オプションにより、コンテナ内からホストのリソースを扱える権利を持たせます。

GOOD
  • ホストの Docker とは完全に別物の Docker 環境が利用可能
BAD
  • -privilegedを使う必要があり脆弱性があります
  • /var/lib/dockerをマウントするので Data Volume がファイルが溜まっていきます
  • CI が再ビルドを行う時、dind コンテナを再起動するたびにそのキャッシュを無効になります

/var/run/docker.sockをマウント

ホストの dockerd のソケットファイルをマウントして、そこに処理をリクエストします。 イメージは以下です。

f:id:kotaroooo0:20200809125858p:plain

Docker out of Docker(dood)と呼ばれます。

GOOD
  • dockerd はホストのものを使うので、毎回同じでありキャッシュが利用できます
  • ディスクスペースを節約できます
BAD
  • ホストで動いている他のコンテナも見えます(完全に独立していない)
  • ホストマシンのルートを取れます
$ docker run -t -i -v /var/run/docker.sock:/var/run/docker.sock debian:jessie /bin/bash
$ apt-get update && apt-get install wget -y && wget -qO- https://get.docker.com | sh
$ docker images # ホストのイメージが表示される
$ docker run -t -i -v /:/host debian:jessie /bin/bash
$ chroot /host # ホストのルートが取れる

どっちを使うべき

EC2などで自分でCIを構成する場合は、doodを使うのが好ましいです。 また、GitHub ActionsなどカスタマにCIを提供する場合では、dindが好ましいです。

参照

jpetazzo.github.io

toris.io

rimuru.lunanet.gr.jp