![在预先存在的网络命名空间中运行 docker](https://linux22.com/image/769836/%E5%9C%A8%E9%A2%84%E5%85%88%E5%AD%98%E5%9C%A8%E7%9A%84%E7%BD%91%E7%BB%9C%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E4%B8%AD%E8%BF%90%E8%A1%8C%20docker.png)
我需要在预先存在的命名空间中运行 docker,该命名空间不是由 docker 基础架构创建的。可以这样做吗?我知道重用另一个容器选项,但正如我提到的,预先存在的 ns 不是由 docker 基础架构创建的(因此回答这问题无关紧要)。我需要 Linux 的解决方案。
答案1
编辑你的docker systemd单元文件,你可以通过以下方式找到它systemctl status docker.service
● docker.service - Docker 应用程序容器引擎已加载:已加载(/usr/lib/systemd/system/docker.service;已禁用;预设:已禁用)
修改[Service]
单元文件的一部分/usr/lib/systemd/system/docker.service
:
[Service]
Type=notify
# This tells systemd to run dockerd in the network namespace
NetworkNamespacePath=/run/netns/ns_name
# This is the original docker command, it caused some issues for me
#ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
# This is the replacement if the default exec doesn't work
ExecStart=/usr/bin/dockerd -H fd://
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutStartSec=0
RestartSec=2
Restart=always
现在刷新配置并启动docker
systemctl daemon-reload
systemctl restart docker
如果你很幸运,你现在可以尝试运行一个docker容器,它就可以正常工作了。但是,有时containerd和docker之间的配置不太顺利,你会得到以下错误:
守护进程的错误响应:无法为容器创建任务:无法创建 shim 任务:OCI 运行时创建失败:runc 创建失败:无法启动容器进程:exec:“/sbin/tini”:stat /sbin/tini:没有此文件或目录:未知
此错误似乎是由于 containerd 和 docker 之间的配置错误造成的。打开containerd
单元文件并将其替换ExecStart
为以下内容:
ExecStart=/usr/bin/containerd --config=/var/run/docker/containerd/containerd.toml
这将告诉 containerd 使用 docker 的配置,在重新加载配置并重新启动所有服务后,您的容器应该可以正常工作。坦率地说,此时重新启动机器更容易。
至于其作用,我们得到了一系列有趣的效果。
- 可执行文件通过 unix 套接字
docker
进行通信,因此只要套接字可访问,您运行什么命名空间或从哪个命令dockerd
都无关紧要。docker
docker-compose
containerd
在默认网络命名空间中运行,该命名空间具有创建容器所需的所有适当的 cgroup。dockerd
正在您的命名空间内运行,因此它将在此命名空间内创建所有网络接口,并且所有容器网络都将默认在此命名空间内生成。
最后要注意的是,除非您设置服务以在启动时创建网络命名空间,否则您可能希望禁用 docker,并让启动脚本创建命名空间,然后启动 docker。此外,您可能需要chattr +i
在您的单元文件上运行以防止更新覆盖您的配置更改。