정적 DNS 쿼리 수행

정적 DNS 쿼리 수행

Consul DNS를 사용하여 Consul에 등록된 노드와 서비스를 조회하는 방법을 설명해 드릴게요. 노드 조회와 서비스 조회의 기본적인 쿼리 형식과 결과를 하나씩 살펴보아요.

출처: 문서

본문

이 문서에서는 Consul DNS를 사용하여 Consul에 등록된 노드와 서비스를 조회하는 방법을 설명해요. 준비된 쿼리(prepared queries) 사용에 대한 정보는 동적 DNS 쿼리 수행을 참고해 주세요.

소개

노드 조회와 서비스 조회는 Consul DNS를 사용해 수행할 수 있는 기본적인 쿼리 유형이에요. 노드 조회는 이름이 지정된 Consul 에이전트에 대해 카탈로그를 쿼리해요. 서비스 조회는 Consul에 등록된 서비스에 대해 카탈로그를 쿼리해요. 추가 배경 정보는 DNS 사용 개요를 참고해 주세요.

요구 사항

모든 버전의 Consul은 DNS 조회 기능을 지원해요.

ACL

ACL이 활성화된 경우 필요한 정책과 연결된 토큰을 제시해야 해요. 프로덕션 배포에서는 DNS 쿼리를 위해 별도의 토큰을 사용하는 것을 권장해요. 기본적으로 Consul 에이전트는 우선순위 순서대로 사전 구성된 토큰을 사용하여 DNS 요청을 해결해요:

  1. 에이전트의 기본 토큰
  2. 내장 익명 토큰

다음 표는 ACL이 활성화된 경우 사용 가능한 DNS 조회와 필요한 정책을 설명해요:

Lookup Type Description ACLs Required
*.node.consul Node Consul이 대상 노드에 대한 DNS 요청을 해결할 수 있게 해줌. 예: <target>.node.consul node:read
*.service.consul *.connect.consul *.ingress.consul *.virtual.consul Service: standard Consul이 ACL 인가 노드에서 실행 중인 대상 서비스 인스턴스에 대한 DNS 요청을 해결할 수 있게 해줌. 예: <target>.service.consul service:read node:read

노드 조회

다음 FQDN 구문을 사용하여 노드 이름, 데이터센터, 도메인을 지정해 주세요:

<node>.node[.<datacenter>.dc].<domain>

datacenter 하위 도메인은 선택 사항이에요. 기본적으로 조회는 에이전트의 데이터센터를 쿼리해요.

기본적으로 도메인은 consul이에요. 대체 도메인 사용에 대한 정보는 Consul DNS 동작 구성을 참고해 주세요.

노드 조회 결과

노드 조회는 IP 주소가 포함된 A 및 AAAA 레코드와, 노드의 node_meta 값을 포함하는 TXT 레코드를 반환해요.

기본적으로 TXT 레코드 값은 RFC1464에 따라 노드의 메타데이터 키-값 쌍과 일치해요. 메타데이터 키가 rfc1035-로 시작하면 TXT 레코드는 노드의 메타데이터 값만 포함해요.

다음 예시 조회는 default 데이터센터의 foo 노드를 쿼리해요:

$ dig @127.0.0.1 -p 8600 foo.node.consul ANY
; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 foo.node.consul ANY
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24355
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;foo.node.consul.   IN  ANY

;; ANSWER SECTION:
foo.node.consul.  0 IN  A 10.1.10.12
foo.node.consul.  0 IN  TXT "meta_key=meta_value"
foo.node.consul.  0 IN  TXT "value only"

;; AUTHORITY SECTION:
consul.     0 IN  SOA ns.consul. postmaster.consul. 1392836399 3600 600 86400 0

Consul Enterprise용 노드 조회

Consul Enterprise는 격리된 관리 네트워크 영역을 정의할 수 있는 추상화인 admin 파티션 개념을 포함해요. 자세한 내용은 Admin 파티션을 참고해 주세요.

Consul 노드는 데이터센터 내의 admin 파티션에 위치해요. 기본적으로 노드 조회는 DNS 쿼리를 받은 Consul 에이전트와 동일한 파티션과 데이터센터를 쿼리해요.

노드 조회에 파티션을 지정하려면 다음 쿼리 형식을 사용해 주세요:

<node>.node[.<partition>.ap][.<datacenter>.dc].<domain>

Consul 서버 에이전트는 default 파티션에 있어요. Consul 서버 에이전트에 DNS 쿼리를 보내는 경우 대상 노드의 파티션이 default가 아니라면 명시적으로 지정해야 해요.

서비스 조회

표준 조회 방법이나 엄격한 RFC 2782 조회 방법 중 하나를 사용하여 네트워크의 서비스 제공자를 쿼리할 수 있어요.

기본적으로 모든 SRV 레코드는 서비스 조회 응답에서 동일하게 가중치가 부여되지만, 서비스 정의의 Weights 특성을 사용하여 가중치를 구성할 수 있어요. 자세한 내용은 서비스 정의를 참고해 주세요.

DNS 프로토콜은 DNS TCP 쿼리를 수행할 때에도 요청 크기를 제한하므로 서비스 쿼리에 영향을 줄 수 있어요. 500개 이상의 인스턴스가 있는 서비스의 경우 서비스의 인스턴스 전체 목록을 검색하지 못할 수 있어요. 자세한 내용은 RFC 1035, Domain Names - Implementation and Specification을 참고해 주세요.

Consul은 DNS SRV 레코드를 무작위화하고 응답을 출력할 때 서비스 구성에 지정된 가중치를 무시해요. 레코드가 잘리면 가중 SRV 응답을 사용하는 각 클라이언트가 인스턴스 가중치에 대해 부분적이고 일관되지 않은 보기를 가질 수 있어요. 결과적으로 요청 분포가 의도된 가중치에서 벗어날 수 있어요. 전체 노드 목록을 검색하려면 /catalog/nodes API 엔드포인트를 호출하는 것을 권장해요. API 호출에 쿼리 매개변수를 적용하여 결과를 정렬하고 필터링할 수 있어요.

표준 조회

표준 서비스 조회를 수행하려면 다음 구문을 사용하여 서비스 제공자를 쿼리하기 위해 태그, 서비스 이름, 데이터센터, 클러스터 피어, 도메인을 지정해 주세요:

[<tag>.]<service>.service[.<datacenter>.dc][.<cluster-peer>.peer][.<sameness-group>.sg].<domain>
  • tag 하위 도메인은 선택 사항이에요. 태그가 포함된 서비스 제공자만 나타나도록 응답을 필터링해요.

  • datacenter 하위 도메인은 선택 사항이에요. 기본적으로 Consul은 쿼리하는 에이전트의 데이터센터를 조사해요.

  • cluster-peer 이름은 선택 사항이며, 쿼리의 대상이 되어야 하는 내보낸 서비스를 가진 클러스터 피어를 지정해요.

  • sameness-group 이름은 선택 사항이며, 쿼리의 대상이 되어야 하는 sameness group을 지정해요. Consul이 sameness group에 연결된 서비스에 대한 DNS 요청을 받으면 sameness group의 첫 번째 정상 멤버에서 서비스 인스턴스를 반환해요. 로컬 파티션이 sameness group의 멤버라면 서비스 인스턴스가 sameness group의 멤버보다 우선해요. 선택적으로 sameness group 조회를 수행할 때 네임스페이스 또는 admin 파티션을 포함할 수 있어요. 자세한 내용은 Consul Enterprise용 서비스 조회를 참고해 주세요.

기본적으로 조회는 consul 도메인에서 수행돼요. 대체 도메인 사용에 대한 정보는 Consul DNS 동작 구성을 참고해 주세요.

표준 조회 결과

표준 서비스 쿼리는 A 및 SRV 레코드를 반환해요. SRV 레코드에는 서비스가 등록된 포트가 포함돼요. SRV 레코드는 클라이언트가 명시적으로 요청한 경우에만 제공돼요.

헬스 체크에 실패한 서비스 또는 노드 시스템 체크에 실패한 서비스는 결과에서 제외돼요. 로드 밸런싱 조치로 Consul은 응답에서 반환되는 노드 집합을 무작위화해요. 이러한 메커니즘은 애플리케이션 수준 재시도와 함께 DNS를 사용하여 자가 치유 서비스 지향 아키텍처의 기반으로 삼을 수 있게 해줘요.

다음 예시는 Consul에 등록된 redis 서비스의 SRV 레코드를 검색해요.

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

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

;; QUESTION SECTION:
;consul.service.consul.   IN  SRV

;; ANSWER SECTION:
consul.service.consul.  0 IN  SRV 1 1 8300 foobar.node.dc1.consul.

;; ADDITIONAL SECTION:
foobar.node.dc1.consul. 0 IN  A 10.1.10.12

다음 예시 명령과 FQDN은 보조 데이터센터의 기본(primary) Postgres 서비스에 대한 SRV 레코드를 검색해요:

$ dig @127.0.0.1 -p 8600 primary.postgresql.service.dc2.consul SRV

; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 primary.postgresql.service.dc2.consul ANY
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 50483
;; flags: qr aa rd; QUERY: 1, ANSWER: 3, AUTHORITY: 1, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;consul.service.consul.   IN  SRV

;; ANSWER SECTION:
consul.service.consul.  0 IN  SRV 1 1 5432 primary.postgresql.service.dc2.consul.

;; ADDITIONAL SECTION:
primary.postgresql.service.dc2.consul. 0 IN  A 10.1.10.12

RFC 2782 조회

RFC 2782에 따라 SRV 쿼리는 DNS 충돌을 방지하기 위해 service 및 protocol 값 앞에 밑줄(_)을 붙여야 해요. RFC 2782 조회를 수행하려면 다음 구문을 사용해 주세요:

_<service>._<protocol>[.service][.<datacenter>].<domain>

protocol 필드에 서비스 태그를 배치하여 결과를 필터링하는 조회를 만들 수 있어요. 서비스 태그를 기준으로 결과를 필터링하는 RFC 2782 조회를 만들려면 다음 구문을 사용해 주세요:

_<service>._<tag>[.service][.<datacenter>].<domain>

다음 예시는 amqp 태그가 붙은 rabbitmq 서비스를 쿼리하며, 포트 5672의 rabbitmq.node1.dc1.consul에서 인스턴스를 반환해요:

$ dig @127.0.0.1 -p 8600 _rabbitmq._amqp.service.consul SRV
; <<>> DiG 9.8.3-P1 <<>> @127.0.0.1 -p 8600 _rabbitmq._amqp.service.consul ANY
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 52838
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;_rabbitmq._amqp.service.consul.  IN  SRV

;; ANSWER SECTION:
_rabbitmq._amqp.service.consul. 0 IN  SRV 1 1 5672 rabbitmq.node1.dc1.consul.

;; ADDITIONAL SECTION:
rabbitmq.node1.dc1.consul.  0 IN  A 10.1.11.20

쿼리 레이블에 <datacenter>.dc 또는 <cluster-peer>.peer를 포함하여 특정 클러스터 피어 또는 데이터센터를 대상으로 하는 RFC 2782 조회를 수행할 수도 있어요:

_<service>._<tag>[.service][.<datacenter>.dc][.<cluster-peer>.peer].<domain>

다음 예시는 클러스터 피어 phx1에 대해 tcp 태그가 붙은 redis 서비스를 쿼리하며, 하나는 10.1.11.83:29081, 다른 하나는 10.1.11.86:29142에 있는 두 개의 인스턴스를 반환해요:

$ dig @127.0.0.1 -p 8600 _redis._tcp.service.phx1.peer.consul SRV
; <<>> DiG 9.18.15 <<>> @127.0.0.1 -p 8600 _redis._tcp.service.phx1.peer.consul SRV
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 40572
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 2

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;_redis._tcp.service.phx1.peer.consul.  IN SRV

;; ANSWER SECTION:
_redis._tcp.service.phx1.peer.consul. 0 IN SRV 1 1 29081 0a000d53.addr.consul.
_redis._tcp.service.phx1.peer.consul. 0 IN SRV 1 1 29142 0a010d56.addr.consul.

;; ADDITIONAL SECTION:
0a000d53.addr.consul. 0 IN  A 10.1.11.83
0a010d56.addr.consul. 0 IN  A 10.1.11.86

.addr 하위 도메인의 호스트에 대한 SRV 응답

Consul에 등록된 서비스가 address 또는 tagged_address 매개변수에 명시적 IP 주소로 구성된 경우, Consul은 다음 형식에 따라 DNS SRV 쿼리의 응답 섹션 target 필드에 호스트 이름을 반환해요:

<hexadecimal-encoded IP>.addr.<datacenter>.consul.

다음 예시에서 rabbitmq 서비스는 명시적 IPv4 주소 192.0.2.10으로 등록돼요.

HCL / JSON

node_name = "node1"

services {
  name = "rabbitmq"
  address = "192.0.2.10"
  port = 5672
}
{
  "node_name": "node1",
  "services": [
    {
      "name": "rabbitmq",
      "address": "192.0.2.10",
      "port": 5672
    }
  ]
}

다음 예시 SRV 쿼리 응답은 16진수 값으로 작성된 호스트 이름을 가진 단일 레코드를 포함해요:

$ dig @127.0.0.1 -p 8600 -t srv _rabbitmq._tcp.service.consul +short
1 1 5672 c000020a.addr.dc1.consul.

16진수 옥텟을 10진수로 변환하여 IP 주소를 드러낼 수 있어요. 다음 예시 명령은 c000020a로 표현된 호스트 이름을 서비스 등록에 지정된 IPv4 주소로 변환해요.

$ echo -n "c000020a" | perl -ne 'printf("%vd\n", pack("H*", $_))'
192.0.2.10

다음 예시에서 rabbitmq 서비스는 명시적 IPv6 주소 2001:db8:1:2:cafe::1337으로 등록돼요.

HCL / JSON

node_name = "node1"

services {
  name = "rabbitmq"
  address = "2001:db8:1:2:cafe::1337"
  port = 5672
}
{
  "node_name": "node1",
  "services": [
    {
      "name": "rabbitmq",
      "address": "2001:db8:1:2:cafe::1337",
      "port": 5672
    }
  ]
}

다음 예시 SRV 쿼리 응답은 16진수 값으로 작성된 호스트 이름을 가진 단일 레코드를 포함해요.

$ dig @127.0.0.1 -p 8600 -t SRV _rabbitmq._tcp.service.consul +short
1 1 5672 20010db800010002cafe000000001337.addr.dc1.consul.

응답에는 콜론 구분자가 제거된 완전히 확장된 IPv6 주소가 포함돼요. 다음 명령은 서비스 등록에 지정된 완전히 확장된 IPv6 주소를 표시하기 위해 콜론 구분자를 다시 추가해요.

$ echo -n "20010db800010002cafe000000001337" | perl -ne 'printf join(":", unpack("(A4)*", $_))."\n"'
2001:0db8:0001:0002:cafe:0000:0000:1337

Consul Enterprise용 서비스 조회

다른 네임스페이스, 파티션, 데이터센터의 서비스를 쿼리하려면 다음 유형의 서비스 조회를 수행할 수 있어요:

  • .service
  • .connect
  • .virtual
  • .ingress

네임스페이스, 파티션 또는 데이터센터를 지정하려면 다음 쿼리 형식을 사용해 주세요:

[<tag>.]<service>.service[.<namespace>.ns][.<partition>.ap][.<datacenter>.dc]<domain>

namespace, partition, datacenter는 선택 사항이에요. 기본적으로 모든 서비스 조회는 DNS 쿼리를 받은 Consul 에이전트의 파티션 및 데이터센터 내 default 네임스페이스를 사용해요.

Consul 서버 에이전트는 default 파티션에 있어요. DNS 쿼리가 Consul 서버 에이전트로 지정된 경우 default 외 파티션의 서비스를 쿼리할 때 대상 서비스의 파티션을 명시적으로 지정해야 해요.

클러스터 피어에서 가져온(imported) 서비스를 조회하려면 Consul Enterprise용 서비스 가상 IP 조회를 참고해 주세요.

네임스페이스 지정을 위한 대체 형식

가독성을 위해 Consul Enterprise용 서비스 조회에 설명된 형식을 권장하지만, 파티션은 지정하지 않고 네임스페이스만 지정하는 대체 쿼리 형식을 사용할 수 있어요:

[<tag>.]<service>.service.<namespace>.<datacenter>.<domain>

서비스 메시 활성화 서비스 조회

.connect 하위 도메인을 추가하여 서비스 메시 활성화 서비스를 쿼리해 주세요:

<service>.connect.<domain>

이것은 서비스에 대해 서비스 메시 지원 엔드포인트를 모두 찾아요. 서비스 메시 지원 엔드포인트는 서비스의 프록시이거나 네이티브로 통합된 서비스 메시 애플리케이션일 수 있어요. DNS 인터페이스는 둘을 구분하지 않아요.

많은 서비스가 서비스 디스커버리를 자동으로 처리하는 프록시를 사용해요. 결과적으로 주로 서비스 메시 네이티브 애플리케이션을 위한 DNS 형식을 사용하지 않을 수 있어요. 이 엔드포인트는 동일한 데이터센터 내의 서비스만 찾으며 태그를 지원하지 않아요. 더 복잡한 동작은 카탈로그 API 엔드포인트를 참고해 주세요.

서비스 가상 IP 조회

쿼리에 .virtual 하위 도메인을 추가하여 서비스에 할당된 고유 가상 IP를 찾아 주세요:

[<port-name>.]<service>.virtual[.<peer>].<domain>

이것은 서비스 메시 지원 서비스의 고유 가상 IP를 반환해요. 각 서비스 메시 서비스에는 Consul이 할당한 가상 IP가 있어요. 사이드카 프록시는 가상 IP를 사용하여 투명 프록시 기능을 활성화해요. 다중 포트 서비스의 경우 서비스 이름 앞에 명명된 포트를 추가하여 해당 특정 포트의 가상 IP를 해결해 주세요. 포트 이름을 생략하면 Consul은 서비스의 기본 가상 IP를 반환해요.

피어 이름은 선택 사항이에요. DNS는 이를 사용하여 지정된 피어에서 가져온 서비스의 가상 IP를 쿼리해요.

Consul은 서비스 정의의 tagged_addresses 필드에 consul-virtual 태그 아래에 가상 IP를 추가해요.

Consul Enterprise용 서비스 가상 IP 조회

기본적으로 서비스 가상 IP 조회는 DNS 쿼리를 받은 Consul 에이전트의 파티션 및 데이터센터 내 default 네임스페이스를 확인해요. 쿼리하는 클러스터 또는 오픈 소스 데이터센터에 피어링된 다른 클러스터의 파티션에서 가져온 서비스를 조회하려면 조회에 네임스페이스와 피어 이름을 지정해 주세요:

<service>.virtual[.<namespace>].<peer>.<domain>

예를 들어 다음 조회는 api 서비스의 http 포트에 대한 가상 IP를 반환해요:

http.api.virtual.consul

클러스터 피어에서 가져오지 않은 서비스를 조회하려면 Consul Enterprise용 서비스 조회를 참고해 주세요.

Consul 서비스 메시 다중 포트 서비스용 서비스 가상 IP 조회

다중 포트 서비스의 경우 Consul은 <port-name>.<service-name>.virtual.consul 명명 규칙에 따라 서비스 이름과 포트 이름을 기반으로 가상 DNS 항목을 생성해요. Consul의 내부 DNS는 해당 특정 서비스-포트 조합에 고유한 Virtual IP(VIP)를 반환해요.

예를 들어 http와 grpc라는 두 포트가 있는 api라는 서비스가 있으면 가상 DNS 항목은 http.api.virtual.consul 및 grpc.api.virtual.consul이 돼요.

다중 포트 서비스에 대한 자세한 내용은 다중 포트 문서를 참고해 주세요.

인그레스 서비스 조회

DNS FQDN에 .ingress 하위 도메인을 추가하여 인그레스 활성화 서비스를 찾아 주세요:

<service>.ingress.<domain>

이것은 서비스의 모든 인그레스 게이트웨이 엔드포인트를 찾아요.

이 엔드포인트는 동일한 데이터센터 내의 서비스를 찾으며 태그를 지원하지 않아요. 더 복잡한 동작은 카탈로그 API 엔드포인트를 참고해 주세요.

UDP 기반 DNS 쿼리

DNS 쿼리가 UDP를 사용하여 수행되면 Consul은 잘림(truncate) 비트를 설정하지 않고 결과를 잘라내요. 이는 추가 부하를 발생시키는 TCP를 통한 중복 조회를 방지해요. 조회가 TCP로 수행되면 결과가 잘리지 않아요.

더 알아보기 (Learn more)