Как использовать сервисный порт при разрешении DNS - PullRequest
0 голосов
/ 04 мая 2018

У меня консул и регистратор работает. Я могу запустить службы в докер-контейнерах:

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-сервер, на котором есть информация.

Ответы [ 2 ]

0 голосов
/ 07 июля 2018

Несколько способов решения этой проблемы:

  • Использование оверлейной сети Docker для связи между контейнерами. В этом случае ваши порты могут быть статическими (на уровне контейнера), и вы можете использовать номер порта при установлении соединения
  • Используйте «consul-template» для генерации файла конфигурации с IP и информацией о порте, считанной из консула. Эта команда cons-template обычно запускается как точка входа в докер и, в свою очередь, запускает ваше реальное приложение. Каждый раз, когда происходит изменение в консуле, consul-template сгенерирует файл и может быть настроен для перезагрузки / перезапуска вашего приложения

Спасибо, Arul

0 голосов
/ 05 мая 2018

Нет альтернативы в пределах ограничений DNS или использования Consul API напрямую, как вы уже упоминали выше; как говорится здесь :

... В этом режиме приложения и службы общаются напрямую с Консулом каждый раз, когда они хотят найти другие службы в центре обработки данных .... [Минусы] Требуется использование HTTP API непосредственно в приложении ИЛИ создание DNS запросы и предполагая порт или сделать два DNS-запроса, чтобы найти адрес и порт

Однако, та же ссылка предлагает некоторые альтернативы, которые всегда связаны с посредником. В случае Fabio используется эффективный прямой DNS с привязкой приложения к порту через тег службы консула, а не прямая ссылка приложения на порт [службы].

...