一千萬個為什麽

搜索

在Docker容器內部運行systemd是否有任何具體和可接受的解決方案?



我已經看到了許多解決方案,以便在docker容器內運行systemd,但看起來像是其中大多數都會危及容器和主機的安全。這裏的大多數人如何處理在容器內運行systemd特定的東西。

轉載註明原文: 在Docker容器內部運行systemd是否有任何具體和可接受的解決方案?

一共有 2 個回答:

你沒有提及你在容器內使用的是什麽發行版(這可能會影響你正在使用哪個系統版本),但是下面的代碼將成功啟動一個運行systemd的CentOS容器:

docker run -it --rm \
  -e container=docker \
  --tmpfs /run \
  --tmpfs /tmp \
  -v /sys/fs/cgroup:/sys/fs/cgroup:ro \
  --cap-add SYS_ADMIN \
  centos /sbin/init

這是與Docker 17.05.0-ce;舊版本可能需要額外的標誌。使用庫存 centos:7 圖像,容器內的初始環境如下所示:

# systemctl status
    State: running
     Jobs: 0 queued
   Failed: 0 units
    Since: Mon 2017-12-04 17:47:15 UTC; 45s ago
[...]

和:

# ps -fe
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 17:47 ?        00:00:00 /sbin/init
root        16     1  0 17:47 ?        00:00:00 /usr/lib/systemd/systemd-journald
dbus        26     1  0 17:47 ?        00:00:00 /bin/dbus-daemon --system --address=systemd: --nofork --nopidfile --systemd-activation
root        28     1  0 17:47 ?        00:00:00 /usr/lib/systemd/systemd-logind
root        30     1  0 17:47 console  00:00:00 /sbin/agetty --noclear --keep-baud console 115200 38400 9600 vt220
root        32     0  0 17:47 ?        00:00:00 bash
root        58    32  0 17:48 ?        00:00:00 ps -fe

請註意,我在這裏使用 - rm 並不是因為它是必要的,而是因為在事實之後我很難清理它。沒有必要讓容器運行。

但看起來他們大多數都會危及容器和主機的安全性

那麽,運行systemd確實需要超出授予典型Docker容器的權限(因此 - cap-add )。這是否對你的環境有安全影響取決於你在做什麽。

根據此博客,通過構建以下dockerfile可以在Docker容器內運行systemd

FROM fedora:rawhide
MAINTAINER “Dan Walsh” 
ENV container docker
RUN yum -y update; yum clean all
RUN yum -y install systemd; yum clean all;
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done);
rm -f /lib/systemd/system/multi-user.target.wants/*;
rm -f /etc/systemd/system/*.wants/*;
rm -f /lib/systemd/system/local-fs.target.wants/*;
rm -f /lib/systemd/system/sockets.target.wants/*udev*;
rm -f /lib/systemd/system/sockets.target.wants/*initctl*;
rm -f /lib/systemd/system/basic.target.wants/*;
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ “/sys/fs/cgroup” ]
CMD [“/usr/sbin/init”]

使用這個命令

  docker build -t httpd_rawhide。
</代碼> 

作者指出可以將構建的碼頭圖像用作基礎圖像

  FROM systemd_rawhide
運行yum -y install httpd; yum幹凈一切; systemctl啟用httpd.service
EXPOSE 80
CMD [“/ usr/sbin/init”]
</代碼> 

如果容器運行

  docker run -privileged -ti -v/sys/fs/cgroup:/ sys/fs/cgroup:ro -p 80:80 httpd_rawhide
</代碼> 

systemd將在Docker容器內運行。也可以使用systemd運行多個服務。根據這個博客的創建者,可以在同一個容器中運行mariadb和http。

根據這篇博客和其他文章,我讀到我的結論是,在碼頭集裝箱內運行systemd技術上是可行的,但我建議避免在集裝箱內運行systemd。

首先,如果systemd能夠在容器中運行,那麽這意味著可以像作者一樣運行多項服務。從docker的角度來看,這是不推薦的,因為docker的意圖是水平擴展,即如果http的負載增加,那麽addtional docker鏡像應該啟動。

其次,如果這樣一個系統化的容器將被部署在像泊塢群這樣的編排平臺上。這會工作嗎?我懷疑這是否會奏效。

第三,通過將cgroup安裝在特權容器中運行systemd看起來不太安全。

總之,盡管您表示腳本需要systemd,但要麽重寫代碼,要麽使用別的東西。我認為應該避免在碼頭集裝箱內運行systemd。