我正在尝试创建一个基于systemd的Docker容器,但是当我尝试运行已构建的容器时,系统崩溃。我认为在容器中运行init可能会引起冲突,并以某种方式与我主机上的systemd发生冲突。
当我尝试运行docker容器时,我已从帐户中注销,并简要查看系统在引导过程中的情况。我的主机正在运行带有Linux 4.20.7的Arch Linux。
仅当我尝试通过/sbin/init
运行systemd来“引导”容器时,才会出现问题。
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"]
我希望该容器仅在运行systemd的情况下启动,而不是您可能做错的事。
答案 0 :(得分:1)
docker-systemctl-replacement脚本的最初目标是“尽可能匹配主机”。您可以在可能稍后在虚拟机上运行的容器中测试驱动器脚本。它允许在没有活动的systemd守护程序的情况下执行一些systemctl命令。
如果愿意,它也可以用作init守护程序。启用了systemd的操作系统在带有容器的容器中会感觉非常相似。
答案 1 :(得分:1)
Docker不想默认将Systemd包含在docker中,因为它将自己发布为应用程序容器(这意味着每个容器一个应用程序)。还有另一种类型的容器,称为系统容器。最知名的是OpenVZ,LXC / LXD和Systemd-nspawn。所有这些都将像使用虚拟机一样在systemd上运行完整的操作系统。
与在LXD内部运行systemd相比,在docker内部使用systemd如此危险
甚至还有一个名为Podman的新婴儿,它是docker的一个克隆,但默认情况下在安装它或使用包含已包含systemd的映像(例如ubuntu云映像http://uec-images.ubuntu.com/releases/server/bionic/release/ < / p>
所以我的建议是测试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
答案 2 :(得分:0)
我最终使用了paulfantom/ubuntu-molecule Docker映像。
当前看来,他们只是在安装systemd,设置一些环境变量,并直接将systemd二进制文件用作入口点。似乎没有我在原始帖子中提到的问题,它可以正常工作。
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 $1
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"]