Skip to content

Latest commit

 

History

History
365 lines (303 loc) · 10.1 KB

srd.md

File metadata and controls

365 lines (303 loc) · 10.1 KB

Consul Service Discoveryを使ってみる

Consulの機能は多岐に渡りますが、Service Discoveryはコアの機能です。Service Discoeryの機能によりシステムを構成するコンポーネント同士はService名ベースでの接続が可能となります。

ここではサービスをいくつか登録し、実際のDNSやヘルスチェックなどの機能を試してみます。

ここではローカルにNginxを2インスタンス起動させConsulからService Discoveryの機能を試してみます。

Consulサーバを立ち上げます。

consul agent -dev

Dockerで二つのインタンスを起動させます。

$ cd consul-workshop
$ git clone https://github.com/tkaburagi/nginx
$ cd nginx

$ docker-compose up -d

起動を確認しておきましょう。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
109f9530196a        nginx_bar         "nginx -g 'daemon of…"   16 seconds ago      Up 15 seconds       0.0.0.0:9090->80/tcp   nginx-bar
ac31d5eec216        nginx-foo        "nginx -g 'daemon of…"   27 seconds ago      Up 26 seconds       0.0.0.0:8080->80/tcp   nginx_foo

curlで両インスタンスからのレスポンスを確認ておきます。

$ curl 127.0.0.1:8080/index.html
<html>
<body>
<h1>Hello Consule From Foo Container</h1>
</body>
$ curl 127.0.0.1:9090/index.html
<html>
<body>
<h1>Hello Consule From Bar Container</h1>
</body>
</html>

それではこれらConsulにRegistrationしてみます。

以下のコマンドを実行し、Consulにサービスを登録します。

$ consul services register \
-name=nginx \
-id=nginx_foo \
-address=127.0.0.1 \
-port=8080 \
-tag=nginx

barのコンテナも同様に登録します。

$ consul services register \
-name=nginx \
-id=nginx_bar \
-address=127.0.0.1 \
-port=9090 \
-tag=nginx

Consulのエンドポイントを確認してサービスが登録されていることを確認してみましょう。GUIでも同様のことが出来ます。

$ curl http://127.0.0.1:8500/v1/catalog/service/nginx | jq

[
  {
    "ID": "2db4a816-17fb-3a9d-0a5f-df8739c75915",
    "Node": "Takayukis-MBP",
    "Address": "127.0.0.1",
    "Datacenter": "dc1",
    "TaggedAddresses": {
      "lan": "127.0.0.1",
      "wan": "127.0.0.1"
    },
    "NodeMeta": {
      "consul-network-segment": ""
    },
    "ServiceKind": "",
    "ServiceID": "nginx-1",
    "ServiceName": "nginx",
    "ServiceTags": [
      "nginx"
    ],
    "ServiceAddress": "127.0.0.1",
    "ServiceWeights": {
      "Passing": 1,
      "Warning": 1
    },
    "ServiceMeta": {},
    "ServicePort": 8080,
    "ServiceEnableTagOverride": false,
    "ServiceProxyDestination": "",
    "ServiceProxy": {},
    "ServiceConnect": {},
    "CreateIndex": 547,
    "ModifyIndex": 554
  }
]

digで確かめてみます。

$ dig @127.0.0.1 -p 8600 nginx.service.consul. SRV

; <<>> DiG 9.10.6 <<>> @127.0.0.1 -p 8600 nginx.service.consul. SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3031
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx.service.consul.		IN	SRV

;; ANSWER SECTION:
nginx.service.consul.	0	IN	SRV	1 1 8080 Takayukis-MBP.node.dc1.consul.
nginx.service.consul.	0	IN	SRV	1 1 9090 Takayukis-MBP.node.dc1.consul.

;; ADDITIONAL SECTION:
Takayukis-MBP.node.dc1.consul. 0 IN	A	127.0.0.1
Takayukis-MBP.node.dc1.consul. 0 IN	TXT	"consul-network-segment="
Takayukis-MBP.node.dc1.consul. 0 IN	A	127.0.0.1
Takayukis-MBP.node.dc1.consul. 0 IN	TXT	"consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sun Aug 25 15:53:01 JST 2019
;; MSG SIZE  rcvd: 251

nginx.service.consulに対してFooとBarの二つのインスタンスにアクセスできることがわかります。

HealthCheckの設定

次にHealthCheckの設定を行います。以下のJsonファイルを作成して下さい。

$ cat << EOF > check_foo.json 
{
  "ID": "nginx_foo",
  "Name": "nginx",
  "Address": "127.0.0.1",
  "Port": 8080,
  "check": {
    "http": "http://127.0.0.1:8080",
    "interval": "10s",
    "timeout": "1s"
   }
}
EOF
$ cat << EOF > check_bar.json 
{
  "ID": "nginx_bar",
  "Name": "nginx",
  "Address": "127.0.0.1",
  "Port": 9090,
  "check": {
    "http": "http://127.0.0.1:9090",
    "interval": "10s",
    "timeout": "1s"
   }
}
EOF

httpで指定したエンドポイントに対して10秒に一度ヘルスチェックを行う設定です。上記の設定を反映させてみます。

$ curl -X PUT --data-binary @check_foo.json http://127.0.0.1:8500/v1/agent/service/register
$ curl -X PUT --data-binary @check_bar.json http://127.0.0.1:8500/v1/agent/service/register

ヘルスチェックの確認をしてみましょう。GUIでも見ることができます。

$ curl http://127.0.0.1:8500/v1/health/checks/nginx | jq .
出力例
[
  {
    "Node": "Takayukis-MBP",
    "CheckID": "service:nginx-bar",
    "Name": "Service 'nginx' check",
    "Status": "passing",
    "Notes": "",
    "Output": "HTTP GET http://127.0.0.1:9090: 200 OK Output: <html>\n<body>\n<h1>Hello Consule From Bar Container</h1>\n</body>\n</html>\n",
    "ServiceID": "nginx-bar",
    "ServiceName": "nginx",
    "ServiceTags": [],
    "Definition": {},
    "CreateIndex": 1265,
    "ModifyIndex": 1292
  },
  {
    "Node": "Takayukis-MBP",
    "CheckID": "service:nginx-foo",
    "Name": "Service 'nginx' check",
    "Status": "passing",
    "Notes": "",
    "Output": "HTTP GET http://127.0.0.1:8080: 200 OK Output: <html>\n<body>\n<h1>Hello Consule From Foo Container</h1>\n</body>\n</html>\n",
    "ServiceID": "nginx-foo",
    "ServiceName": "nginx",
    "ServiceTags": [],
    "Definition": {},
    "CreateIndex": 1306,
    "ModifyIndex": 1307
  }
]

次にfooのコンテナを停止させてみます。

$ docker stop nginx-foo-1

少し時間を置いてから再度ヘルスチェックの確認をしてみます。

$ curl http://127.0.0.1:8500/v1/health/checks/nginx | jq .
出力例
[
  {
    "Node": "Takayukis-MBP",
    "CheckID": "service:nginx-bar",
    "Name": "Service 'nginx' check",
    "Status": "passing",
    "Notes": "",
    "Output": "HTTP GET http://192.168.3.3:9090: 200 OK Output: <html>\n<body>\n<h1>Hello Consule From Bar Container</h1>\n</body>\n</html>\n",
    "ServiceID": "nginx-bar",
    "ServiceName": "nginx",
    "ServiceTags": [],
    "Definition": {},
    "CreateIndex": 1265,
    "ModifyIndex": 1292
  },
  {
    "Node": "Takayukis-MBP",
    "CheckID": "service:nginx-foo",
    "Name": "Service 'nginx' check",
    "Status": "critical",
    "Notes": "",
    "Output": "Get http://192.168.3.3:8080: dial tcp 192.168.3.3:8080: connect: connection refused",
    "ServiceID": "nginx-foo",
    "ServiceName": "nginx",
    "ServiceTags": [],
    "Definition": {},
    "CreateIndex": 1306,
    "ModifyIndex": 1322
  }
]

fooのコンテナのstatusがCriticalに変化しています。この状態でdigるとどうなるでしょうか。

$ dig @127.0.0.1 -p 8600 nginx.service.consul SRV

; <<>> DiG 9.10.6 <<>> @127.0.0.1 -p 8600 nginx.service.consul. SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50525
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 3
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx.service.consul.		IN	SRV

;; ANSWER SECTION:
nginx.service.consul.	0	IN	SRV	1 1 9090 Takayukis-MBP.node.dc1.consul.

;; ADDITIONAL SECTION:
Takayukis-MBP.node.dc1.consul. 0 IN	A	127.0.0.1
Takayukis-MBP.node.dc1.consul. 0 IN	TXT	"consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sun Aug 25 22:08:32 JST 2019
;; MSG SIZE  rcvd: 150

一つのサーバのみ返ってきており、Consulが停止したサーバを自動で切り離したことがわかります。再起動しましょう。

$ docker-compose up -d
$ dig @127.0.0.1 -p 8600 nginx.service.consul. SRV

; <<>> DiG 9.10.6 <<>> @127.0.0.1 -p 8600 nginx.service.consul. SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 26653
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 5
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx.service.consul.		IN	SRV

;; ANSWER SECTION:
nginx.service.consul.	0	IN	SRV	1 1 9090 Takayukis-MBP.node.dc1.consul.
nginx.service.consul.	0	IN	SRV	1 1 8080 Takayukis-MBP.node.dc1.consul.

;; ADDITIONAL SECTION:
Takayukis-MBP.node.dc1.consul. 0 IN	A	127.0.0.1
Takayukis-MBP.node.dc1.consul. 0 IN	TXT	"consul-network-segment="
Takayukis-MBP.node.dc1.consul. 0 IN	A	127.0.0.1
Takayukis-MBP.node.dc1.consul. 0 IN	TXT	"consul-network-segment="

;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Sun Aug 25 22:07:48 JST 2019
;; MSG SIZE  rcvd: 251

正しい状態に戻りました。ConsulのService Registryの機能を使うことでプラットフォームに依存せずサービス名ベースでの相互接続やサービス間のヘルスチェックが可能です。実際のアプリケーションからはConsulを経由して、APIやデータストアなどのシステムコンポーネントにアクセスすることが出来ます。

また、Service RegistryだけでなくService Meshを実現するための様々な機能を備えています。

最後にCtr+Cで抜けて全コンテナを停止しておきましょう。

$ docker-compose down

参考リンク