Docker in Dockerの種類
Docker in Dockerには二種類あり、ホストのDocker daemonと共有し、自分自身と同じ階層にコンテナを増やしたりする方法と、dockerコンテナの中でdockerコンテナを起動する、dockerマトリョーシカがある。
↓の記事にうまくまとめられているのでここでは深く説明しません。
https://qiita.com/sugiyasu-qr/items/85a1bedb6458d4573407
この記事ではコンテナの中にコンテナを生成するDocker in Dockerについて記載します。
コンテナの中のコンテナ
VirtualBoxやVMwareなどの仮想化技術でも仮想化環境の中で仮想化することは出来るようです。「nested virtualization」と検索すると記事がいろいろ出てきます。例えば今あるVPSやクラウドなどで一人一人に与えられるリソースはたいていの場合は物理マシンではなく仮想マシンで与えられるためその中で個々人が仮想化を行おうとすると仮想化の中の仮想化を行なっているということになります。
使われ方としては与えられた仮想マシンの中で仮想化をするということで、継続的インテグレーションなどでも使われています。
同様に準仮想化と呼ばれるコンテナの中でコンテナを起動することもできます。今回はDockerでの話をします。
メリット
階層型にリソースの制限ができる
例えば1台の物理サーバー上にWebサーバが3台、DBが2台あるとします。
このとき、DBに7割のCPUやディスクの読み書きのリソースを与え、3割をWebサーバにしたいとなったときに、Docker in Dockerの場合はDBが入っているコンテナとWebサーバが入っているコンテナを制限すればよいです。注意として、全てを並列で動かすときにもリソースの制限はできます。しかし、階層型の方がより直感的で人間にとってわかりやすいと思います(=コンピュータにとって負荷が大きい)
別のコンテナへのアクセスを制限することが出来る
Docker Daemon共有化では、ホストマシンのDockerを使って横にコンテナを増やしたりすることで擬似的にDocker in Dockerを実現します。しかし、ホストマシンのDockerを操作できるということは、別に動かしているコンテナや自分自身を止めることもできるということになります。外部からのアクセスによってDocker in Dockerを動かす場合、動かし方によっては脆弱性となりえます。
一方、Dockerマトリョーシカにしてしまう場合は、子にしかアクセスできないため別のコンテナへのアクセスはできません
デメリット
負荷が大きい
不可の原因は具体的にはわかっていませんが、僕の場合は一時期コンテナ作るのに10秒かかる状況がありました。その時に一番負荷がかかっていたのはディスクIOで、おそらく後述する差分ストレージによる問題と考えています。
動作が一部不安定
Docker in Dockerを進めたJérôme PetazzoniさんによるとAppArmerやSELinuxなどLinux Security Modules絡みでクラッシュすることがあるようです。
https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/
Dockerのストレージドライバ
Dockerコンテナ内で使われるストレージはいろんなファイルシステムで実装されています。
http://docs.docker.jp/engine/userguide/storagedriver/selectadriver.html
DockerはもともとAUFSで作られていましたが、ホストのファイルシステムが原因でRHEL/CentOS系では利用できませんでした。そのためDockerではDevicemapperというストレージドライバも使われるようになりました。そのため、現在のdockerでも使われるストレージドライバは決まっておらずOSやホストのファイルシステムによって決められています。
↑の図に書いてあるようにそれぞれストレージドライバによって適したものを選択する必要があります。
それぞれのストレージドライバのコンテナの作成速度を比較した図があります。この中ではoverlayfsが一番早く動作していることがわかります
使われ方
Docker in DockerはやはりCI(継続的インテグレーション)での使われ方が多いようです。Dockerをプロダクト環境で使うということもありJenkinsなどをprivileged権限をつけて使われることが多いようです。そもそもDocker in DockerはDockerの開発のワークフロー改善のために作られていました。
まとめ
今回Docker in Dockerの良いところ、悪いところを記述してみましたが、実際にはDocker in Dockerを動かして見て問題なく動くかどうかを調べると良いと思います。