Dockerコンテナで複数のサービスを動かすポイントを解説しましたが、今回はその応用編として具体的に3つの方法をご紹介します。
コンテナで複数のサービスをで起動させるにはどうすればよいのでしょうか。前回は基本的な注意点などを解説しましたが、今回は比較的簡単な方法を3つご紹介します。
まず、コミュニティの間では「そもそもDockerコンテナで同時に稼働させるアプリケーションの数を幾つにすべきか」という議論があります。1つのコンテナに1つのアプリケーションを稼働させるようにすれば、複数のコンテナが連携して稼働する場合でも、コンテナを組み合わせて汎用的に使える割合が高くなります。だからといって、稼働するアプリケーションが多いシステムでは、1コンテナ・1アプリケーションのポリシーを厳密に適用してしまうと、コンテナの数が膨大になることが予想されます。
現実的に考えると、1つのコンテナにおいても、多少の汎用性を犠牲にしても複数のアプリケーションを稼働させるといった運用が十分に考えられます。この場合、1つのコンテナで複数のサービスを同時稼働させる仕組みが必要です。例えば、1つのコンテナでWebサービスとFTPサービスを同時に提供するような場合、httpdデーモンとvsftpdデーモンの2つを起動させる必要があります。
それではWebサービスとFTPサービスを同時に稼働させる場合、どのようなDockerfileになるのでしょうか。以下の例を見てください。
# mkdir /root/apache_ftp # cd /root/apache_ftp # vi Dockerfile FROM centos:centos7.2.1511 MAINTAINER Masazumi Koga ENV container docker ENV http_proxy http://proxy.yoursite.com:8080 ENV https_proxy http://proxy.yoursite.com:8080 RUN yum update -y && yum clean all RUN yum install -y iproute httpd vsftpd && yum clean all RUN echo "Hello Apache." > /var/www/html/test1.html RUN echo "Hello Vsftpd." > /var/ftp/pub/test2.txt COPY myapp.sh /usr/local/bin RUN chmod 755 /usr/local/bin/myapp.sh EXPOSE 80 ENTRYPOINT ["/usr/local/bin/myapp.sh"]
このDockerfileには、httpdデーモンとvsftpdデーモンの2つをインストールしています。今回、httpdによって提供するWebコンテンツは「/var/www/html/test1.html」、vsftpdによって提供するファイルは「/var/ftp/pub/test2.txt」としました。しかしDockerfileを見渡しても、httpdデーモンとvsftpdデーモンを直接起動する処理がありません。その代わりENTRYPOINTには、なにやらmyapp.shという謎のスクリプトが指定されています。myapp.shスクリプトは一体何者なのでしょうか。このmyapp.shは、httpdデーモンとvsftpdデーモンを稼働させるスクリプトです。今回はmyapp.shを以下のように作成しました。
# cat myapp.sh #!/bin/sh /usr/sbin/httpd -k start ←httpdデーモンを起動 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf ←vsftpdデーモンを起動 tail -f /dev/null ←永久に終わらないtailコマンド
myapp.shスクリプト内において、httpdデーモンとvsftpdデーモンはバックグラウンドで起動するように記述されています。しかし、バックグラウンドで起動したプロセスのみでは、コンテナがすぐに終了してしまうため、コンテナを稼働し続ける仕組みを提供する「tail -f /dev/null」が組み込まれています。このtailコマンドの活用は連載の第9回でも紹介しましたが、プロセスがすぐに終了するようなコマンドだけではなく、バックグラウンドで稼働するデーモンが複数存在する場合にも有用です。実際にDockerfileが存在するディレクトリにmyapp.shスクリプトを用意し、Dockerイメージのビルドおよびコンテナの起動を行ってみてください。
# docker build -f ./Dockerfile -t centos:c7apache02 --no-cache=false . # docker run -itd --name web0002 centos:c7apache02
起動したコンテナにおいて稼働しているプロセスをホストOSから確認してみます。
# docker exec -it web0002 ps -ef UID PID PPID C STIME TTY TIME CMD root 1 0 0 12:09 ? 00:00:00 /bin/sh /usr/local/bin/myapp.sh root 7 1 0 12:10 ? 00:00:00 /usr/sbin/httpd -k start apache 9 7 0 12:10 ? 00:00:00 /usr/sbin/httpd -k start apache 10 7 0 12:10 ? 00:00:00 /usr/sbin/httpd -k start apache 11 7 0 12:10 ? 00:00:00 /usr/sbin/httpd -k start apache 12 7 0 12:10 ? 00:00:00 /usr/sbin/httpd -k start apache 13 7 0 12:10 ? 00:00:00 /usr/sbin/httpd -k start root 14 1 0 12:10 ? 00:00:00 /usr/sbin/vsftpd /etc/vsftpd/vsftpd.conf root 15 1 0 12:10 ? 00:00:00 tail -f /dev/null root 20 0 0 12:14 ? 00:00:00 ps -ef
コンテナ内で実行されたmyapp.shスクリプトにおいて、永久に処理が終わらないtailコマンドが組み込まれていることにより、myapp.sh内で起動したhttpd、vsftpdが稼働し続けていることが分かります。しかしこの場合は、起動したいサービス以外にmyapp.shのようなカスタムの起動スクリプトを別途作成しなければなりません。この例のmyapp.shは非常に単純ですが、稼働させるアプリケーションが多岐にわたる場合や、挙動を変えるための起動オプションの変更などを細かく定義する必要がある場合は、それらを正確に処理できるmyapp.shスクリプトを用意しなければならず、アプリケーション以外にスクリプトもメンテナンスしなければなりません。
サービスを起動・停止させるためのスクリプトは、一般的に「ラッパースクリプト」と呼ばれますが、このラッパースクリプトはDockerの世界だけではなく、古くから高可用性クラスタ環境におけるサービスの起動・停止にも使われています。しかし、ラッパースクリプト自体が肥大化し、複雑になることが多く、バイナリのオプションの仕様変更やラッパースクリプトの改変の度に十分なテストを行う必要があります。
Copyright © ITmedia, Inc. All Rights Reserved.