見出し画像

Dockerコンテナでsystemctlを使う

こんにちは。RGA(リアルグローブ・オートメーティッド)で主にコンテナ関連の案件を担当している川野です。

少し前にDockerであるサービスの検証を行った際、systemctlが使えないという問題に遭遇しましたので、これについて書いてみたいと思います。

__________________________________

経緯

proftpdというFTPサーバのソフトウェアのインストールの検証を行う際にcentos7イメージでDockerコンテナを使ったところ、systemctlが使えないことを知ったのでまとめました。

結論

systemdは、centos7と最新版のcentosイメージに含まれるが、デフォルトでは有効化されていないということでした。
(systemdはプロセスを管理するためのデーモンみたいなもので、systemctlを使って操作します。なのでsystemdが有効化されていないとsystemctlが使えません)

Systemd is now included in both the centos:7 and centos:latest base containers, but it is not active by default.
https://hub.docker.com/_/centos?tab=description

最近になってコンテナ上で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

参考文献

__________________________________

執筆者プロフィール:川野 孝
ゲーム事業の自社開発企業で3年間SREとして、GCP/AWS上のインフラストラクチャのTerraform/Ansibleを使った運用改善やGKEを使ったKubernetesアーキテクチャの構築、スクラム開発などを経験。
RGAではそれらの経験を生かし、OpenShiftやCI/CD設計構築、スクラムの導入などの関連する業務に従事。

【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。

IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!

お問合せは以下の窓口までお願いいたします。

【お問い合わせ窓口】
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp