Consul Multiple Datacenters 検証結果 +α
この記事は、HashiCorp Advent Calendar 2015 17日目の記事です。
検証環境の Consul は、
$ consul --version Consul v0.6.0 Consul Protocol: 3 (Understands back to: 1)
です。
検証環境は v0.6.0
ですが、v0.6.0 に依存した話しはほとんどないと思います。
筆者は、Consul を Multiple Datacenters(以降、Multi-DC) で運用しております。
Multi-DC で Consul を導入する際に検証した結果を記します。
トピックは以下のとおりです。
- WAN
- DC をまたいで DNS を引く
- DC をまたいで KV のデータを取得する
- DC をまたいで KV にデータを入れる
- Consul Event は複数の DC に一斉に送れない
- DNS forward に Unbound を使う
- External Services
準備
Consul のバイナリを入手します。
$ curl -LO https://releases.hashicorp.com/consul/0.6.0/consul_0.6.0_linux_amd64.zip $ unzip consul_0.6.0_linux_amd64.zip
実験のために何台もサーバを立てるのは大変なので、
検証用に 1 台のサーバで consul を複数起動する - tkuchikiの日記 のような手順で、
1 台のサーバに Server x 3, Client x 1 のクラスタを 2セット作ります。
dc01
$ ./consul members Node Address Status Type Build Protocol DC consul01-dc01 10.0.2.15:8301 alive server 0.6.0 2 dc01 consul02-dc01 10.0.2.15:8311 alive server 0.6.0 2 dc01 consul03-dc01 10.0.2.15:8321 alive server 0.6.0 2 dc01 consul04-dc01 10.0.2.15:8331 alive client 0.6.0 2 dc01
$ curl http://127.0.0.1:8500/v1/status/leader "10.0.2.15:8300"
dc02
$ ./consul members -rpc-addr=127.0.0.1:18400 Node Address Status Type Build Protocol DC consul01-dc02 10.0.2.15:18301 alive server 0.6.0 2 dc02 consul02-dc02 10.0.2.15:18311 alive server 0.6.0 2 dc02 consul03-dc02 10.0.2.15:18321 alive server 0.6.0 2 dc02 consul04-dc02 10.0.2.15:18331 alive client 0.6.0 2 dc02
$ curl http://127.0.0.1:18500/v1/status/leader "10.0.2.15:18300"
WAN
WAN は、すべての DC を含めた Consul クラスタ全体のことです。
consul members -wan
は Multi-DC の Consul Server のみを返します。
$ ./consul members -wan Node Address Status Type Build Protocol DC consul01-dc01.dc01 10.0.2.15:8302 alive server 0.6.0 2 dc01 consul01-dc02.dc02 10.0.2.15:18302 alive server 0.6.0 2 dc02 consul02-dc01.dc01 10.0.2.15:8312 alive server 0.6.0 2 dc01 consul02-dc02.dc02 10.0.2.15:18312 alive server 0.6.0 2 dc02 consul03-dc01.dc01 10.0.2.15:8322 alive server 0.6.0 2 dc01 consul03-dc02.dc02 10.0.2.15:18322 alive server 0.6.0 2 dc02
client に向けて consul members -wan
を実行すると、
何も出力せず、status code 2 を返します。
$ ./consul members -rpc-addr=127.0.0.1:8430 -wan $ echo $? 2
DC をまたいで DNS を引く
dc01
の Consul に対して、dc02
の node を問い合わせます。
$ dig @127.0.0.1 -p 8630 consul04-dc02.node.dc02.consul A ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> @127.0.0.1 -p 8630 consul04-dc02.node.dc02.consul A ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 19552 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;consul04-dc02.node.dc02.consul. IN A ;; ANSWER SECTION: consul04-dc02.node.dc02.consul. 60 IN A 10.0.2.15 ;; Query time: 1 msec ;; SERVER: 127.0.0.1#8630(127.0.0.1) ;; WHEN: Tue Dec 15 17:58:09 2015 ;; MSG SIZE rcvd: 94
A レコードが返ってきます。
DNS Interface - Consul by HashiCorp に書いてありますが、
<node>.node[.datacenter].<domain>
なので、
同一 DC にいる場合は、 [.datacenter]
を省略することができます。
$ dig @127.0.0.1 -p 8630 consul04-dc01.node.consul A ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> @127.0.0.1 -p 8630 consul04-dc01.node.consul A ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 46271 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;consul04-dc01.node.consul. IN A ;; ANSWER SECTION: consul04-dc01.node.consul. 60 IN A 10.0.2.15 ;; Query time: 0 msec ;; SERVER: 127.0.0.1#8630(127.0.0.1) ;; WHEN: Tue Dec 15 18:05:00 2015 ;; MSG SIZE rcvd: 84
DC をまたいで KV のデータを取得する
まず、通常の KV にデータを PUT して取り出す場合です。
dc01
に PUT します。
$ curl -X PUT -d "dc01-test" http://127.0.0.1:8500/v1/kv/dc01 true
$ curl http://127.0.0.1:8500/v1/kv/dc01?raw dc01-test $ curl http://127.0.0.1:8510/v1/kv/dc01?raw dc01-test $ curl http://127.0.0.1:8520/v1/kv/dc01?raw dc01-test $ curl http://127.0.0.1:8530/v1/kv/dc01?raw dc01-test
dc01
内で KV のデータが共有されていますね。
この状態で、dc02
の KV を参照すると、
$ curl http://127.0.0.1:18500/v1/kv/dc01?raw
データが入っていませんね。
これは、仕様なのでおかしい挙動ではありません。
追記: 2016-08-23 19:30
KV をまたいでデータを取得するためには、以下のように dc=
をつければ OK です。訂正致します。
curl -s 'data' http://127.0.0.1:18500/v1/kv/data?dc=dc02&raw"
ちなみに、consul-replicate というものがあるので、
これを使えば KV のデータをレプリケーションすることができます。
しかし、
- consul-replicate をどのサーバで動かすか
- consul-replicate の HA構成はどうするか
- consul-replicate のレプリケーションが一方向なので、DC 間での同期はどうするのか
といった問題があるので、使いどころが難しそうです。
DC をまたいで KV にデータを入れる
追記: 2016-08-23 19:30
curl -s -X PUT -d 'data' http://127.0.0.1:18500/v1/kv/data?dc=dc02"
のように、dc=
をつければ datacenter をまたいで KV にデータをいれることができました。
間違ってた情報を書いていたので、そちらは削除します。
Consul Event は複数の DC に一斉に送れない
consul event
には、-datacenter
というオプションがありますが、
指定できる DC は一つだけです。
複数の DC に Event を送りたい場合は、DC ごとに実行するようです。
Unbound で DNS forward する
Dnsmasq で Consul DNS に forward して内部 DNS に使っている方が多いと思いますが、
Unbound でも forward できます。
# unbound.conf server: access-control: 127.0.0.0/8 allow do-not-query-localhost: no forward-zone: name: "consul" forward-addr: 127.0.0.1@8600
Unbound の設定に明るくなくて、
デフォルトの設定に上記設定を追加したらうまく forward できませんでした...
設定が最低限すぎるので、適宜設定を追加してお使いください。
External Services
Consul Service は、Consul クラスタ内のサービスを監視しますが、
External Services を使うと、外部のサービスを監視することができます。
$ curl -X PUT -d '{"Datacenter": "dc01", "Node": "google", "Address": "www.google.com", "Service": {"Service": "search", "Port": 80}}' http://127.0.0.1:8500/v1/catalog/register true
External Services を使うためには、recursor
または recursors
で DNS サーバを指定しなくてはなりません。
consul01-dc01(port 8600) は recursor
を設定せず、
consul02-dc01(port 8610) は設定しているとします。
その場合、以下の様な実行結果になります。
$ dig @127.0.0.1 -p 8600 search.service.consul ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> @127.0.0.1 -p 8600 search.service.consul ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56306 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 ;; WARNING: recursion requested but not available ;; QUESTION SECTION: ;search.service.consul. IN A ;; ANSWER SECTION: search.service.consul. 15 IN CNAME www.google.com. ;; Query time: 0 msec ;; SERVER: 127.0.0.1#8600(127.0.0.1) ;; WHEN: Tue Dec 15 19:41:34 2015 ;; MSG SIZE rcvd: 88
$ dig @127.0.0.1 -p 8610 search.service.consul ; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.37.rc1.el6_7.2 <<>> @127.0.0.1 -p 8610 search.service.consul ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26004 ;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0 ;; QUESTION SECTION: ;search.service.consul. IN A ;; ANSWER SECTION: search.service.consul. 15 IN CNAME www.google.com. www.google.com. 149 IN A 216.58.220.196 ;; Query time: 11 msec ;; SERVER: 127.0.0.1#8610(127.0.0.1) ;; WHEN: Tue Dec 15 19:42:01 2015 ;; MSG SIZE rcvd: 118
recursor
を設定した consul02-dc01 は、A レコードが返ってきます。
recursor
の反映は consul reload
ではできませんので、再起動する必要があります。
※追記
recursor を設定していない状態からの反映は consul reload
ではできませんが、
recursor を設定している状態からは consul reload
で変更を反映することができます。
まとめ
Consul の Multi-DC について検証した結果 +α を紹介しました。
使った設定ファイルは https://gist.github.com/tkuchiki/c4ea89df94c8e2a51b83 に置いてあります。
明日は、Multiple DNS recursors の対応ありがとうございます!(http://fstn.hateblo.jp/entry/2015/02/21/024400)
な、@foostan さんです!