如果你还搞不懂 Docker In Docker(DinD) 模式下的资源管理, 不妨看看这篇文章
如果你还搞不懂 Docker In Docker(DinD) 模式下的资源管理, 不妨看看这篇文章
如果在 公众号 文章发现状态为 已更新, 建议点击 查看原文 查看最新内容。
状态: 未更新
原文链接: https://typonotes.com/posts/2023/04/04/docker-dind-mode-introduce/
今天遇到了一个群友关于 Docker DinD 的问题。
有人熟悉docker in docker么 请教个问题, 我现在在docker-1里面挂载了本地的/root/.m2 想在里面启动一个新的docker在build的时候使用 这个目录下的缓存 有人做过么~
需求是想要通过 容器1 启动 容器2, 同时要求 容器2 也能挂载并使用 .m2
目录, 加入 JAVA 的应用的构建。
其实 DinD 说通了并不难。 想来难的地方应该也就是 理不清楚各个容器之间的关系
Docker 常规操作模式
首先抽象一下 Docker 的操作, 提出两个重点组件
- docker.sock:
/var/run/docker.sock
。 套接字, 为用户提供管理 docker 引擎的接口。 - docker CLI: 命令行工具。 面向用户提供 语义化 的接口操作方式。
任何符合 docker.sock
通信的方式和操作, 都能控制 docker 引擎。
本机操作
我们从 本机操作 开始, 一步步扩展开, 比较容易理解
从图中可以看到, 当 cli 和 sock 都在本机的时候, 所有注入的 环境依赖(变量、路径挂载、端口映射等) 都是直接使用 宿主机 的。
这个时候的认知最简单。
启动
|
|
远程操作
同时 Docker 还提供了远程操作方式。
这个时候保证本机的 docker 引擎 未安装 或者 未启动, 以避免产生理解歧义。
当在 cli 的机器上, 配置 DOCKER_HOST
变量的时候, 就可以实现远程的 sock 操作。
设置环境变量, 指定远程宿主机
|
|
本地执行查看命令
|
|
本地启动容器
|
|
登陆到远程宿主机, 查看所启动的容器
|
|
可以看到, 本地操作远程是完全没有问题的。
注意 由于本地没有安装 docker 引擎, 且只下载了一个 cli 命令行工具。 所以在 注入环境依赖 的时候, 通常也不会造成困惑, 会默认使用 宿主机 资源。
除此之外, Docker 还提供了 HTTPS接口 的远程操作方式。 这里就不讨论了。 不过额外强调一句, 如果要开这种模式, 一定要配置证书和身份验证, 否则不小心开到公网, 就是被别人当成木马马场用。
Docker DinD 模式
所谓的 Docker-in-Docker
模式, 就是将 docker.sock
挂载到启动的 容器A 中, 而容器A提供 操作方式/界面(例如 cli 命令工具)
在 宿主机 执行 docker:dind 容器, 并挂载 docker.sock
到容器中
|
|
通过上图可以看到, 我们通过挂载 docker.sock
到 container01 中后, 相当于在 container01 中同时拥有了 docker.sock
和 docker cli
, 这种情况和 本地操作 类似。
这里就是困惑点: 当我在 container01 中新启动一个容器的时候, 此时如果需要挂载 资源(例如映射文件目录), 应该使用 container01 的路径? 还是 宿主机 的路径?
在 容器中 执行 docker run
命令, 启动一个新容器
|
|
重新看图,其实这点很简单了。
- 虽然是是在 container01 中执行的
docker run
命令, 但是调用的docker.sock
套接字是 从宿主机挂载到container01中 的。 - 因此实际上还是通过 宿主机 启动的 container02。 换句话说,
- container02 的父节点是 宿主机
- contaienr02 和 container01 是兄弟关系。
在 container01 中, 通过命令我们之前启动的三个容器。
|
|
另外一种 DinD
如果有人说, 我启动 container01 的时候不挂载 docker.sock, 而是直接在 contianer01 中完整安装一个 docker 引擎。 这种情况应该怎么挂载呢?
如果是在 container01 中执行的的启动命令, 这个时候肯定就是挂在 container01 对应的路径。
不过, 不得不强调一下 这种把容器当成虚拟机的用法, 还是敬而远之吧。
总结
其实很简单, 就一句话: 谁 执行 容器的启动, 就挂载谁的路径。
思考题
我们知道在 k8s 中, 简略的调度过程是这样的 user -> master api-server -> node kubelet -> docker.sock/containerd.sock
。
那么, 用户在任意地方启动 pod 的时候, 如果需要挂载 node 的目录资源到 pod 中, 应该是用 用户所在机器的目录路径? master 节点路径? 还是 node 节点路径?
- 原文链接:https://typonotes.com/posts/2023/04/04/docker-dind-mode-introduce/
- 本文为原创文章,转载注明出处。
- 欢迎 扫码关注公众号
Go与云原生
或 订阅网站 https://typonotes.com/ 。 - 第一时间看后续精彩文章。觉得好的话,请猛击文章右下角「在看」,感谢支持。