64
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

dind(docker-in-docker)とdood(docker-outside-of-docker)でコンテナを料理する

Posted at

1. はじめに

コンテナの中にコンテナを立てたい、コンテナ内からホストマシンのコンテナを操作したい、そんなことを考えた方も多いのではないでしょうか。
こうした要求にこたえられる手法がdind (docker-in-docker)dood (docker-outside-of-docker)です。

  • コンテナの中にコンテナを立てたい >> dind (docker-in-docker) を使います
  • コンテナ内からホストマシンのコンテナを操作したい >> dood (docker-outside-of-docker) を使います

本記事では実際にdindとdoodを用いてコンテナを起動するまでを実施します。

想定読者

  • コンテナの起動停止、コンテナに入っての作業など基本的な操作ができる方
  • コンテナに関する基礎的な用語を理解している方
  • dind、doodの概要を知りたい方
  • dind、doodを使ってコンテナを利用したい方

2. dindとdoodについて

2.1 Dockerデーモンとtcp通信/Unixドメインソケット通信

コンテナの起動停止などを行う際にはdockerコマンドを用いてdockerデーモンに対して命令を送ります。
dockerコマンドを実行すると①TCP通信または②Unixドメインソケット通信のいずれかによりdockerデーモンへ命令が送られます。
従って、操作対象としたいマシンのdockerデーモンへ命令を送ることが出来れば、どのような環境からも対象マシン上のコンテナを操作することが出来ます。

この辺りはDocker を他のホスト・ポートや Unix ソケットに接続に記載があります。

dindやdoodではこの仕組みを利用し、命令の送り先として操作対象のマシンを明示的に指定することで実現されます。
なお、本記事では②Unixドメインソケット通信を用いることとします。

2.2 dind (docker-in-docker)

dind (docker-in-docker) はコンテナ内にホストマシンとは完全に独立したdocker環境を構築する手法です。
下図では、ホストマシン上にdocker環境があり、これとは別にコンテナA内部にもdocker環境が構築されています。

ホストマシンとコンテナAとで異なるdocker.sockファイルを保持している点に注目してください。
docker.sockは、一般的にソケットファイルと呼ばれるものでUnixドメインソケット通信に利用されます。
これはホストマシンのdockerとコンテナAのdockerが異なるdockerデーモンを操作対象としていることを意味しています。

従って、ホストマシン上でdockerコマンドを実行した場合はホストマシンのdockerデーモンに対して命令が送られます。
一方でコンテナA内部でdockerコマンドを実行した場合はコンテナAのdockerデーモンに対して命令が送られます。

ホストマシン上で起動したコンテナ(図中のコンテナA/B/C)の存在はホストマシン上からしか確認できず、コンテナA上で起動したコンテナ(図中のコンテナX/Y)はコンテナAからしか存在を確認できません。
また、当然のことながらコンテナAを停止するとコンテナX/Yも同時に停止されます。

dind.png

2.3 dood (docker-outside-of-docker)

dood (docker-outside-of-docker) はコンテナ内からホストマシンのdockerを操作する手法です。
下図では、ホストマシン上にdocker環境があり、コンテナAはホストマシンのdocker環境に接続しています。

コンテナAにはホストマシンのdocker.sockファイルがマウントされている点に注目してください。
docker.sockは、一般的にソケットファイルと呼ばれるものでUnixドメインソケット通信に利用されます。
コンテナAのdockerがホストマシンのdockerデーモンを操作対象としていることを意味しています。

従って、ホストマシン上でdockerコマンドを実行した場合も、コンテナA上でdockerコマンドを実行した場合もホストマシンのdockerデーモンに対して命令が送られます。
ホストマシン上からはホストマシン上で起動したコンテナ(図中のコンテナA/B/C)とコンテナA上で起動したコンテナ(図中のコンテナX/Y)の両方の存在を確認できます。
これは、逆にコンテナAからもすべてのコンテナ(図中のコンテナA/B/C/X/Y)の存在が確認できることを意味しています。
また、コンテナAを停止したとしてもホストマシン上で起動されているコンテナX/Yは停止されません。

dood.png

3. dind (docker-in-docker) を試す

3.1 docker:dindイメージを利用したdind

まずは一般的によく使われているdocker:dindのイメージを利用したdindの方法です。

以下のコマンドでコンテナを起動します。

docker run -it --rm --privileged --name dind -d docker:20-dind

起動したコンテナ内に入ってdocker psコマンドを実行すると何も表示されません。
これにより、コンテナ内にホストマシンとは異なる独立したコンテナ環境が構築できていることを確認できます。

C:\Users\user>docker exec -it dind sh
/ # docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

3.2 CentOSイメージを利用したdind

docker:dindのイメージを使うと簡単にdindが実現できることが分かりましたが、CentOSなどのイメージでdindを行いたい時があります。
この場合はコンテナ内で通常と同じ手順でdockerをインストールすると実現できます。

以下でcentosのコンテナを起動します。
コンテナ内でsystemctlが使用できるように--privilegedオプションを使用しています。

C:\>docker run -d --privileged --name dind centos:7 /sbin/init
C:\>docker exec -it dind bash

起動したコンテナに入り、以下の手順に従ってdockerをインストールします。

[root@00587f333c1e /]# yum install -y yum-utils
[root@00587f333c1e /]# yum-config-manager \
>     --add-repo \
>     https://download.docker.com/linux/centos/docker-ce.repo
[root@00587f333c1e /]# yum install docker-ce docker-ce-cli containerd.io
[root@00587f333c1e /]# systemctl enable --now docker

インストール完了後にdocker psコマンドを実行するとコンテナが1つも起動していないことが確認できます。
これによりホストマシンとは異なるdocker環境がコンテナ内に構築できていることが確認できました。

[root@00587f333c1e /]# docker ps
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

4. dood (docker-outside-of-docker) を試す

4.1 dockerイメージを利用したdood

doodを実現するために、下記のコマンドでdockerイメージを起動します。
-v /var/run/docker.sock:/var/run/docker.sockオプションによりホストマシンのソケットファイルをコンテナ内へマウントさせています。

docker run -it --rm -v /var/run/docker.sock:/var/run/docker.sock --name dood docker:20

起動したコンテナ内からdocker psコマンドを実行してみるとホストマシン上で稼働しているコンテナ(この場合だと自分自身のコンテナ)が確認できます。

コンテナ内から実行中のコンテナ一覧を取得
/ # docker ps
CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS     NAMES
af159e03e643   docker:20   "docker-entrypoint.s…"   3 seconds ago   Up 2 seconds             dood

4.2 CentOSイメージを利用したdood

dindと同じく、centosなどを用いてもdoodは実現できます。
先ほどと同じく、ソケットファイルをマウントしてコンテナを起動します。

docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name dood centos:7 /sbin/init

コンテナ内へ入り、docker-cliをインストールします。
doodではコンテナ内でdockerデーモンを起動するわけではないのでインストールするのはCLIのみで大丈夫です。

[root@86a4aff52d05 /]# yum install -y yum-utils
[root@86a4aff52d05 /]# yum-config-manager \
>     --add-repo \
>     https://download.docker.com/linux/centos/docker-ce.repo
[root@86a4aff52d05 /]# yum install docker-ce-cli

インストール完了後にdockerコマンドを実行すると、ホストマシン上で起動しているコンテナを確認することができました。

[root@86a4aff52d05 /]# docker ps
CONTAINER ID   IMAGE      COMMAND        CREATED          STATUS          PORTS     NAMES
86a4aff52d05   centos:7   "/sbin/init"   16 minutes ago   Up 16 minutes             dood
00587f333c1e   centos:7   "/sbin/init"   24 minutes ago   Up 24 minutes             dind
64
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
64
47

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?