はじめに
CentOSのコンテナはデフォルトだとSystemdは使えませんが、
DockerHubのページでSystemdをアクティブにする方法が記載されているので試してみました。
実行環境
OS:MacOS Monterey 12.4
Docker:Docker version 20.10.14
Docker Desktop for Mac:version 4.7.1
Docker Image:CentOS 7
CentOS7のDockerイメージを取得
% docker pull centos:7
Systemdベースのイメージを作成
Dockerfileを作成
DockerHubのページにサンプルが記載されているので、参考にDockerfileを作成します。
% vim ~/workspace/docker/centos/systemd-base/Dockerfile
FROM centos:7
ENV container docker
RUN (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"]
イメージをビルドする
Dockerfileを元にイメージをビルドします。
% docker build --rm -t centos-systemd ~/workspace/docker/centos/systemd-base/
[+] Building 0.1s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.1s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 0.0s
=> [1/2] FROM docker.io/library/centos:7 0.0s
=> CACHED [2/2] RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:ddbe5f1f9b13355b0558d857948f089860b0e4393ec6a40b9 0.0s
=> => naming to docker.io/library/centos-systemd 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
ビルド後、dockerコマンドでイメージを一覧すると確認できます。
% docker images -a
REPOSITORY TAG IMAGE ID CREATED SIZE
centos-systemd latest ddbe5f1f9b13 2 days ago 204MB
centos 7 eeb6ee3f44bd 8 months ago 204MB
コンテナを起動
失敗1
DockerHubのページを参考に以下のコマンドでコンテナを起動します。
% docker run --name centos-systemd-container -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -d centos-systemd
f27733e900c6cc99ed9aa3e046c72773cf87cef580b8b8c27d5610d39b35e4f6
起動したコンテナでSystemdを使用できるか確認してみます。
sh-4.2# systemctl list-units --type=service
Failed to get D-Bus connection: Operation not permitted
権限がなくてD-Bus接続の取得に失敗したようです。
dockerドキュメントで権限に関して調べてみると、
Dockerコンテナはデフォルトだと権限が無く、デバイスに対して接続できない状態にあるため、特権コンテナにする必要があるようです。
そのため「privileged」オプションを付与して特権コンテナとして立ち上げてみます。
失敗2
% docker run --name centos-systemd-container --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -d centos-systemd
e3de98766ea9b4a181eb9fde99040c0093514e25bb0e72f55bd412717b2e8422
sh-4.2# systemctl list-units --type=service
Failed to get D-Bus connection: No such file or directory
今度はファイル・ディレクトリが見つからないものがあったらしく失敗しました。
メッセージで検索をかけていると、こちらにたどり着きました。
DockerDesktopがcgroupv2を使用するようになったため、systemdもcgroupv2をサポートしている必要があり、少なくともsystemd247以上のバージョンが必要みたいです。
自身の環境を確認してみます。
sh-4.2# journalctl --version
systemd 219
+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN
バージョンが足りていませんでした。
同ページによるとDockerDesktopにcgroupv1を使用させるパラメータがあるようなので設定してみます。
設定ファイルは~/Library/Group Containers/group.com.docker/settings.jsonです。
"deprecatedCgroupv1": true, // trueに変更します
settings.jsonを変更したら再起動してもう一度試してみます。
成功
sh-4.2# systemctl list-units --type=service
UNIT LOAD ACTIVE SUB DESCRIPTION
systemd-journald.service loaded active running Journal Service
systemd-tmpfiles-setup.service loaded active exited Create Volatile Files and D
ir
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
2 loaded units listed. Pass --all to see loaded but inactive units, too
.
To show all installed unit files use 'systemctl list-unit-files'.
無事、systemctlコマンドが反応してくれるようになりました。
参考文献