サービス検出を使った自動化を行うために、
サービスの可用性を高めるConsul
複数台のサーバ構成によって、
クラウド技術の普及により、
このような課題を簡単に解決すべく登場したのがConsulです。Consulが持つ機能の1つにサービス検出
また、
Consulは、
このConsulの機能を使えば、
Nginxの負荷分散にConsulを使うには
それでは、
同一ネットワーク上で、
- Consulサーバ:HTTP・
DNSインターフェースを持つ。1台 (192. 168. 39. 3) のみ。 - Consulクライアント:サービスが稼働する環境を想定。2台
(192. 168. 39. 11、 192. 168. 39. 12) で構成。

Consulサーバのセットアップ
Consulのセットアップの他に、
まず、
$ wget -O 0.5.0_linux_amd64.zip https://dl.bintray.com/mitchellh/consul/0.5.0_linux_amd64.zip $ unzip 0.5.0_linux_amd64.zip $ sudo cp consul /usr/bin/consul
セットアップ後は、nohup
を使ってバックグラウンドでConsulサーバを起動するのは、
$ nohup consul agent -server -bootstrap-expect=1 -data-dir=/tmp/consul -bind=192.168.39.3 -node=server -ui-dir=/opt/consul/dist &
正常に起動したかどうかは、consul members
コマンドでも確認できます。
# consul members Node Address Status Type Build Protocol server 192.168.39.3:8301 alive server 0.5.0 2
次にdnsmasqの設定を行います。ConsulのDNSインターフェースはポート8600を使用するため、dig
等のコマンドでConsulの名前解決を行う場合は、curl
やping
等のツールで名前解決を手軽に行うのがdnsmasqです。
以下はCentOSにおけるセットアップ例です。
# yum -y install dnsmasq # cp -p /etc/dnsmasq.conf /etc/dnsmasq.conf.orig # echo "server=/consul/127.0.0.1#8600" >> /etc/dnsmasq.conf # echo "strict-order" >> /etc/dnsmasq.conf
必要に応じて/etc/
も書き換えます。自分自身で名前解決を行うためnameserver 127.
を既存の指定よりも前の行に記述します。
nameserver 127.0.0.1
nameserver 8.8.8.8
それからdnsmasqを起動します。
# chkconfig dnsmasq on # service dnsmasq start
正常に名前解決を行えるか確認します。host
コマンドを使い、server
というノード名称を持つIPアドレスを確認します。
$ host server.node.consul server.node.consul has address 192.168.39.3
名前解決の確認ができれば、ping
などコマンドライン上から利用できることがわかります。
$ ping -c 3 server.node.consul PING server.node.consul (192.168.39.3) 56(84) bytes of data. 64 bytes from consul-server (192.168.39.3): icmp_seq=1 ttl=64 time=0.008 ms 64 bytes from consul-server (192.168.39.3): icmp_seq=2 ttl=64 time=0.042 ms 64 bytes from consul-server (192.168.39.3): icmp_seq=3 ttl=64 time=0.035 ms --- server.node.consul ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.008/0.028/0.042/0.015 ms
これでConsulサーバー側の準備が完了しました。
Consulクライアントのセットアップ
次は、node1
、node2
と設定することにします。
まず始めに、
# yum -y install nginx # service nginx start # echo 'node1' > /usr/share/nginx/html/consul.html
curl
を使って動作確認をします。正常に設定が終わっていれば、node1
という文字列が画面に表示されます。これはホスト名を確認用するためでなく、
$ curl http://127.0.0.1/consul.html node1
次にConsulエージェントのセットアップです。先ほどのConsulサーバと同様に行います。
$ wget -O 0.5.0_linux_amd64.zip https://dl.bintray.com/mitchellh/consul/0.5.0_linux_amd64.zip $ unzip 0.5.0_linux_amd64.zip $ sudo cp consul /usr/bin/consul
以上の動作を2台目のサーバでも繰り返します。このとき、node1
の箇所はnonde2
に置き換えての実行をお願いします。
Consulへのサービス登録準備
それではConsulにサービスを登録します。サービス登録には、
あらかじめ、
# mkdir /etc/consul.d/ # cat << EOF > /etc/consul.d/web.json { "service": { "name": "web", "tags": [ "nginx" ], "port": 80, "check": { "script": "curl http://127.0.0.1:80/consul.html >/dev/null 2>&1", "interval": "10s", "timeout": "5s" } } } EOF
ここではnginx
を指定しています。重要なのはcheck
で囲まれたブロックです。script
でcurl
コマンドでconsu.
が取得可能かで判断します。またinterval
は、script
を実行する間隔です。10s
は10秒ごとにという指定ですtimeout
でタイムアウト秒数を指定しました。
今回はcurl
を使いましたが、ping
でも任意のコマンドを指定できます。Consulは終了コードによってサービスの状態を区別します。終了コード0
であれば正常1
の場合は警告
Consulエージェントの起動とサービス登録
準備が整ったら次のようにConsulを起動します。
$ consul agent -data-dir=/tmp/consul -node=node1 -bind=192.168.39.11 -config-dir=/etc/consul.d/ -join=192.168.39.3
ここで指定したオプションは、
-data-dir
- Consul用のデータ保存に使うディレクトリです。
-node
- このConsulノードの名称であり、
Consulクラスタ内で重複できません。 -bind
- 使用するIPアドレスを明示しています。
-config-dir
- 設定ファイル用のディレクトリを指定し、
対象以下の .json
ファイルを読み込みます。 -join
- ConsulサーバのIPアドレスを指定します。この例では
192.
です。168. 39. 3
正常に実行すると、web
サービスが認識されたことがわかります。
==> Starting Consul agent... ==> Starting Consul agent RPC... ==> Joining cluster... Join completed. Synced with 1 initial agents (省略) 2015/04/18 23:15:20 [INFO] consul: adding server server (Addr: 192.168.39.3:8300) (DC: dc1) 2015/04/18 23:15:21 [INFO] agent: Synced service 'web' 2015/04/18 23:15:25 [INFO] agent: Synced check 'service:web'
consul members
コマンドを実行すると、
$ consul members Node Address Status Type Build Protocol server 192.168.39.3:8301 alive server 0.5.0 2 node1 192.168.39.11:8301 alive client 0.5.0
動作確認として、
# dig node1.node.consul a (省略) ;; QUESTION SECTION: ;node1.node.consul. IN A ;; ANSWER SECTION: node1.node.consul. 0 IN A 192.168.39.11
この機能を使えば、
更にweb
サービスの登録状況を確認します。Consulは登録したサービス名で名前解決が可能です。先ほど登録したサービスweb
の情報を持つIPアドレスを調べるには、web.
という名前で名前解決を試みます。正常に処理されると、
$ dig web.service.consul a (省略) ;; ANSWER SECTION: web.service.consul. 0 IN A 192.168.39.11
同様にcurl
を使って動作確認してみましょう。ホスト名をweb.
と指定することで、
$ curl http://web.service.consul/consul.html node1
2台目のサービスを登録
それでは、-node
のノード名称と-bind
のIPアドレスが違うだけです。
$ consul agent -data-dir=/tmp/consul -node=node2 -bind=192.168.39.12 -config-file=/etc/consul.d/ -join=192.168.39.3
この状態でconsul members
コマンドを実行すると、
$ consul members Node Address Status Type Build Protocol node1 192.168.39.11:8301 alive client 0.5.0 2 node2 192.168.39.12:8301 alive client 0.5.0 2 server 192.168.39.3:8301 alive server 0.5.0 2
また、web
が登録されているかどうかも、dig
コマンドで確認します。すると、
# dig web.service.consul a (省略) ;; QUESTION SECTION: ;web.service.consul. IN A ;; ANSWER SECTION: web.service.consul. 0 IN A 192.168.39.11 web.service.consul. 0 IN A 192.168.39.12
この状態でweb
サービスに対するDNSラウンドロビンが行えるようになります。curl
コマンドを何度か実行すると、
$ curl http://web.service.consul/consul.html node1 $ curl http://web.service.consul/consul.html node2 $ curl http://web.service.consul/consul.html node1 $ curl http://web.service.consul/consul.html node2
サービス障害と名前解決
引き続きConsulのサービス検出機能を見ていきます。例えば、
# service nginx stop Stopping nginx: [ OK ]
Consulサーバ上でdig
を実行すると、
dig web.service.consul a (省略) ;; QUESTION SECTION: ;web.service.consul. IN A ;; ANSWER SECTION: web.service.consul. 0 IN A 192.168.39.12
まとめ
今回はNginxのサービス検出をDNSで行う方法を見てきました。Nginxに限らず、
次回はこのサービス検出をトリガとして、