CFEngine でプロセス管理

プロセスを管理する Docker コンテナを作成します。

Docker は各実行中のコンテナで1つのプロセスを監視します。そして、コンテナの生死とは、そのプロセスの生死を指します。Docker コンテナ内での CFEngine の動かし方を紹介します。これは、次の問題を軽減するものです。

  • 1つのコンテナの中で、複数のコンテナを簡単に起動できるかもしれません。通常の docker run コマンドを実行するだけで、全てを自動的に管理します。
  • 停止またはクラッシュしたプロセスを管理し、1分以内に CFEngine が対象プロセスを再起動します。
  • CFEngine スケジューリング・デーモン(cf-execd)が動いている限り、コンテナ自身も動かし続けます。CFEngine によって、コンテナの生存をサービスの状況と切り離せるようになります。

どのように動作するのか

CFEngine は、cfe-docker 統合ポリシー(integration policies)と一緒に Dockerfile の中でインストールします。Docker イメージの中で CFEngine が構築されています。

Dockerfile の ENTRYPOINT には任意のコマンド(と任意の引数)をパラメータとして指定できます。Docker コンテナが CFEngine ポリシーの書かれたパラメータを受け取り実行する時、CFEngine はコンテナ内で任意のプロセスが間違いなく実行されるようにします。

CFEngine は ENTRYPOINT で指定したコマンドの ベースネーム (最終的に実行するコマンドの名前)にあたるプロセス・テーブルをスキャンし、 ベースネーム のプロセスが見つからなければ、それを開始しようとします。例えば、コンテナを docker run "/path/to/my/application パラメータ" で開始したら、CFEngine は application という名前のプロセスを探し、コマンドを実行します。もし application にあたるエントリがプロセス・テーブルに無ければ、 CFEngine は /path/to/my/application parameters でアプリケーションを再度起動しようとします。このプロセス・テーブルの確認は、毎分実行されます。

従って重要になるのは、アプリケーションを開始するにあたり、そのプロセスにベースネームが含まれている必要があるため、ご注意ください。

使い方

この例は、Docker をインストール済みであり、動くものと想定しています。これから1つのコンテナの中に apache2sshd をインストール・管理します。

3つの手順を踏みます:

  1. コンテナの中に CFEngine をインストールします。
  2. CFEngine の Docker プロセス管理ポリシーを、CFEngine をインストールしたコンテナにコピーします。
  3. docker run コマンドの一部として、アプリケーション・プロセスを開始します。

イメージの構築

以下のように、Dockerfile の1~2ステップで設定できます。

FROM ubuntu
MAINTAINER Eystein Måløy Stenberg <eytein.stenberg@gmail.com>

RUN apt-get update && apt-get install -y wget lsb-release unzip ca-certificates

# install latest CFEngine
RUN wget -qO- http://cfengine.com/pub/gpg.key | apt-key add -
RUN echo "deb http://cfengine.com/pub/apt $(lsb_release -cs) main" > /etc/apt/sources.list.d/cfengine-community.list
RUN apt-get update && apt-get install -y cfengine-community

# install cfe-docker process management policy
RUN wget https://github.com/estenberg/cfe-docker/archive/master.zip -P /tmp/ && unzip /tmp/master.zip -d /tmp/
RUN cp /tmp/cfe-docker-master/cfengine/bin/* /var/cfengine/bin/
RUN cp /tmp/cfe-docker-master/cfengine/inputs/* /var/cfengine/inputs/
RUN rm -rf /tmp/cfe-docker-master /tmp/master.zip

# apache2 and openssh are just for testing purposes, install your own apps here
RUN apt-get update && apt-get install -y openssh-server apache2
RUN mkdir -p /var/run/sshd
RUN echo "root:password" | chpasswd  # need a password for ssh

ENTRYPOINT ["/var/cfengine/bin/docker_processes_run.sh"]

作業ディレクトリでこのファイルを Dockerfile として保存します。イメージを構築するには docker build コマンドを使います。例: docker build -t managed_image

コンテナのテスト

apache2sshd を実行するコンテナを開始し、 SSH インスタンスのポート転送を管理します。

$ docker run -p 127.0.0.1:222:22 -d managed_image "/usr/sbin/sshd" "/etc/init.d/apache2 start"

これが、まさに cfe-docker 統合における明確な利点です。通常の docker run コマンドの一部として、複数のプロセスを開始します。

新しいコンテナ内にログインしたら、 apache2sshd の両方が動作しています。先ほどの Dockerfile で root パスワードを "password" と指定しましたので、これを使って SSH でログインします。

ssh -p222 root@127.0.0.1

ps -ef
UID        PID  PPID  C STIME TTY          TIME CMD
root         1     0  0 07:48 ?        00:00:00 /bin/bash /var/cfengine/bin/docker_processes_run.sh /usr/sbin/sshd /etc/init.d/apache2 start
root        18     1  0 07:48 ?        00:00:00 /var/cfengine/bin/cf-execd -F
root        20     1  0 07:48 ?        00:00:00 /usr/sbin/sshd
root        32     1  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
www-data    34    32  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
www-data    35    32  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
www-data    36    32  0 07:48 ?        00:00:00 /usr/sbin/apache2 -k start
root        93    20  0 07:48 ?        00:00:00 sshd: root@pts/0
root       105    93  0 07:48 pts/0    00:00:00 -bash
root       112   105  0 07:49 pts/0    00:00:00 ps -ef

もし apache2 を停止しても、CFEngine が1分以内に再起動します。

service apache2 status
 Apache2 is running (pid 32).
service apache2 stop
         * Stopping web server apache2 ... waiting    [ OK ]
service apache2 status
 Apache2 is NOT running.
# ... wait up to 1 minute...
service apache2 status
 Apache2 is running (pid 173).

自分のアプリケーションに適用

自分のアプリケーションでも同じように設定できます。上記の例で調整が必要なのは、2ヵ所だけです。

  • 上記の Dockerfile を使い、 apache2sshd のかわりに自分のアプリケーションをインストールします。
  • docker run でコンテナを起動に、 apache2sshd ではなく、自分のアプリケーション用のコマンドライン引数を指定します。