DockerコンテナでSystemdを使って複数プロセスを起動する

docker

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

コンニチーーーハ、千葉です。

Dockerコンテナを実行するときに指定できるプロセスは、基本的には1つとなります。

そのため複数プロセスを起動させるためには、別途プロセス管理ツールが必要です。公式ではSupervisorを使って複数プロセスを起動する方法が記載されています。

今回は、SupervisorではなくSystemdを使ってプロセス管理を行ってみました。 例として、sshdとnginxを起動するコンテナを作成します。(sshしたら負け!という議論はここではしません。)

systemdとは?

Fedora 15やCentOS 7、Red Hat Enterprise Linux 7から採用されたされました。systemdの詳細や利用方法については、こちらが分かりやすいのでリンクを貼っておきます。

コンテナイメージの作成

Mac上のboot2dockerでSystemdの利用はできませんでした。EC2上のCentOS7で動作確認しています

systemdを使ったコンテナイメージを作成し、起動してみます。公式のCentOS7のイメージを使います。 CentOS7のデフォルトでは、systemdは利用できません。 有効化するにはDockerコンテナでは不要なsystemd関連の不要ファイルを削除する必要があります。

以下のDockerfileを作成します。systemd関連の不要ファイルの削除、sshdとnginxのインストールと起動設定を行っています。

FROM centos:7
MAINTAINER "chiba" <chiba@example.com>
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/*;\
yum update -y; yum -y install epel-release openssh-clients openssh-server;yum install nginx -y; yum clean all;\
systemctl enable nginx.service sshd.service;
EXPOSE 22 80
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

Dockerfileからコンテナイメージを作成します。

docker build --rm -t chiba/centos7-systemd .

コンテナを起動

コンテナイメージが作成できたので、コンテンを起動します。ホストのcgroupをマウントしているところがポイントですね。

docker run -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro --hostname centos7-systemd --name centos7-systemd chiba/centos7-systemd

接続確認

コンテナのipアドレスを確認します。

docker ps 
docker inspect --format '{{ .NetworkSettings.IPAddress }}' [コンテナID]

sshしてみる

[root@ip-172-32-11-194 docker-systemd]# ssh 172.17.0.3
The authenticity of host '172.17.0.3 (172.17.0.3)' can't be established.
ECDSA key fingerprint is ed:cd:c1:68:b3:8d:ec:f0:eb:d9:a1:ba:40:67:11:1f.
Are you sure you want to continue connecting (yes/no)? ^C

curlしてみる

[root@ip-172-32-11-194 docker-systemd]# curl http://172.17.0.3
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
    <head>
----省略

接続問題無いです!!

プロセスの起動・停止をしてみる

まずは、コンテナに接続

$ docker exec -it [コンテナID] /bin/bash

sshの停止・起動

[root@centos7-systemd /]# ps -ef | grep sshd
root        68     1  0 15:33 ?        00:00:00 /usr/sbin/sshd -D
root        72    24  0 15:33 ?        00:00:00 grep --color=auto sshd
[root@centos7-systemd /]#
[root@centos7-systemd /]# systemctl stop sshd
[root@centos7-systemd /]#
[root@centos7-systemd /]# ps -ef | grep sshd
root        77    24  0 15:33 ?        00:00:00 grep --color=auto sshd
[root@centos7-systemd /]#
[root@centos7-systemd /]# systemctl start sshd
[root@centos7-systemd /]#
[root@centos7-systemd /]# ps -ef | grep sshd
root        81     1  0 15:33 ?        00:00:00 /usr/sbin/sshd -D
root        83    24  0 15:34 ?        00:00:00 grep --color=auto sshd

nginxの停止・起動

[root@centos7-systemd /]# ps -ef | grep nginx
root        22     1  0 15:20 ?        00:00:00 nginx: master process /usr/sbin/nginx
nginx       23    22  0 15:20 ?        00:00:00 nginx: worker process
root        85    24  0 15:34 ?        00:00:00 grep --color=auto nginx
[root@centos7-systemd /]#
[root@centos7-systemd /]# systemctl stop nginx
[root@centos7-systemd /]#
[root@centos7-systemd /]#
[root@centos7-systemd /]# ps -ef | grep nginx
root        92    24  0 15:35 ?        00:00:00 grep --color=auto nginx
[root@centos7-systemd /]#
[root@centos7-systemd /]#
[root@centos7-systemd /]# systemctl start nginx
[root@centos7-systemd /]#
[root@centos7-systemd /]# ps -ef | grep nginx
root        99     1  0 15:35 ?        00:00:00 nginx: master process /usr/sbin/nginx
nginx      100    99  0 15:35 ?        00:00:00 nginx: worker process
root       102    24  0 15:35 ?        00:00:00 grep --color=auto nginx

停止・起動についても問題なさそうです!

まとめ

Dockerコンテナで、Systemdを利用したプロセス管理が可能でした。次は、Supervisorを使って起動・停止も行ってみたいと思います!

参考