运行 docker 容器中的 systemd 导致主机崩溃

Running systemd in docker container causes host crash

我正在尝试创建一个基于 systemd 的 docker 容器,但是当我尝试 运行 构建容器时,我的系统崩溃了。我认为容器中的 运行ning init 可能会导致冲突,并且在某种程度上与我主机上的 systemd 冲突。

当我尝试 运行 docker 容器时,我退出了我的帐户,并简要地查看了我的系统正在经历的启动过程。我的主机是 运行ning Arch Linux,linux 4.20.7.

只有当我尝试通过 运行ning systemd 通过 /sbin/init "boot" 容器时,才会出现问题。

docker run -it \
   --volume=/sys/fs/cgroup:/sys/fs/cgroup:rw \
   --privileged 66304e3bc48

Dockerfile(改编自solita/ubuntu-systemd):

FROM ubuntu:18.04

# Don't start any optional services.
RUN find /etc/systemd/system \
    /lib/systemd/system \
    -path '*.wants/*' \
    -not -name '*journald*' \
    -not -name '*systemd-tmpfiles*' \
    -not -name '*systemd-user-sessions*' \
    -exec rm \{} \;

RUN apt-get update && \
    apt-get install --yes \
    python sudo bash ca-certificates dbus systemd && \
    apt-get clean && \
    rm -rf /var/lib/apt/lists/*

RUN systemctl set-default multi-user.target
RUN systemctl mask dev-hugepages.mount sys-fs-fuse-connections.mount

STOPSIGNAL SIGRTMIN+3

# Workaround for docker/docker#27202, technique based on comments from docker/docker#9212
CMD ["/bin/bash", "-c", "exec /sbin/init --log-target=journal 3>&1"]

我希望容器能够启动 运行ning systemd,我不是你,我可能做错了什么。

"match the host as close as possible" 是 docker-systemctl-replacement 剧本的最初目标。您可以稍后在虚拟机上 运行 的容器中测试驱动脚本。它允许在没有活动的 systemd 守护进程的情况下执行一些 systemctl 命令。

如果您愿意,它也可以用作 init 守护进程。支持 systemd 的操作系统在容器中感觉非常相似。

我最终使用了 paulfantom/ubuntu-molecule Docker 图片。

目前看来他们只是在安装systemd,设置一些环境变量,并直接使用systemd 二进制文件作为入口点。它似乎没有我在原始 post.

中提到的问题

Dockerfile

FROM ubuntu:18.04

ENV container docker
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive

RUN sed -i 's/# deb/deb/g' /etc/apt/sources.list

# hadolint ignore=DL3008
RUN apt-get update \
    && apt-get install -y --no-install-recommends systemd python sudo bash iproute2 net-tools \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

# hadolint ignore=SC2010,SC2086
RUN cd /lib/systemd/system/sysinit.target.wants/ \
    && ls | grep -v systemd-tmpfiles-setup | xargs rm -f 

RUN rm -f /lib/systemd/system/multi-user.target.wants/* \
    /etc/systemd/system/*.wants/* \
    /lib/systemd/system/local-fs.target.wants/* \
    /lib/systemd/system/sockets.target.wants/*udev* \
    /lib/systemd/system/sockets.target.wants/*initctl* \
    /lib/systemd/system/basic.target.wants/* \
    /lib/systemd/system/anaconda.target.wants/* \
    /lib/systemd/system/plymouth* \
    /lib/systemd/system/systemd-update-utmp*

RUN systemctl set-default multi-user.target
ENV init /lib/systemd/systemd
VOLUME [ "/sys/fs/cgroup" ]

ENTRYPOINT ["/lib/systemd/systemd"]

Docker 不想默认将 Systemd 包含在 docker 中,因为它会将自己发布为 应用程序容器 (这意味着每个容器一个应用程序) .还有另一种类型的容器称为 系统容器 。最著名的是 OpenVZ、LXC/LXD 和 Systemd-nspawn。所有这些都将 运行 完整 OS 与 systemd 就好像它是一个虚拟机。

和在 docker 中使用 systemd 相比 运行在 LXD

中使用 systemd 是非常危险的

甚至还有一个名为 Podman 的新婴儿,它是 docker 的克隆,但在您安装它时或当您使用已经包含 systemd 的图像时,它默认使用 systemd,就像 [=46] 的图像一样=] 云图像 http://uec-images.ubuntu.com/releases/server/bionic/release/

所以我的建议是测试 LXD 和 systemd-nspawn;并关注 Podman 它解决了 docker 不想解决的问题;阅读本文以了解 https://lwn.net/Articles/676831/


参考文献:

https://coreos.com/rkt/docs/latest/rkt-vs-other-projects.html https://podman.io/slides/2018_10_01_Replacing_Docker_With_Podman.pdf https://containerjournal.com/features/system-containers-vs-application-containers-difference-matter

运行时和特权容器的诅咒 https://brauner.github.io/2019/02/12/privileged-containers.html