在预先存在的网络命名空间中运行 docker

在预先存在的网络命名空间中运行 docker

我需要在预先存在的命名空间中运行 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都无关紧要。dockerdocker-compose
  • containerd在默认网络命名空间中运行,该命名空间具有创建容器所需的所有适当的 cgroup。
  • dockerd正在您的命名空间内运行,因此它将在此命名空间内创建所有网络接口,并且所有容器网络都将默认在此命名空间内生成。

最后要注意的是,除非您设置服务以在启动时创建网络命名空间,否则您可能希望禁用 docker,并让启动脚本创建命名空间,然后启动 docker。此外,您可能需要chattr +i在您的单元文件上运行以防止更新覆盖您的配置更改。

相关内容