この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
おはようございます、加藤です。Consul チュートリアルをやってみたの第3回です。クラスタの作成とヘルスチェックをやってみました。
- Consul by HashiCorp
- Consulのメインページ
- Consul Curriculum - HashiCorp Learn
- Consulのチュートリアル
やってみる内容
Consul サーバー & クライアントを起動して、クライアントのクラスタへの参加(1サーバー構成だけど)とヘルスチェックの挙動確認を行います。 環境はDockerを使って用意しました。
Consul クラスターの作成
Consulは本番環境の場合、サーバー & クライアント構成で動作します。今回は1台のサーバーと1台のクライアント、合計2台で検証を行います。
下記のオプションを設定して、ノード1のConsul エージェントを起動します。
- -server
- エージェントをサーバーモードで動作させるフラグ
- -bootstrap-expect=1
- 参加予定のConsulサーバー数を指定
- Bootstrapping a Datacenter - Consul by HashiCorp
- -node=agent-one
- クラスタ内でのノードの名前(一意である必要がある)
- デフォルトはホスト名ですが検証の為に指定します
- -bind=172.20.20.10
- Configuration - Consul by HashiCorp
- -enable-script-checks=true
- ヘルスチェックの為に外部スクリプトの実行を許可するフラグ
Dockerで検証したいのでdocker-compose
で2台を立ち上げます。
使用するdocker-compose.yml
はこちらです。
docker-compose.yml
version: "3"
services:
n1:
image: consul
container_name: consul_n1
environment:
- CONSUL_BIND_ADDRESS=172.20.20.10
command: agent -server -bootstrap-expect=1 -node=agent-one -enable-script-checks=true
networks:
consul:
ipv4_address: 172.20.20.10
n2:
image: consul
container_name: consul_n2
environment:
- CONSUL_BIND_ADDRESS=172.20.20.11
command: agent -node=agent-two -enable-script-checks=true
volumes:
- "./consul.d:/consul/config"
depends_on:
- n1
networks:
consul:
ipv4_address: 172.20.20.11
networks:
consul:
driver: bridge
ipam:
driver: default
config:
- subnet: 172.20.20.0/24
環境を起動します。
host
git clone https://github.com/kmd2kmd/consul_getting_started_chapter5_6.git
cd consul_getting_started_chapter5_6
docker-compose up -d
サーバー側のコンテナの中に入り、クライアントをクラスタに参加させます。
consul members
で、agent-twoが表示されていればOKです。
host
docker-compose exec n1 sh
consul_n1
# 意図したオプションで起動しているか確認
ps | grep consul
# 6 consul 5:14 consul agent -data-dir=/consul/data -config-dir=/consul/config -server -bootstrap-expect=1 -node=agent-one -enable-script-checks=true
# 初期状態の確認
consul members
Node Address Status Type Build Protocol DC Segment
agent-one 172.20.20.10:8301 alive server 1.4.4 2 dc1 <all>
# メンバーの追加
consul join 172.20.20.11
consul members
# Node Address Status Type Build Protocol DC Segment
# agent-one 172.20.20.10:8301 alive server 1.4.4 2 dc1 <all>
# agent-two 172.20.20.11:8301 alive client 1.4.4 2 dc1 <default>
# コンテナから抜けないでこのまま継続
サーバー側から、手動操作で参加をしていますが、Consul エージェント起動時に自動で参加することや、AWS上で動いている場合はConsul サーバーのEC2インスタンスをタグから見つけ出して参加する事が可能です。(Consul サーバーのAutoScalingのサポート) Cloud Auto-join - Consul by HashiCorp
へルスチェック機能
ノード2(agent-two)は下記の2つの定義ファイルを読み込んで起動しています。
ping.json
はノード全体のヘルスチェックを行う為の設定です。Googleに対してPingが成功するか(インターネットにアクセスできるか)をヘルスチェックとして行っています。
ping.json
{
"check": {
"name": "ping",
"args": [
"ping",
"-c1",
"google.com"
],
"interval": "30s"
}
}
web.json
はサービスのヘルスチェックを行う為の設定です。自身(localhost)に対して、cURL
でTCP/80にアクセスを行えるかをヘルスチェックとして行っています。
ノード2では、Web機能を動かしていないので、サービスとしてのヘルスチェックは失敗する想定です。
web.json
{
"service": {
"name": "web",
"tags": [
"rails"
],
"port": 80,
"check": {
"args": [
"curl",
"localhost"
],
"interval": "10s"
}
}
}
ヘルスチェックに失敗したものを確認してみます。ノード2(agent-two)でサービスwebのチェックが失敗している事がわかります。
consul_n1
curl -s http://localhost:8500/v1/health/state/critical | jq
[
{
"Node": "agent-two",
"CheckID": "service:web",
"Name": "Service 'web' check",
"Status": "critical",
"Notes": "",
"Output": " % Total % Received % Xferd Average Speed Time Time Time Current\n Dload Upload Total Spent Left Speed\n\r 0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0curl: (7) Failed to connect to localhost port 80: Connection refused\n",
"ServiceID": "web",
"ServiceName": "web",
"ServiceTags": [
"rails"
],
"Definition": {},
"CreateIndex": 23,
"ModifyIndex": 23
}
]
ヘルスチェックに失敗しているので、digでサービスwebのアドレスを解決しようとしても応答がありません。
consul_n1
apk add bind-tools
dig +short @127.0.0.1 -p 8600 web.service.consul
しかし、ノードとしてはヘルスチェック(Googleへのping)に成功しているので、ノードの名前は解決をする事ができます。
consul_n1
dig +short @127.0.0.1 -p 8600 agent-two.node.consul
172.20.20.11
サービスwebを復旧させてみます。exit
でノード1から抜けた後に、ノード2のコンテナの中に入りsocat
でダミーのWebサーバーを立ち上げます。
host
docker-compose exec n2 sh
consul_n2
apk add bind-tools socat
socat -v -T0.05 tcp-l:80,reuseaddr,fork system:"echo 'HTTP/1.1 200 OK'; echo 'Connection: close'; echo; cat" > /dev/null 2>&1 &
再度、全体のヘルスチェックを確認してみると、失敗無しになっており、サービスwebの名前解決も出来るように復旧しました。
consul_n2
curl -s http://localhost:8500/v1/health/state/critical | jq
# []
dig +short @127.0.0.1 -p 8600 web.service.consul
# 172.20.20.11
あとがき
ヘルスチェックの設定形式と挙動を確認できました。今回はノードのヘルスチェックにpingを使用しましたが、HTTPチェックやTCPチェックなどいくつかのチェック手段が用意されています。 Check Definition - Consul by HashiCorp 複数のヘルスチェックを簡単に動かすことができるので、1つのサーバーで複数サービスを動かしている場合など便利に使えそうですね!