Dockerコンテナでsystemctlを使う
こんにちは。RGA(リアルグローブ・オートメーティッド)で主にコンテナ関連の案件を担当している川野です。
少し前にDockerであるサービスの検証を行った際、systemctlが使えないという問題に遭遇しましたので、これについて書いてみたいと思います。
__________________________________
経緯
proftpdというFTPサーバのソフトウェアのインストールの検証を行う際にcentos7イメージでDockerコンテナを使ったところ、systemctlが使えないことを知ったのでまとめました。
結論
systemdは、centos7と最新版のcentosイメージに含まれるが、デフォルトでは有効化されていないということでした。
(systemdはプロセスを管理するためのデーモンみたいなもので、systemctlを使って操作します。なのでsystemdが有効化されていないとsystemctlが使えません)
最近になってコンテナ上でsystemdを使いたい需要が出てきたってことなのでしょうか。
また、コンテナはベースOSと完全に分離していないため、kernelやハードウェアに関係するプロダクトは基本的には使用できないと考えて良いらしいです。
コンテナとVMそれぞれの事象について
やってることとしてはソフトウェアをインストールしてsystemctlを実行しているだけです。
まずRPELリポジトリを有効化し、proftpdをインストールします。(VM、コンテナ共通の手順です)
[root@8cd3e7e34b47 /]# yum install -y epel-release
(省略)
[root@8cd3e7e34b47 /]# yum install -y proftpd
(省略)
コンテナで確認
systemctlを実行してみると権限エラーがでました。
[root@8cd3e7e34b47 ~]# systemctl status proftpd
Failed to get D-Bus connection: Operation not permitted
Unitファイルは一応あります。
[root@8cd3e7e34b47]# cat /usr/lib/systemd/system/proftpd.service
[Unit]
Description = ProFTPD FTP Server
After = network.target nss-lookup.target local-fs.target remote-fs.target
[Service]
Type = forking
PIDFile = /run/proftpd/proftpd.pid
Environment = PROFTPD_OPTIONS=
EnvironmentFile = -/etc/sysconfig/proftpd
ExecStart = /usr/sbin/proftpd $PROFTPD_OPTIONS
ExecReload = /bin/kill -HUP $MAINPID
[Install]
WantedBy = multi-user.target
コマンドからプロセスは起動できます。
[root@8cd3e7e34b47 ~]# proftpd
[root@8cd3e7e34b47 ~]# proftpd --version
ProFTPD Version 1.3.5e
[root@8cd3e7e34b47 ~]# ps auwx | grep proftpd
nobody 101 0.0 0.1 98588 3680 ? Ss 23:56 0:00 proftpd: (accepting connections)
root 111 0.0 0.0 9108 836 pts/1 S+ 23:59 0:00 grep --color=auto proftpd
VMで確認
systemctlコマンド実行できました。
[centos@ip-172-31-38-240]$ systemctl status proftpd
● proftpd.service - ProFTPD FTP Server
Loaded: loaded (/usr/lib/systemd/system/proftpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Unitファイルはコンテナ同様ありました。
コンテナでsystemdを有効化
centos7イメージでsystemdを有効化できる方法が、ドキュメントに記載されていたので、試してみました。
1. ベースイメージを作成
$ cat << EOF > 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"]
EOF
$ docker build --rm -t local/c7-systemd .
[+] Building 3.7s (6/6) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 623B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:7 3.3s
=> [1/2] FROM docker.io/library/centos:7@sha256:9d4bcbbb213dfd745b58be38b13b996ebb5ac315fe75711bd618426a630e0987 0.0s
=> [2/2] 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/system 0.2s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:07085e1e41e6e56d46556b6f63a51a91884509d102ce696a6aed09a5690a1f42 0.0s
=> => naming to docker.io/local/c7-systemd 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
2. コンテナを起動
以下の2つのオプションを追加し、/sbin/initを実行します。
-v /sys/fs/cgroup:/sys/fs/cgroup:ro
プロセスをグループ化したものがcgroupです。
(コメント)今回DockerをmacOSから立ち上げています。cgroupのパスはmacOSにはないですが、このまま実行して動作することを確認しました。
--cap-add=SYS_ADMIN
システム管理者権限で実行できるようにするためのオプションです。
(コメント)この時点であまり検証以外ではこの方法はやるべきではなさそうです。
コンテナはkernel上(macOSで共有されている)で起動されていますが、これらのオプションをみるとDocker環境から逸脱してホストの権限で動かそうとしています。
$ docker run -it -v /sys/fs/cgroup:/sys/fs/cgroup:ro --cap-add SYS_ADMIN local/c7-systemd /sbin/init
systemd 219 running in system mode. (+PAM +AUDIT +SELINUX +IMA -APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 -SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
Detected virtualization docker.
Detected architecture x86-64.
Welcome to CentOS Linux 7 (Core)!
Set hostname to <03e4ac8046ed>.
Initializing machine ID from random generator.
[ OK ] Reached target Local File Systems.
[ OK ] Reached target Paths.
[ OK ] Created slice Root Slice.
[ OK ] Created slice System Slice.
[ OK ] Listening on Journal Socket.
Starting Create Volatile Files and Directories...
[ OK ] Reached target Slices.
[ OK ] Reached target Swap.
[ OK ] Listening on Delayed Shutdown Socket.
Starting Journal Service...
[ OK ] Started Journal Service.
[ OK ] Started Create Volatile Files and Directories.
[ INFO ] Update UTMP about System Boot/Shutdown is not active.
[DEPEND] Dependency failed for Update UTMP about System Runlevel Changes.
[ OK ] Reached target System Initialization.
[ OK ] Started Daily Cleanup of Temporary Directories.
[ OK ] Reached target Timers.
[ OK ] Listening on D-Bus System Message Bus Socket.
[ OK ] Reached target Sockets.
[ OK ] Reached target Basic System.
[ OK ] Reached target Multi-User System.
3. コンテナに接続
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
03e4ac8046ed local/c7-systemd "/sbin/init" 30 seconds ago Up 30 seconds clever_chatelet
$ docker exec -it 03e4ac8046ed /bin/bash
[root@03e4ac8046ed /]# yum install -y epel-release
(省略)
[root@03e4ac8046ed /]# yum install -y proftpd
(省略)
[root@03e4ac8046ed /]# systemctl status proftpd
● proftpd.service - ProFTPD FTP Server
Loaded: loaded (/usr/lib/systemd/system/proftpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
systemdが有効化されてsystemctlコマンドが実行できることを確認できました。
(補足)
/sbin/initコマンドは、systemdとシンボリックリンクになっているので、コンテナ起動時にsystemdを実行することになります。
PID1にsystemdがきてないとうまく有効化されないようです。
[root@03e4ac8046ed /]# ls -l /sbin/init
lrwxrwxrwx 1 root root 22 Nov 13 2020 /sbin/init -> ../lib/systemd/systemd
[root@03e4ac8046ed /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 43072 4868 ? Ss 02:32 0:00 /sbin/init
root 19 0.0 0.1 39076 3236 ? Ss 02:32 0:00 /usr/lib/systemd/systemd-journald
root 21 0.0 0.1 11844 2924 pts/1 Ss 02:33 0:00 /bin/bash
root 127 0.0 0.1 51748 3404 pts/1 R+ 02:44 0:00 ps aux
参考文献
__________________________________
【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。
IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!
お問合せは以下の窓口までお願いいたします。
【お問い合わせ窓口】
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp