Dockerはコンテナの起動時に、initプロセスではなく、CMDで指定したプロセスから実行されるため、通常は1つしかプロセスを起動できない制約があります。しかし、プロセス管理ツールのsupervisorを使用すれば、コンテナ内で複数のプロセスを起動することができます。
前回、Dockerfileを使ってsupervisorからsshdとMySQLのプロセスを起動させることを確認できました。そこで、Chefを使ってsupervisorに起動プロセスの定義を追加することで、コンテナ内の起動プロセスを追加できないか試してみました。
Dockerfileの作成
Dockerfileの構成は以下の通りです。
sshd ├──Dockerfile ├──sources.list ... ミラーサイト一覧 ├──id_rsa.pub ... Chef workstationの公開鍵 └──supervisord.conf ... supervisorの定義ファイル
Dockerfileを以下のように作成します。
後でMySQLを起動できるように、「RUN dpkg-divert~」を設定しています。
supervisorの定義ファイルは、/etc/supervisor/conf.d/配下にも置くことができるので、「RUN mkdir -p /etc/supervisor/conf.d/」でディレクトリを作成しています。
$ vi Dockerfile FROM ubuntu:12.04 MAINTAINER hidemium # Ubuntu update ADD sources.list /etc/apt/sources.list RUN apt-get -y update # Hack for initctl not being available in Ubuntu RUN dpkg-divert --local --rename --add /sbin/initctl RUN ln -sf /bin/true /sbin/initctl # ssh install RUN apt-get -y install openssh-server RUN apt-get -y install python-setuptools RUN apt-get clean RUN easy_install supervisor RUN mkdir /var/run/sshd RUN echo 'root:root' | chpasswd # sshd config ADD id_rsa.pub /root/id_rsa.pub RUN mkdir /root/.ssh/ RUN mv /root/id_rsa.pub /root/.ssh/authorized_keys RUN chmod 700 /root/.ssh RUN chmod 600 /root/.ssh/authorized_keys RUN sed -i -e '/^UsePAM\s\+yes/d' /etc/ssh/sshd_config # supervisor config RUN mkdir -p /var/log/supervisor RUN mkdir -p /etc/supervisor/conf.d/ ADD supervisord.conf /etc/supervisord.conf # Expose ports. EXPOSE 22 # Define default command. CMD ["supervisord", "-n"]
supervisorの定義ファイルは、デフォルトの定義にsshdの起動を追加したものにしています。
$ vi supervisord.conf [unix_http_server] file=/tmp/supervisor.sock ; (the path to the socket file) [supervisord] logfile=/tmp/supervisord.log ; (main log file;default $CWD/supervisord.log) logfile_maxbytes=50MB ; (max main logfile bytes b4 rotation;default 50MB) logfile_backups=10 ; (num of main logfile rotation backups;default 10) loglevel=info ; (log level;default info; others: debug,warn,trace) pidfile=/tmp/supervisord.pid ; (supervisord pidfile;default supervisord.pid) nodaemon=false ; (start in foreground if true;default false) minfds=1024 ; (min. avail startup file descriptors;default 1024) minprocs=200 ; (min. avail process descriptors;default 200) [rpcinterface:supervisor] supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface [supervisorctl] serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket [include] files = /etc/supervisor/conf.d/*.conf [program:sshd] command=/usr/sbin/sshd -D autostart=true autorestart=true
Chefレシピの作成例
それでは、Chef側について見ていきます。
今回、apache2とMySQLについて試してみました。
apache2
cookbookの構成は以下の通りです。
site-cookbook └──apache2 └──recipes │ └──default.rb └──templates └──default └──apache2.conf.erb ... supervisorの定義ファイル
recipesファイル(抜粋)は以下の通りです。
Chef側では、templateファイルとしてsupervisorの定義ファイルを用意します。
定義ファイルを配置後、supervisorctl reloadコマンドによりプロセスを起動します。
プログラムによっては、supervisorctl <サービス名> startコマンドでも起動できない場合があるため、supervisorctl reloadコマンドでsupervisorに定義されたプロセスをすべて再読み込みさせています。
ChefはSSH接続で実行していますが、supervisorの再読み込みでSSHが切断されることはありませんでした。
$ vi site-cookbooks/apache2/recipes/default.rb : package "apache2" do action :install end template "apache2.conf" do path "/etc/supervisor/conf.d/apache2.conf" owner "root" group "root" mode "0644" source "apache2.conf.erb" end bash "supervisorctl reload" do code "supervisorctl reload" action :run end :
templateファイルは以下の通りです。
$ vi site-cookbooks/apache2/templates/default/apache2.conf.erb [program:apache2] command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
MySQL
cookbookの構成は以下の通りです。
site-cookbook └──mysql └──recipes │ └──default.rb └──templates └──default └──mysqld.conf.erb ... supervisorの定義ファイル
MySQLを追加する場合のrecipesファイル(抜粋)は以下の通りです。
上記と同じ構成となっています。
supervisorctl reloadコマンド後に、sleepを入れいるのは、mysqldの起動に時間がかかるため、mysqlコマンドを実行しても接続できないためです。
$ vi site-cookbooks/mysql/recipes/default.rb : package "mysql-server" do action :install end template "mysqld.conf" do path "/etc/supervisor/conf.d/mysqld.conf" owner "root" group "root" mode "0644" source "mysqld.conf.erb" end bash "supervisorctl reload" do code "supervisorctl reload; sleep 3" action :run end :
templateファイルは以下の通りです。
$ vi site-cookbooks/mysql/templates/default/mysqld.conf.erb [program:mysqld] command=/usr/bin/mysqld_safe