如何在 Arch Linux Docker 容器中运行 systemd 服务?

如何在 Arch Linux Docker 容器中运行 systemd 服务?

人们似乎可以通过多种不同的方式在 Docker 容器中运行 systemd 服务。最新的例子是直接建议我发现使用--volume=/sys/fs/cgroup:/sys/fs/cgroup:ro --cap-add=SYS_ADMIN --security-opt=seccomp:unconfined.然而,它仍然只是失败

错误:无法启动服务[ntpd]:执行“/usr/sbin/systemctl start ntpd”返回1:无法连接到总线:没有这样的文件或目录

要在具有最新 Arch Linux 发行版的 docker 1.12.1 容器上的 systemd 231 下运行简单服务,我至少需要做什么?

答案1

我在测试需要 systemd 的 Ansible playbook 时遇到了同样的问题。正如您所说,docker 似乎是最好的方法,因为启动和关闭容器比虚拟机要容易得多。
首先基础/archlinux图像已被弃用 - 你应该使用archlinux/基地反而。然后,要完全以非特权方式运行 systemd,需要完成以下几件事:

  • 提供一个container=变量,这样 systemd 就不会尝试执行引导硬件机器时通常执行的许多操作
  • systemd 主动使用 cgroup,因此/sys/fs/cgroup从主机绑定挂载文件系统
  • /sys/fs/fuse不需要绑定安装,但有助于避免依赖熔丝的软件出现问题
  • systemd 认为tmpfs到处使用是一个很好的方法,但是以非特权方式运行使其无法安装到tmpfs任何它想要的地方,因此预先安装tmpfs/tmp,/run/run/lock
  • 作为最后一位,您需要指定sysinit.target为默认启动单位,而不是multi-user.target其他,因为您确实不想在容器内启动图形化的东西

结果命令行是

docker run \
  --entrypoint=/usr/lib/systemd/systemd \
  --env container=docker \
  --mount type=bind,source=/sys/fs/cgroup,target=/sys/fs/cgroup \
  --mount type=bind,source=/sys/fs/fuse,target=/sys/fs/fuse \
  --mount type=tmpfs,destination=/tmp \
  --mount type=tmpfs,destination=/run \
  --mount type=tmpfs,destination=/run/lock \
    archlinux/base --log-level=info --unit=sysinit.target

如果我们正在讨论在那里运行特定的服务,例如您示例中的 ntpd,您将需要添加

--cap-add=SYS_TIME

否则ntpd会因权限拒绝而失败,因为没有人希望容器默认设置系统时间。

PS 我花了相当长的时间来学习 systemd 的行为方式并设法让它在许多操作系统映像上工作。我在一篇文章中描述了我的经历在 docker 容器中运行 systemd。它是俄语的,但我相信谷歌翻译应该可以在您的浏览器中使用。谢谢

相关内容