首页 > 大数据 > > 我在 Docker 里面起 Docker
更新:
我发了之后携程的大佬告诉我还有一种更常用的 docker in docker 的方法。

从上面的架构图可以看出,Docker 是典型的C-S架构,通过`/var/run/docker.sock`通信,那么把 socket mount到 container 内部,就可以达到调用外面 docker 命令的目的。

如果只是要调用 docker 命令,这是一个比下面命令更加安全的做法。
最近遇到的两个问题最后都用一个参数搞定了。通过它,甚至可以在 Docker 的container 里面起一个新的 container。就像这样:

左边是在 container 的 sh 会话里。跑一个 hello-world 看看。

这个能在 docker 里面跑 docker 的有趣的命令就是说
docker run -it --rm --privileged --pid=host alpine:edge nsenter -t 1 -u -i -m -n sh 这个命令涉及到了很多Linux本身的功能,最主要的就是namespace,也就是 docker可以隔离的根本。
Linux 进程分为 priviledged process 也就是 root 用户起的进程,和 unpriviledged process 就是普通用户起的进程。 --privileged 就是起 priviledged container 进程。
--pid=host 给了container 宿主的进程 namespace,Linux 的进程是树状结构,第一个启动的进程是PID 为1的进程,其他进程都是这个进程的子进程。 container 在启动的时候有自己的进程 namespace,在这个 namespace 里只能看到自己进程和子进程构成的进程树。本来是这样的:

加了参数是这样的:

alpine:edge 是一个轻量级的Linux系统。
nsenter又是一个Linux下面操作namespace的命令,从英文上理解就是 enter namespace的意思,顾名思义是用来进入目标进程的namespace。这里我们进入了PID 1进程的namespace,并且进入了这个进程的UTS (hostname信息) IPC (进程间通信)PID(进程信息)mount(文件信息)network(网络信息)的各种namespace。
简单的描述就是通过提权进入宿主的资源空间,来达到调用宿主的 docker 方法的目的。
这个命令也不是仅仅用来在 docker 里面起 docker 玩。Mac 因为系统的原因没办法直接跑docker,docker 其实是跑在一个特制的叫 LinuxKit 的 Linux 系统中。我有一个叫 docker_dist 的 volume。我想查看里面的文件。我像下面这样直接在 Mac 上面访问 volume 的地址是找不到的。

现在我可以通过上面的命令进入到跑 docker container 的宿主,也就是 Docker 在 Mac 上面起的虚拟机,文件就保存在那里。

直接起的container,因为 namespace 的隔离特性,是访问不到宿主的文件,网络等任何资源的。现在就能直接访问到了,真香。
参考链接
Docker can now run within Docker - Docker Blog
pid_namespaces(7) - Linux manual pagehttps://hackernoon.com/the-curious-case-of-pid-namespaces-1ce86b6bc900linuxkit/linuxkit
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31537575/viewspace-3124867/ ,如需转载,请注明出处,否则将追究法律责任。