我正在运行consul和registrator。我可以在docker容器中启动服务:
docker run -d -P --name=redis redis
正如预期的那样,registrator
能够在consul
中注册服务:
http http://localhost:8500/v1/catalog/service/redis
HTTP/1.1 200 OK
Content-Encoding: gzip
Content-Length: 308
Content-Type: application/json
Date: Fri, 04 May 2018 11:33:50 GMT
Vary: Accept-Encoding
X-Consul-Effective-Consistency: leader
X-Consul-Index: 34
X-Consul-Knownleader: true
X-Consul-Lastcontact: 0
[
{
"Address": "127.0.0.1",
"CreateIndex": 34,
"Datacenter": "dc1",
"ID": "48b6c821-3b93-dbf4-394e-5024123ea7df",
"ModifyIndex": 34,
"Node": "863e97e527c3",
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceAddress": "",
"ServiceEnableTagOverride": false,
"ServiceID": "polyphemus.wavilon.net:redis:6379",
"ServiceMeta": {},
"ServiceName": "redis",
"ServicePort": 32769,
"ServiceTags": [],
"TaggedAddresses": {
"lan": "127.0.0.1",
"wan": "127.0.0.1"
}
}
]
然后我可以使用consul
DNS服务:
» dig @127.0.0.1 -p 8600 redis.service.consul
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @127.0.0.1 -p 8600 redis.service.consul
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 62382
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;redis.service.consul. IN A
;; ANSWER SECTION:
redis.service.consul. 0 IN A 127.0.0.1
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Fri May 04 13:31:21 CEST 2018
;; MSG SIZE rcvd: 65
这一切都很好。这基本上意味着我可以开始使用consul来定位我的服务,所以这样的事情:
curl -X GET http://myservice.service.consul
可以在我的容器内工作。但是......这里缺少一件:registrator
知道IP 和运行服务的端口。我可以通过特殊的dns SRV
请求来检查:
» dig @127.0.0.1 -p 8600 redis.service.consul SRV
; <<>> DiG 9.10.3-P4-Ubuntu <<>> @127.0.0.1 -p 8600 redis.service.consul SRV
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52758
;; 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:
;redis.service.consul. IN SRV
;; ANSWER SECTION:
redis.service.consul. 0 IN SRV 1 1 32769 863e97e527c3.node.dc1.consul.
;; ADDITIONAL SECTION:
863e97e527c3.node.dc1.consul. 0 IN A 127.0.0.1
863e97e527c3.node.dc1.consul. 0 IN TXT "consul-network-segment="
;; Query time: 0 msec
;; SERVER: 127.0.0.1#8600(127.0.0.1)
;; WHEN: Fri May 04 13:36:02 CEST 2018
;; MSG SIZE rcvd: 149
我的问题是:如何在我的应用程序中集成它?我们假设我正在使用python
编写requests
个应用程序。 DNS解析如何定位和使用服务公开的端口?
要明确:信息已在consul
中正确注册,如何使用应用程序中的此信息?
我看到了不同的选择:
SRV
DNS(或API)请求被查询以便定位IP和端口。80
(我正在做http REST服务),因此DNS解析不需要关心端口。第一个选项意味着应用程序的一些重构,我想避免。第二种选择意味着我需要摆弄所有服务配置。
有更好的选择吗?在进行名称解析时是否有透明的方法来集成SRV
DNS请求,并自动使用端口而不是使用端口80
(或443
)?
我看不出这对python
requests
,curl
或任何其他工具的可行性如何:我们总是需要在使用时手动指定端口那些图书馆/工具。
还有一个相关问题:何时/如何使用SRV
DNS请求?似乎那些提供了我需要的信息,但正常的DNS解析并没有使用它:客户端总是假设服务运行的端口(80
为http
,{{ 1}}用于443
等等,而不是询问具有该信息的DNS服务器。
答案 0 :(得分:0)
在DNS的限制范围内或直接使用Consul API,没有其他选择,正如您已经在上面提到过的那样;正如它所说here:
然而,相同的链接确实提供了一些替代方案,这些方案总是涉及中间人。在 Fabio 的情况下,使用有效的直接DNS,通过consul服务标签从应用程序到端口的关联,而不是从应用程序到[服务]端口的任何直接引用。...在这种模式下,应用程序和服务每次想要在数据中心找到其他服务时都直接与Consul交谈.... [缺点]需要在应用程序中直接使用HTTP API或制作DNS 查询并假设端口或进行两次DNS查询以查找 地址和端口
答案 1 :(得分:0)
我们处理此问题的几种方法:
谢谢, 阿鲁尔