Carpe Diem

備忘録

Consulを使ってみる

概要

Consulというサービス・ディスカバリツールを使います。
クラウド時代ではオートスケールなどサーバの台数やIPが変動することが多いため、動的に検知できる必要がありConsulはそのためのツールです。
またConsulを通してどのサーバ上でどのようなサービスが動作しているか、そのポート番号、IPアドレス、ホスト名などをリアルタイムで知ることができるようになります。

環境

Consulのポート・プロトコル

Consulが使用するポート・プロトコルは以下です。

機能 TCP/UDP ポート 説明
Server RPC TCP 8300 Server が他の Agent からRPCのリクエストを受け付ける
Serf LAN TCP & UDP 8301 LAN用のゴシッププロトコル。全 Agent 同士が使う
Serf WAN TCP & UDP 8302 WAN用のゴシッププロトコル。Server 同士が使う
CLI RPC TCP 8400 consulコマンド実行時にローカルの Agent との通信に使われる
HTTP API TCP 8500 Client が HTTP リクエストを受け付ける
DNS TCP & UDP 8600 Agent が DNSクエリを受け付ける

複数サーバ間の通信で利用する83008301を閉じていると上手く動かないので注意してください。

事前準備

IP 役割
192.168.33.10 サーバ。サーバ自体でクラスタを組めます。
本番運用では冗長化のため3台or5台で組みます。
今回は簡単のため1台で。
192.168.33.11 クライアント

Vagrantfileに以下を追記します。

  config.vm.define :server do |web|
    web.vm.network :private_network, ip: "192.168.33.10"
    web.vm.network :forwarded_port, host: 8600, guest: 8600, protocol: "udp"
  end

  config.vm.define :client do |web|
    web.vm.network :private_network, ip: "192.168.33.11"
  end

ポイントはDNS機能が8600ポートで提供されているのですが、protocolがTCPでなくUDPというところです。
DNS名前解決のレコードの参照をUDPで行い、ゾーンの転送の方はTCPで行います。
なのでUDPのポートマッピングを行います。

インストール

DOWNLOAD CONSULで最新バージョンをチェックしてバイナリをダウンロードします。

$ cd /tmp
$ wget https://releases.hashicorp.com/consul/0.6.4/consul_0.6.4_linux_amd64.zip
$ unzip consul_0.6.4_linux_amd64.zip 
$ sudo mv consul /usr/local/bin/

バージョン確認します。

$ consul version
Consul v0.6.4
Consul Protocol: 3 (Understands back to: 1)

設定(サーバ)

/etc/consul.d/config.json

{
  "data_dir": "/tmp/consul",
  "server": true,
  "node_name": "server1",
  "bootstrap_expect": 1,
  "bind_addr": "192.168.33.10",
  "client_addr": "0.0.0.0"
}

各オプションの説明

オプション 説明
data_dir Consulが内部的に利用するディレクト
server サーバモードで起動するかどうか
node_name ノード名。デフォルトはホスト名。ユニークである必要がある
bootstrap_expect Consulクラスタを形成した際に指定するserverノード数。
その数に達したタイミングでリーダの選出を行う。
数に達しないと、一向にリーダが決まらない状態になる
bind_addr bindできる内部クラスタのアドレス範囲。デフォルト0.0.0.0。
vagrantだとFailed to get advertise address: Multiple private IPs found. Please configure one.が出るので指定。
client_addr bindできるクライアントのアドレス範囲。デフォルト127.0.0.1

起動

$ consul agent -config-dir /etc/consul.d

設定(クライアント)

/etc/consul.d/config.json

{
  "data_dir": "/tmp/consul",
  "server": false,
  "node_name": "client1",
  "bind_addr": "192.168.33.11",
  "start_join": ["192.168.33.10"]
}

各オプションの説明

オプション 説明
data_dir Consulが内部的に利用するディレクト
server サーバモードで起動するかどうか
node_name ノード名。デフォルトはホスト名。ユニークである必要がある
bind_addr bindできる内部クラスタのアドレス範囲。デフォルト0.0.0.0。
vagrantだとFailed to get advertise address: Multiple private IPs found. Please configure one.が出るので指定。
start_join joinするサーバ群のIP

起動

$ consul agent -config-dir /etc/consul.d

動作確認

検知できているかを確認します。サーバ、クライアントどちらからでも確認できます。
またConsulは最初のポートの話で書いたように、複数のインタフェースを用意しているのでどれを使っても確認ができます。

CLI RPCで検証

$ consul members
Node     Address             Status  Type    Build  Protocol  DC
client1  192.168.33.11:8301  alive   client  0.6.4  2         dc1
server1  192.168.33.10:8301  alive   server  0.6.4  2         dc1

クライアントを落とすと以下のようになります。

$ consul members
Node     Address             Status  Type    Build  Protocol  DC
client1  192.168.33.11:8301  left    client  0.6.4  2         dc1
server1  192.168.33.10:8301  alive   server  0.6.4  2         dc1

HTTP APIで検証

$ curl localhost:8500/v1/catalog/nodes?pretty
[
    {
        "Node": "client1",
        "Address": "192.168.33.11",
        "TaggedAddresses": {
            "wan": "192.168.33.11"
        },
        "CreateIndex": 356,
        "ModifyIndex": 357
    },
    {
        "Node": "server1",
        "Address": "192.168.33.10",
        "TaggedAddresses": {
            "wan": "192.168.33.10"
        },
        "CreateIndex": 192,
        "ModifyIndex": 355
    }
]

DNSで検証

$ dig @localhost -p 8600 <ノード名>.node.consul

で調べます。問い合わせるネームサーバーはConsulがローカルに用意してるので、@localhostで。

サーバの場合、ノード名がserver1なので

$ dig @localhost -p 8600 server1.node.consul
;; ANSWER SECTION:
server1.node.consul.    0   IN  A   192.168.33.10

クライアントの場合、ノード名がclient1なので

$ dig @localhost -p 8600 client1.node.consul
;; ANSWER SECTION:
client1.node.consul.    0   IN  A   192.168.33.11

ソース