Consul Cheat Sheet 日本語版

これから Consul を使う方の参考になりましたら、というか自分のための整理です。

## これは何？

> *"Service discovery and configuration made easy. Distributed, highly available, and datacenter-aware."*
> *訳:サービス検出と設定を簡単に。データセンタ間を意識した分散と高可用性。

Consul ( http://www.consul.io/ ) は、サービス検出や監視と設定を行うためのツール。[Vagrant](http://www.vagrantup.com/) や [Packer](http://www.packer.io/)、[Serf](http://www.serfdom.io/) を製作している [Hashicorp 社](http://www.hashicorp.com/)製のツールで、Go 言語で書かれており、オープンソース(Mozilla Public license, version 2.0)で公開されている。開発は [GitHub](https://github.com/hashicorp/consul) を通してオープンに行われている。

### Serf と Consul の違い
Serf はノード検出が `serf` エージェント単位であるのに対し、Consul は HTTP や MySQL などのサービス単位で行う事ができる。また Consul はデータ冗長化の仕組みや KVS を内蔵しているほか、HTTP や DNS などのインターフェースを備えている。
一方、Consul の現行バージョン (v.0.3) では、Serf のイベントハンドラに相当する機能は無く、何か変か発生したときのアクションは自分で実装する必要がある。[ロードマップ](https://groups.google.com/forum/#!topic/consul-tool/J3Oiysk3ggQ)によると、将来的には Serf のようなイベントハンドラも実装される模様。

## インストール
前提として、Consul にはサーバとノードという二つの役割を持つ。

* Consul サーバ ... データを保管し、ノードが収集した情報を回答するインターフェース
* Consul ノード ... 実際に監視を行い、サーバに情報を伝えるエージェント

いずれの場合でも、単一の `consul` という名前のバイナリで実行可能である。起動時に付けるオプションによって、どちらの役割もこなせる。

オフィシャルの[ダウンロードサイト](http://www.consul.io/downloads.html)から、対応した OS のバイナリをダウンロードし、展開する。現在対応している OS は、Mac OS X、Linux、Windows である。

### CentOS6/RHEL6 でのセットアップ方法

```
$ wget -O 0.3.0_linux_amd64.zip https://dl.bintray.com/mitchellh/consul/0.3.0_linux_amd64.zip
$ unzip ./0.3.0_linux_amd64.zip
# cp ./consul /usr/bin/consul
```

動作確認は、バージョン番号を確認。

```
$ consul -v
Consul v0.3.0
Consul Protocol: 2 (Understands back to: 1)
```

### Web UI のセットアップ方法
Consul 本体とは別パッケージ。Web UI を使わないのであれば、入れる必要はない。

```
$ wget -O 0.3.0_web_ui.zip https://dl.bintray.com/mitchellh/consul/0.3.0_web_ui.zip
$ unzip 0.3.0_web_ui.zip
# mkdir /opt/consul
# mv ./dist /opt/consul/webui
```

Web UI を有効にするには、Consul Server 起動時に、`-ui-dir=/opt/consul/webui/` のように指定する。あとは HTTP インターフェースのポート番号（標準:8500) に対してアクセスすると表示される（ http://<ホスト>:8500/ ）。

## Consul の４つの特長

### サービス検出
* 'http' や 'mysql' など、任意のサービスを定義する
* 検出対象は、JSON 形式のファイルか API で定義
* 検出結果を HTTP API か DNS を通して取得、Web UI でも確認できる

HTTPインターフェース(標準は Port 8500)に curl で問い合わせ:

```
$ curl -s http://192.168.39.5:8500/v1/catalog/nodes  | jq '.'
[
   {
     "Address": "192.168.39.5",
     "Node": "consul1.pocketstudio.net“
   },
   {
     "Address": "192.168.39.6",
     "Node": "consul2.pocketstudio.net“
   }
]
```

DNS インターフェース ( Port 8600 が標準 ) に dig で問い合わせ:

```
$ dig @192.168.39.5 -p 8600 consul1.node.consul any

; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.23.rc1.el6_5.1 <<>> @192.168.39.5 -p 8600 consul1.node.consul any
(snip)
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;consul1.node.consul.           IN      ANY

;; ANSWER SECTION:
consul1.node.consul.    0       IN      A       192.168.39.5
```

### 障害検知
* Consul node がヘルスチェックを実施する
* 検出済みのサービスに対する障害発生を検出する
* 監視間隔や対象は、ノードが主体的に対象ホスト内部から監視
* HTTP または DNS インターフェース、Web UI で確認できる

HTTP インターフェースで確認:

```
$ curl http://192.168.39.5:8500/v1/health/state/critical | jq '.'
[
  {
    "ServiceName": "web",
    "ServiceID": "web",
    "Notes": "",
    "Status": "critical",
    "Name": "Service 'web' check",
    "CheckID": "service:web",
    "Node": "consul1"
  }
]

```

### KVS
* HTTP API を通して RESTful に問い合わせ・操作ができる
* Consul server 間のデータを複製・保全
* Consul システムも内部で使用
* ユーザによる一般的な KVS としても利用可（base64でデコードが必要）
* ロック機能を使える（クライアントのリーダ選出は実装中）

### 複数データセンタ（ネットワーク）対応
* 複数のネットワークをまたがった通信を行う
* LAN 側と WAN 側で、別々のゴシックプールを持つ
* ローカル側のクラスタにない問い合わせは、対象データセンタに問い合わせ

## Consul の起動
### Consul サーバ起動
起動例：

```
$ consul agent -server -bootstrap -client=192.168.39.5 -dc=local \
    -node=consul1 -data-dir=/tmp/consul  -bind=192.168.39.5
```

重要なのは、初回起動する Consul サーバでは `-bootstrap` を付ける事。
2台目以降でクラスタを形成する際には `-server` と `-join` を使い、1台目のサーバを指定する。

なお、Server の障害耐性(fault tolerance)を高めるには、3台以上でクラスタを組む必要がある（[参考ページ](http://www.consul.io/docs/internals/consensus.html)の末尾 *Deployment Table* を参照）。

### Consul ノード起動

Consul ノードとして実行したい場合は、`-server` オプションを明示しない。

```
$ consul agent -dc=local -node=consul2 -data-dir=/tmp/consul2 \
    -bind=192.168.39.6 -join=192.168.39.5
```

### agent 起動時の出力内容

* **Node name** ... ノード名（エージェント固有のもの）。`-node`フラグで指定可
* **Datacenter** ... データセンタ名。`-dc` フラグで指定可
* **Server** ... サーバかクライアント、どちらで動作しているか
* **Client Addr** ... HTTP・DNS・RPC インターフェースの情報

### メンバの確認
`consul members` コマンドを実行する事で、サーバやクライアントの一覧や、死活状況が確認出来る。

```
# consul members
Node     Address             Status  Type    Build  Protocol
consul3  192.168.39.13:8301  alive   client  0.3.0  2
consul1  192.168.39.11:8301  alive   server  0.3.0  2
```

## 設定
### サービスの定義方法
HTTP インターフェースで API を経由して指定する方法と、ノードでのエージェント起動時、`-config-file` または `-config-dir` (対象ディレクトリ内の .json ファイルのみ対象)で指定する。

例えば、HTTP サービスのチェックを行うスクリプトの例は、次のようになる。

```file:/etc/consul.d/httpd.json
{
  "service": {
    "name": "web",
    "tags": [ "httpd" ],
    "port": 80,
    "check": {
      "script": "curl localhost:80 >/dev/null 2>&1",
      "interval": "10s"
    }
  }
}
```

## HTTP API
Consul は RESTful な HTTP API を持ち、ノードやサービスのチェックに関する設定や、設定変更、削除が可能。現行の API のバージョンは `v1` 。
エンドポイントには、以下の種類がある。
* **kv** ... キーバリュー・ストア
* **agent** ... エージェント制御
* **catalog** ... ノードやサービス管理
* **health** ... ヘルスチェックの管理
* **status** ... Consul のシステム状態
* **session** ... セッション管理やロック
* **internal** ... Consul 内部で使用

### キーバリュー・ストア ( kv )

* **/v1/kv/<key>**
`GET` `PUT` `DELETE` などのメソッドを使い、キーバリュー・ストアとしてユーザが任意に利用可能。ただし、GET で取得したデータは base64 でデコードする必要がある。

### エージェント ( agent )
ローカルの Consul エージェントと連携するために使用。

* `/v1/agent/checks` ... ローカルエージェントが管理している check を返す
* `/v1/agent/services` ... ローカルエージェントが管理している service を返す
* `/v1/agent/members` ... ローカル serf エージェントが見えているメンバを返す
* `/v1/agent/join/<address>` ... ローカルエージェントがノードに join するトリガ
* `/v1/agent/force-leave/<node>** ... ノードを force remove（強制削除）
* `/v1/agent/check/register` ... 新しいローカル check の登録
* `/v1/agent/check/pass/<checkID>` ... ローカルテストを通過(passing)したとマーク
* `/v1/agent/check/warn/<checkID>` ... ローカルテストの警告(warning)をマーク
* `/v1/agent/check/fail/<checkID>` ... ローカルテストの障害(critical)をマーク
* `/v1/agent/service/register` ... 新しいローカル service の登録
* `/v1/agent/service/deregister/<serviceID>` ... ローカル service の削除

### カタログ ( catalog )
node や service などに対する監視 ( checks ) の登録や削除。

* `/v1/catalog/register` ... 新しい node、service、check の登録
* `/v1/catalog/datacenters` ... 既知のデータセンタ一覧
* `/v1/catalog/nodes` ... 指定したデータセンタ上に存在するノード一覧
* `/v1/catalog/services` ... 指定したデータセンタ上に存在するサービス一覧
* `/v1/catalog/service/<service>` ... 指定したサービスが存在するノード一覧
* `/v1/catalog/node/<node>` ... 指定したノード上のサービス一覧

### ヘルスチェック ( health )
各サービスやノードの状態を確認。

* `/v1/health/node/<node>` ... ノードのヘルス情報を返す
* `/v1/health/checks/<service>` ... service のヘルス情報に関する check を返す
* `/v1/health/service/<service>` ... service を持つノードのヘルス情報を返す
* `/v1/health/state/<state>` ... 指定した state 状態にある check を返す

### クラスタ状態 ( status )
Consul クラスタに関する情報を返す。

* `/v1/status/leader` ... 現在の Raft リーダを返す
* `/v1/status/peers` ... 現在の Raft ピアの一覧を返す

### セッション ( session)
セッションの作成、破棄、問い合わせに使用。

* `/v1/session/create` ... 新しいセッションの作成
* `/v1/session/destroy/<session>` ... 指定したセッションの破棄
* `/v1/session/info/<session>` ... 指定したセッションに問い合わせ
* `/v1/session/node/<node>` ... 特定ノードに紐付くセッション一覧
* `/v1/session/list:アクティブなセッションの一覧



参考

* http://www.consul.io/docs/agent/http.html
* 参考訳：http://pocketstudio.jp/log3/2014/04/23/consul_docs_part2/

## DNS インターフェース

標準で Port 8600 に問い合わせると、DNS の回答を得られる。`dig` であれば `dig @127.0.0.1 -p 8600` のようにポートを明示する。Consul のトップレベルドメインは `.consul`。

問い合わせの形式：

```
<タグ>.<サービス名>.<ノード名>.node.<データセンタ名>.consul
```
タグおよびサービス名は省略可能。

参考

* Consulの名前解決にDNS Forwardingを使う方法 - Qiita
 * http://qiita.com/zembutsu/items/ea05fbeff06cafb5ec2e


## 参考
* http://www.consul.io/