これまではSerfの基本的な使い方や、
Dockerコンテナ群をSerfで管理する方法
DockerはLinuxコンテナを簡単に起動・Dockerfile
と言う設定ファイルを使った構成管理の自動化などの利点があります。
コンテナ管理問題を解決するSerf
コンテナを多く立ちあげた時に発生するのは、docker exec
コマンドを実行することにより、
docker exec
は、docker exec
を実行するのは手間になりがちです。また、
この問題を解決するために、
そこで登場するのが、
- メンバー管理の自動化
Serfがコンテナのホスト名とIPアドレスを自動的に管理するため、
コンテナの起動・ 停止時に人手で管理する必要がありません。 - タグ機能でコンテナの役割を明確化
Serfはエージェントにタグを動的に付与でき、
コンテナの役割や管理担当者の情報を動的に付与できます。 - イベントハンドラでコンテナ内の一斉操作
コンテナにログインすることなく任意のコマンドを一斉に実行できます。開発環境やテスト環境を問わず、
有用な機能です。
いずれも手動でも行えますが、
図1は1つのホスト上で複数のコンテナを管理するイメージです。この図ではホストOS側・172.
で固定されているため、172.
にしておくと便利です。
![図1 SerfでLinuxコンテナを一括管理 図1 SerfでLinuxコンテナを一括管理](/assets/images/admin/feature/01/serf-consul/0003/thumb/TH800_001.jpg)
自動的にSerfクラスタを構成するDockerfile
Dockerでコンテナを起動・bash
を実行させてみます。
前提として、serf agent
等のコマンドで起動しているものとします。この時、172.
をバインドしている必要がありますserf agent -bind=172.
として明示することもできます)。
自動的にSerfを起動するためにはDockerfile
を用います。Dockerには、Dockerfile
という名称のテキスト形式のファイルを作成し、
作業用のディレクトリを作成し、Dockerfile
を作成します。内容はcentos
のコンテナイメージの使用を明示し、wget
とunzip
パッケージの取得を行っています。それからserfのアーカイブを取得・
FROM centos
RUN yum -y install wget unzip
RUN wget -O 0.6.4_linux_amd64.zip https://dl.bintray.com/mitchellh/serf/0.6.4_linux_amd64.zip
RUN unzip 0.6.4_linux_amd64.zip
RUN cp ./serf /usr/bin/serf
ENTRYPOINT ["serf"]
CMD ["agent","-join=172.17.42.1","-event-handler=query:ssh=/bin/sh"]
※ 実際のDockerfileは、
次に、Dockerfile
を元にdocker build
コマンドを使い、serf-centos
というタグを付けていますが、<ユーザ名>/serf-centos
など、
# docker build -t serf-centos . Sending build context to Docker daemon 3.31 MB Sending build context to Docker daemon Step 0 : FROM centos ---> 9dbcac75201e Step 1 : RUN yum -y install wget unzip ---> Using cache ---> 7d35b2710d1d Step 2 : RUN wget -O 0.6.4_linux_amd64.zip https://dl.bintray.com/mitchellh/serf/0.6.4_linux_amd64.zip ---> Using cache ---> 6f943b9c59cd (省略) Successfully built 5aa497793ab2
画面上にSuccessfully
と表示されれば、serf-centos
という名称のコンテナイメージが作成できました。次は、docker run
コマンドを使い、
# docker run -d serf-centos 175dbd9034122edff3af72804c1a8cc8e968ebed5d53c25259e375f82b4b40f4
コンテナが正常に稼働しているかどうかは、docker ps
コマンドで確認することができます。ここでは自動的にSerfクラスタを形成しているか確認するためにserf members
コマンドを実行してみます。正常であれば、
# serf members dev2.pocketstudio.net 172.17.42.1:7946 alive 3f42611e8fe7 172.17.0.10:7946 alive
同時に複数台の起動も試してみましょう。先ほど同様docker run -d serf-centos
を数回実行した後、serf members
コマンドを実行します。次のように、
# serf members dev2.pocketstudio.net 172.17.42.1:7946 alive 3f42611e8fe7 172.17.0.10:7946 alive 0f8a23cdc921 172.17.0.11:7946 alive 4bbedca26a70 172.17.0.14:7946 alive 175dbd903412 172.17.0.15:7946 alive
コンテナ内をserf queryを使って同時操作
Serfのイベントハンドラssh
を使い、serf query
コマンドを使用します。任意のコマンドを実行するにはserf event
またはserf query
を使う方法がありますが、query
形式を定義していました。結果を知る必要がなければevent
形式でも構いません。
例として、serf ssh uptime
を実行してみます。正常に処理されると、uptime
が実行され、ssh
が発生すると、/bin/
と引数としてのコマンドを実行した結果が表示されます。
# serf query ssh uptime Query 'ssh' dispatched Ack from 'dev2.pocketstudio.net' Ack from '0f8a23cdc921' Response from '0f8a23cdc921': 09:11:04 up 2:23, 0 users, load average: 0.17, 0.06, 0.02 Ack from '4bbedca26a70' Response from '4bbedca26a70': 09:11:04 up 2:23, 0 users, load average: 0.17, 0.06, 0.02 Total Acks: 3 Total Responses: 2
ほかにもps
コマンドでプロセスの状況を知ることもできます。
# serf query ssh "ps ax" Query 'ssh' dispatched Ack from 'dev2.pocketstudio.net' Ack from '4bbedca26a70' Response from '4bbedca26a70': PID TTY STAT TIME COMMAND 1 ? Ssl 0:01 serf agent -join=172.17.42.1 -event-handler=query:sh=/bin/sh 19 ? S 0:00 /bin/sh 20 ? R 0:00 ps ax Ack from '175dbd903412' Response from '175dbd903412': PID TTY STAT TIME COMMAND 1 ? Ssl 0:00 serf agent -join=172.17.42.1 -event-handler=query:sh=/bin/sh 16 ? S 0:00 /bin/sh 17 ? R 0:00 ps ax Total Acks: 5
これはあくまで一例ですので、cat
やyum
コマンドだけでなく、/bin/
を指定しました。しかしroot権限で何でも実行できてしまうため、
メンバー管理とタグ
Serfはエージェントのメンバー毎にタグを付ける機能があります。コンテナを複数起動している場合、serf members
コマンドで参照できるだけではなく、
タグを指定するにはserf tags -set <key>=<value>
の形式でコマンドを実行します。コマンドの実行は、role=admin
というタグを設定し、serf members
コマンドで見た結果です。
$ serf tags -set role=admin Successfully updated agent tags $ serf members dev2.pocketstudio.net 172.17.42.1:7946 alive role=admin 3f42611e8fe7 172.17.0.10:7946 alive 0f8a23cdc921 172.17.0.11:7946 alive
タグの削除はserf tag -delete <key>
の形式で指定します。また、
Serfの詳細設定
Serfエージェントの様々な設定は、serf
コマンドの引数で指定する方法と、
外部の設定ファイルを使う方法
Serfを同じ設定で起動・
{
"node_name": "dev01", # ノード名称を「dev01」
"tags": {
"role": "develop" # タグ「role=develop」
},
"interface": "eth1", # インターフェースを「eth1」
"discover": "serf-cluster", # オート・ディスカバリで「serf-cluster」を検索
"event_handlers": [
"ssh=/bin/bash" # イベントハンドラ「ssh=/bin/bash」を定義
]
}
このJSON形式のファイルを作成した後、-config-file=
オプションを指定します。
$ serf agent -confg-file=/etc/serf.json
JSON形式の場合は、kill -1 <serfのPID>
を実行します。
Serfの便利オプション
Serfには様々なオプションが用意されています。ここでは、
node_
name (-node) Serfクラスタ内の自分のノード名称を指定するもので、
serf members
コマンド実行時に表示されます。省略時は自分自身のホスト名が利用されます。なお、Serfクラスタ内でノード名称の重複はできないため、 設定ファイルをコピーして流用する時は注意が必要です。 - 設定ファイル:"node_
name": "dev01" - コマンドライン:serf agent -node=dev01
- 設定ファイル:"node_
bind
(-bind) Serfエージェントが内部の通信で利用するIPアドレスを指定します。通常は指定する必要はありませんが、
サーバが複数のインターフェースを持っている場合、 どのIPアドレスを使うか明示するために使います。 - 設定ファイル:"bind": "192.
168. 39. 3" - コマンドライン:serf agent -bind=192.
168. 39. 3
- 設定ファイル:"bind": "192.
interface
(-iface) Serfが利用する標準インターフェース名を指定します。複数のインターフェースを持っている環境で多用します。
- 設定ファイル:"interface": "eth1"
- コマンドライン:serf agent -iface=eth1
badvertise
(-advertise) Serfクラスタ内の自分のIPアドレスを指定します。
bind
の指定に似ていますが、こちらはインターフェースが複数のIPアドレスを持っている場合や、 NATの環境で明示したい時に使います。 - 設定ファイル:"advertise": "192.
168. 39. 1" - コマンドライン:serf agent -advertise=192.
168. 39. 1
- 設定ファイル:"advertise": "192.
discover
(-discover) マルチキャストDNS
(mDNS) がネットワーク内で利用可能な場合にオプションを指定すると、 serf join
で参加するクラスタを明示しなくても自動的にクラスタを形成します。この引数として指定したクラスタ名と一致する場合に自動参加します。- 設定ファイル:"discover": "development"
- コマンドライン:serf agent -discover=development
encrypt_
key (-encrypt) Serfで暗号化したネットワーク通信を行う場合に使う秘密鍵を指定します。予め
serf keygen
コマンドで生成した文字列を引数として使います。暗号化してクラスタを形成すると、ここで指定した鍵が一致しないとクラスタに参加できません。 - 設定ファイル:"encrypt_
key": "<文字列>" - コマンドライン:serf agent -encrypt=<文字列>
- 設定ファイル:"encrypt_
log_
level (-log-level) Serfエージェント起動後に標準出力されるログの粒度を指定します。種類には情報が多い順にtrace、
debug、 info、 warn、 errを選べます。デフォルトはinfoです。 - 設定ファイル: "log_
level": "debug" - コマンドライン: serf agent -log-level=debug
- 設定ファイル: "log_
start_
join (-join) Serfエージェント起動時、
どのSerfエージェントと通信を開始してクラスタを形成するか明示します。 - 設定ファイル:"start_
join": "192. 168. 39. 1" - コマンドライン:serf agent -join=192.
168. 39. 1
- 設定ファイル:"start_
その他にも設定用のオプションがあります。詳細はSerfのConfigurationページが参考になります。
まとめ
Dockerを使ったコンテナ環境に対しても、