Edited at
Docker2Day 24

公式の consul イメージで高可用性 Consul クラスタを試す

More than 1 year has passed since last update.


はじめに

Consul は公式イメージ library/consul があるのに、みんな progrium/consul 使いよる。

情報が足りないんかな?よっしゃ立ててみよ!


ハンズオン

お手元の docker-machine / virtualbox で試せるコピペスクリプト

# create machines (consul0, consul1, consul2)

for i in 0 1 2; do
docker-machine create -d virtualbox --virtualbox-memory 512 consul$i
done

# start consul servers
for i in 0 1 2; do
docker $(docker-machine config consul$i) run \
-d \
--name consul$i \
-p 8300-8302:8300-8302/tcp \
-p 8301-8302:8301-8302/udp \
-p 8400:8400/tcp \
-p 8500:8500/tcp \
-p 8600:8600/tcp \
-p 8600:8600/udp \
consul agent \
-server \
-node consul$i \
-ui \
-client 0.0.0.0 \
-advertise $(docker-machine ip consul$i) \
-retry-join $(docker-machine ip consul0) \
-bootstrap-expect 3
done

しばらくしたら http://$(docker-machine ip consul0):8500/ui にアクセス。

SERVICES や…

services.png

NODES を見ると、正常な consul が3つ確認できます。

nodes.png

ここで consul0 を落としてみます。

docker $(docker-machine config consul0) stop consul0

consul0 は落としてるので、 consul1 の IP でアクセス。

http://$(docker-machine ip consul1):8500/ui

SERVICES や…

fail.png

NODES を見ると、 consul0 に障害が起きていることがわかります。

fail1.png

再度、 consul0 を復旧させるとクラスタのノードにも反映されます。

docker $(docker-machine config consul0) start consul0

nodes.png

遊び終わって全部消すときは

for i in 0 1 2; do

docker $(docker-machine config consul$i) rm -f consul$i
docker-machine rm -f consul$i
done


解説

要点だけ軽く。


docker-machine create ...

実運用する時のサーバー3台に見立てて VirtualBox VM で Docker ホストを3つ作っています。

--virtualbox-memory 512 はただのメモリ節約なので無くてもOK。

付けなかった場合のデフォルトは 1024MB です。多分 Consul でこんなにいらない。

docker-machine を使っているので、パブリッククラウド向けのオプションを適切に設定すれば、そのまま上位環境にも反映できそうです。


-p のポート

Consul のドキュメント に記載があります。


  • Server RPC (Default 8300). This is used by servers to handle incoming requests from other agents. TCP only.

  • Serf LAN (Default 8301). This is used to handle gossip in the LAN. Required by all agents. TCP and UDP.

  • Serf WAN (Default 8302). This is used by servers to gossip over the WAN to other servers. TCP and UDP.

  • CLI RPC (Default 8400). This is used by all agents to handle RPC from the CLI. TCP only.

  • HTTP API (Default 8500). This is used by clients to talk to the HTTP API. TCP only.

  • DNS Interface (Default 8600). Used to resolve DNS queries. TCP and UDP.

Docker の EXPOSE 向けにまとめると


  • 8300-8302/tcp

  • 8301-8302/udp

  • 8400/tcp

  • 8500/tcp

  • 8600/tcp

  • 8600/udp


-server

サーバーモードで起動。

これがない場合は問い合わせコマンドなどを発行するためのクライアントモードになります。


-node consul$i

consul クラスタ内でのノード名をつけています。

指定しない場合のデフォルトは、 consul agent を起動するマシンの hostname が採用されます。


-ui -client 0.0.0.0

Web UI を有効にし、クライアント機能インターフェースをバインドする(要は受け入れる) IP を 0.0.0.0 (どこからでも)に変更しています。

-client はデフォルトでは 127.0.0.1 ループバックのみで、これだとクラスタリングに不都合です。

Consul クラスタを収めるサブネットや VPC 程度の範囲が適切ですが、これは Docker ホスト自体のインフラレベルで絞るべきなので、ここのオプション値は突き詰めすぎなくても良いかと思います。


-advertise $(docker-machine ip consul$i)

他のクラスタメンバーからこの consul server を指し示すための IP をセットします。


-retry-join $(docker-machine ip consul0)

既存サーバーに参加交渉してクラスタを開始する -join の便利版。

この例ではいずれのサーバーも consul0 を参加先に指定しています。

-join は単発でトライしてミスったら終了ですが、こちらはリトライし続けてくれます。


-bootstrap-expect 3

-bootstrap (リーダーの選出など、クラスタの準備を行うモードで起動する)の便利版。

join してくるノードが指定数になるまで待機し、指定数になるとブートストラップを行い、リーダーを自動選出してクラスタを開始します。

このオプションは、次のいずれかに準拠するように指定する必要があります。


  • クラスタに参加するサーバーの数を決めておいて、全てのサーバーで同じ数値を指定する。

  • メンバーは数値を指定せずに、リーダーだけ数値を指定する。

今回は1番目の手法を取りました。

Consul クラスタの運用は3台または5台(その上は7台)が推奨されています し、どのリージョン・どのゾーンに置くかすら決めづらいリーダーを決めるより、クラスタの規模をあらかじめ決めるほうが楽でしょう。


おわりに

今回構築したようなクラスタは、どのノードを参照しても同じ仕事をしてくれます。

これを活かして 【consul0 ⇔ swarm-manager0】 のような組み合わせを 0~2 まで作り、 Plan for Swarm in production にあるような高可用性 Swarm クラスタを作ってみたいですね。

ていうか最初それがやりたかったのにどうしてこうなった。

書きました本番環境にも使える高可用性かつスケーラブルな Docker Swarm + Consul クラスタを構築

consul0~2 を立てる作業も、1枚の docker-compose.yml でマシンを指定して流す方法があればもっとスマートになったかも。(--engine-labelconstraints で出来たような…できなかったような…)

以上です。