使用dind(容器中容器)和dood(容器外的容器)来操作容器
首先
很多人可能会考虑在容器中放置容器,从容器内部操作主机上的容器。满足这些要求的方法是 dind(容器内部的 docker)和 dood(容器外部的 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](https://cdn.silicloud.com/blog-img/blog/img/657d1fee37434c4406c1d334/17-0.png)
2.3 dood(docker外部的docker)
dood(docker-outside-of-docker)是一种从容器内部操作主机上的docker的方法。
在下面的图中,主机上有一个docker环境,容器A连接到主机上的docker环境。
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](https://cdn.silicloud.com/blog-img/blog/img/657d1fee37434c4406c1d334/22-0.png)
尝试使用dind (docker-in-docker)。
使用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来实现。
使用–privileged选项启动CentOS容器,以便在容器内可以使用systemctl。
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
尝试使用dood(在Docker外部的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