Serf/Consulで管理を自動化! ~実践的な手法を紹介~

第3回 Dockerコンテナ群をSerfで管理する方法・詳細オプション

この記事を読むのに必要な時間:およそ 5 分

コンテナ内をserf queryを使って同時操作

Serfのイベントハンドラsshを使い,コンテナにログインすることなく,コンテナ内で一斉にコマンドを実行してみます。引き続きホストOS上で作業を行います。ここで実行するのは,前回の連載で使用したserf queryコマンドを使用します。任意のコマンドを実行するにはserf eventまたはserf queryを使う方法がありますが,ここでは結果を実行した画面に表示させたいためquery形式を定義していました。結果を知る必要がなければevent形式でも構いません。

例として,コマンドserf ssh uptimeを実行してみます。正常に処理されると,次のように各コンテナ内部でuptimeが実行され,その結果が表示されます。それぞれのコンテナ内では,イベントsshが発生すると,/bin/bashと引数としてのコマンドを実行した結果が表示されます。

# 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

これはあくまで一例ですので,catyumコマンドだけでなく,様々なコマンドを実行することができます。また,イベントハンドラの例として/bin/bashを指定しました。しかしroot権限で何でも実行できてしまうため,インターネット上の共用環境など,セキュリティ上で好ましくない場合,特定のコマンドのみ実行可能なイベントハンドラを作っておくことを強く推奨します。

メンバー管理とタグ

Serfはエージェントのメンバー毎にタグを付ける機能があります。コンテナを複数起動している場合,そのコンテナの役割や目的を記録するために,タグの機能を使えます。タグの情報はserf membersコマンドで参照できるだけではなく,イベントハンドラ内でも変数として利用できます。そのため,タグ機能を応用すると,イベントハンドラ内で特定のタグを持つコンテナやサーバのみコマンドを実行させる使い方もあります。

タグを指定するにはserf tags -set <key>=<value>の形式でコマンドを実行します。コマンドの実行は,ホストOS,コンテナ内どちらでも構いません。以下は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を同じ設定で起動・停止したい場合や,複数のSerf動作環境で同じ設定を適用したい場合は,外部ファイルの利用が手軽です。ファイルは次のようなJSON形式で定義します。

{
  "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形式のファイルを作成した後,Serf起動時に-config-file=オプションを指定します。

$ serf agent -confg-file=/etc/serf.json

JSON形式の場合は,Serfの設定変更と反映が簡単になります。エージェント起動後でも設定変更したい場合は,対象のJSONファイルを修正後,kill -1 <serfのPID>を実行します。

著者プロフィール

前佛雅人(ぜんぶつまさひと)

クリエーションライン株式会社 Technology Evangelist

ホスティングサービスで運用保守サポートに携わった後,現職へ。サポート業務や新技術検証・開発業務を行う。趣味で監視や自動化に関するOSS検証や翻訳を行うのが好き。辛口の日本酒が大好き。

Twitter:@zembutsu