У меня консул и регистратор работает. Я могу запустить службы в докер-контейнерах:
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
Это все хорошо. Это в основном означает, что я могу начать использовать консул для поиска своих сервисов, так что-то вроде этого:
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
, как мне использовать эту информацию из приложения?
Я вижу разные варианты:
- внедрить в моем приложении слой «разрешения DNS для консула» (в виде библиотеки), который делает
SRV
запросов DNS (или API) для консула для определения IP и порта.
- заставляет контейнеры всегда выставлять порт
80
(я выполняю http REST-сервисы), так что разрешение DNS не должно заботиться о порте.
Первый вариант подразумевает некоторый рефакторинг приложения, которого я хотел бы избежать. Второй вариант подразумевает необходимость настройки всех служб.
Есть ли лучшая альтернатива? Существует ли прозрачный способ интеграции SRV
DNS-запросов при выполнении разрешения имен и автоматического использования порта вместо использования порта 80
(или 443
)?
Я не понимаю, как это вообще возможно с python
requests
, или с curl
, или с любым другим инструментом: нам всегда нужно вручную указывать порт при использовании этих библиотек / инструментов.
И связанный с этим вопрос: когда и как SRV
используются DNS-запросы? Похоже, они предоставляют именно ту информацию, которая мне нужна, но обычное разрешение DNS ее не использует: клиенты всегда делают предположения относительно порта, на котором работает служба (80
для http
, 443
для https
и т. д.) вместо того, чтобы спрашивать DNS-сервер, на котором есть информация.