それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

docker で systemdが動く ubuntu イメージを作って遊ぶ-その2

前回、systemd を動かした。

前回の続き

docker の起動コマンドを /sbin/init にすれば、 docker の ubuntu でも systemdを使って遊べることがわかった。

単純な作業だったので、dockerfile でイメージ化して遊ぶ

dockerfileを作って遊ぶ

FROM ubuntu:20.04
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends init

ENTRYPOINT ["/sbin/init"]

ビルド

dockerfileをビルドしてイメージにする。

docker image build -f Dockerfile -t ubuntu-systemd .

イメージを起動

コンテナは特権コンテナのほうが楽だけど、他に同じようなことをやってるひとを github見つけた。 その人の使ってるセキュリティ起動オプションを使う。

docker run -d   \
  --security-opt seccomp=unconfined \
  --tmpfs /tmp \
  --tmpfs /run \
  --tmpfs /run/lock \
  -v /sys/fs/cgroup:/sys/fs/cgroup:ro \
  -t ubuntu-systemd:latest

無事に起動することがわかる。

確認

nginx をインストールして systemd 経由でちゃんと起動するか確かめてみる。

docker exec -it 56e -- apt-get install nginx  --no-install-recommends
docker exec -it 56e systemctl status nginx
docker restart 56e systemctl status nginx
docker exec -it 56e systemctl status nginx

nginx が再起動後に起動することがわかる。

takuya@ubuntu:~/ubuntu-systemd$ docker exec -it 56e systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: inactive (dead)
       Docs: man:nginx(8)
takuya@ubuntu:~/ubuntu-systemd$ docker exec -it 56e systemctl start nginx
takuya@ubuntu:~/ubuntu-systemd$ docker exec -it 56e systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Tue 2021-05-25 17:16:51 JST; 1s ago
       Docs: man:nginx(8)
    Process: 611 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
    Process: 612 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
   Main PID: 613 (nginx)
      Tasks: 5 (limit: 1388)
     CGroup: /system.slice/snap.docker.dockerd.service/system.slice/nginx.service
             ├─613 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             ├─614 nginx: worker process
             ├─615 nginx: worker process
             ├─616 nginx: worker process
             └─617 nginx: worker process

May 25 17:16:51 56e5331be46b systemd[1]: Starting A high performance web server and a reverse proxy server...
May 25 17:16:51 56e5331be46b systemd[1]: Started A high performance web server and a reverse proxy server.
takuya@ubuntu:~/ubuntu-systemd$

まとめ

/sbin/init もちょっとしたことで動くんだね。

でも公式でやってないということは・・・

遊べることがわかったけど、公式でやってないということは。何らかの問題があるのでサポートしてないんだろう。

また、先人がやってないということは、この手法を突き詰めることは徒労に終わる可能性が高いので、遊ぶのはここまで。

systemd は本当に多機能なので、直接使うと無駄が多いとか、そういう理由で supervisord を使ったりするかも。

docker の設計思想がシングルプロセスなのでdocker-composeを使うんですよ。きっと

例えば systemd-multiuser.target

マルチユースなマルチユーザーを前提にした multiuser や logind はいらないよね。

そう考えるとやっぱり無駄が多そう。

例えばシャットダウン

シャットダウンはできない。

root@db1ccf6f38c6:/# ps auxf
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         678  1.0  0.0   4108  2540 pts/1    Ss   18:30   0:00 bash
root         686  0.0  0.0   5896  2140 pts/1    R+   18:30   0:00  \_ ps auxf
root           1  0.5  0.0  16308  5020 ?        Ss   18:27   0:01 /lib/systemd/systemd-shutdown reboot --timeout 90000000us --log-level 6 --log-target kmsg --log-color

シャットダウンできるわけでもない。

次のようなsystemctl が使いたいだけにはヘビィすぎる。

systemctl restart nginx 

systemd は本当に巨大なので、必要な部分だけ取り出して使おうとすると、ちょっとめんどくさいですよね。

追記 Windows Dockerで動かした場合

WSL2のWindowsなDockerで動かした場合、特権なしで動きました。

もしかして世間にあふれるブログ情報でsystemd / init を動かしたと書かれていたらWindowsでの話かもしれません。

WindowsのDocker (WSL2・Hyper-V)で動かした場合に特権なしで動いている例。 特権なしの代わりに sys_admin のCapabilityをADDしています。

参考資料

GitHub - bdellegrazie/docker-ubuntu-systemd: systemd-enabled versions of Docker base images

https://stackoverflow.com/questions/39169403/not-able-to-use-systemd-on-ubuntu-docker-container

dockerで systemd が動く ubuntu を作って遊ぶ - それマグで!