HashiCorp Consul 마스터 노트 시리즈 3편. 서비스 등록의 두 방법(파일·HTTP API), DNS 8600 포트로 이름 조회, 헬스 체크 7종(Script·HTTP·TCP·gRPC·Docker·TTL·Alias)의 결정적 차이, 태그·메타데이터 활용, prepared query까지 — 시험 Objective 3 핵심.
이 글은 HashiCorp Consul 마스터 노트 시리즈의 세 번째 편입니다. 2편(배포)에서 클러스터 띄우는 법을 잡았다면, 이번엔 그 클러스터 위에 서비스를 등록하고 찾는 방법 — Objective 3.
서비스 디스커버리는 Consul의 가장 자주 쓰는 기능. 등록·조회·헬스 체크 세 단계를 정확히 익히면 마이크로서비스 간 동적 연결이 정리돼요.
서비스 등록 — 두 가지 방법
1. 구성 파일
# /etc/consul.d/web.hcl
service {
name = "web"
port = 8080
tags = ["v1", "primary"]
meta {
version = "1.2.3"
team = "frontend"
}
check {
id = "web-http"
name = "HTTP Health Check"
http = "http://localhost:8080/health"
method = "GET"
interval = "10s"
timeout = "1s"
}
}
# 등록
consul services register /etc/consul.d/web.hcl
# 또는 에이전트 시작 시 자동 등록 (config-dir에 있으면)
sudo systemctl restart consul
2. HTTP API
curl --request PUT \
--data @web.json \
http://localhost:8500/v1/agent/service/register
{
"Name": "web",
"Port": 8080,
"Tags": ["v1", "primary"],
"Check": {
"HTTP": "http://localhost:8080/health",
"Interval": "10s"
}
}
여기서 시험 함정이 하나 있어요. 에이전트가 등록된 서비스의 책임을 가짐. 노드 다운 시 그 노드의 서비스도 자동 비활성. 다른 노드에서 같은 서비스 = 다른 인스턴스로 인식.
서비스 조회 — 두 가지 방법
1. DNS (포트 8600)
dig @127.0.0.1 -p 8600 web.service.consul
# 출력:
# web.service.consul. 0 IN A 10.0.1.20
# web.service.consul. 0 IN A 10.0.1.21
기본 형식 — <service>.service.consul.
# 데이터센터 명시
dig @127.0.0.1 -p 8600 web.service.dc2.consul
# 태그 필터
dig @127.0.0.1 -p 8600 v1.web.service.consul
# SRV 레코드 (포트 포함)
dig @127.0.0.1 -p 8600 -t SRV web.service.consul
2. HTTP API
# 카탈로그 조회 (모든 인스턴스, 헬스 무관)
curl http://localhost:8500/v1/catalog/service/web
# 헬스 체크 통과한 인스턴스만
curl http://localhost:8500/v1/health/service/web?passing
여기서 정말 중요한 시험 함정 — /catalog/service는 모든 인스턴스, /health/service?passing은 통과한 것만. 운영 트래픽 라우팅엔 항상 passing 필터.
DNS 통합
호스트 OS DNS 위임
*.consul 쿼리만 Consul로.
# /etc/resolv.conf 위에 추가
nameserver 127.0.0.1
options ndots:5
또는 systemd-resolved/dnsmasq로 위임. web.service.consul 같은 이름을 직접 사용 가능 — 코드 수정 X.
짧은 이름 (alt_domain)
# /etc/consul.d/consul.hcl
domain = "internal" # 기본 .consul 대신 .internal
alt_domain = "example.com" # 추가 도메인
이러면 web.service.example.com 으로도 조회 가능.
헬스 체크 7종 — 시험 단골
1. HTTP
check {
http = "http://localhost:8080/health"
method = "GET" # 기본 GET
interval = "10s"
timeout = "1s"
# 상태 코드: 200~299 = passing, 429 = warning, 그 외 = critical
}
2. TCP
check {
tcp = "localhost:5432"
interval = "10s"
timeout = "1s"
}
연결 성공 = passing.
3. gRPC
check {
grpc = "localhost:9000"
grpc_use_tls = true
interval = "10s"
}
gRPC Health Checking 프로토콜.
4. Script
check {
args = ["/usr/local/bin/check_service.sh"]
interval = "30s"
timeout = "5s"
}
스크립트 종료 코드 — 0=passing, 1=warning, 2=critical.
여기서 시험 함정이 하나 있어요. Script 체크는 보안 위험입니다. 임의 명령 실행 가능. enable_script_checks = false가 기본 — 의식적으로 활성 필요.
# 보안 강화
enable_local_script_checks = true # 로컬 정의만
# enable_script_checks = true # API로도 등록 가능 (위험)
5. Docker
check {
docker_container_id = "abc123..."
shell = "/bin/bash"
args = ["health_check.sh"]
interval = "10s"
}
컨테이너 안에서 명령 실행.
6. TTL
check {
ttl = "30s"
notes = "App pings periodically"
}
애플리케이션이 직접 PASS/FAIL을 푸시. TTL 안 갱신되면 자동 critical.
# 애플리케이션이 주기적으로 호출
curl http://localhost:8500/v1/agent/check/pass/<check-id>
curl http://localhost:8500/v1/agent/check/warn/<check-id>
curl http://localhost:8500/v1/agent/check/fail/<check-id>
7. Alias
check {
alias_service = "redis" # 다른 서비스 헬스 따라감
}
다른 서비스 상태를 그대로 따라감. 의존 서비스 함께 체크할 때.
7종 비교
| 종류 | 동작 | 적합 |
|---|---|---|
| HTTP | 엔드포인트 GET/POST | 웹 앱·API |
| TCP | 포트 연결 | DB·미들웨어 |
| gRPC | gRPC Health 프로토콜 | gRPC 서비스 |
| Script | 스크립트 실행 | 복잡 로직 (보안 주의) |
| Docker | 컨테이너 안 명령 | Docker 환경 |
| TTL | 앱이 푸시 | 외부 체크 어려운 자리 |
| Alias | 다른 서비스 따라감 | 의존 서비스 |
여기서 정말 중요한 시험 함정 — TTL 체크는 앱이 능동 푸시. 푸시 멈추면 자동 critical. 다른 모든 체크는 Consul이 능동 호출.
헬스 체크 상태 3종
| 상태 | 의미 | 트래픽 |
|---|---|---|
| passing | 정상 | 받음 |
| warning | 경고 | 받음 (기본) |
| critical | 비정상 | 받지 않음 |
curl http://localhost:8500/v1/health/service/web?passing
# passing만 (warning·critical 제외)
curl http://localhost:8500/v1/health/service/web
# 모두
태그 (Tags)
서비스 분류·필터링.
service {
name = "web"
tags = ["v1", "primary", "production"]
}
태그로 DNS 조회
# v1 태그 가진 web 인스턴스만
dig @127.0.0.1 -p 8600 v1.web.service.consul
태그 활용
- 버전 분리 —
v1,v2 - 환경 —
production,staging - 역할 —
primary,replica
메타데이터 (Meta)
태그보다 풍부한 키-값 정보.
service {
name = "web"
meta {
version = "1.2.3"
team = "frontend"
deploy_at = "2026-05-03"
}
}
DNS 조회는 X (HTTP API로만).
Prepared Query — 고급 라우팅
복잡한 조회 룰을 미리 정의.
curl --request POST \
--data @prepared-query.json \
http://localhost:8500/v1/query
{
"Name": "web-failover",
"Service": {
"Service": "web",
"Failover": {
"NearestN": 3,
"Datacenters": ["dc2", "dc3"]
},
"OnlyPassing": true
}
}
특징:
- 자동 페일오버 (다른 DC로)
- 가까운 DC 우선
- 태그 필터링·메타 매칭
CLI vs DNS vs API
# CLI
consul catalog services
consul catalog nodes -service=web
# DNS
dig @127.0.0.1 -p 8600 web.service.consul
# HTTP API
curl http://localhost:8500/v1/catalog/services
curl http://localhost:8500/v1/health/service/web?passing
일반적 패턴
클라이언트 코드에서 사용
# Python — DNS 사용 (가장 단순)
import socket
ip = socket.gethostbyname('redis.service.consul')
# 자동으로 헬스 통과한 인스턴스 중 하나
# 또는 HTTP API
import requests
response = requests.get('http://localhost:8500/v1/health/service/redis?passing')
instances = response.json()
chosen = instances[0]
host = chosen['Service']['Address']
port = chosen['Service']['Port']
Consul Template
설정 파일 자동 갱신.
# nginx.conf.tpl
upstream backend {
{{ range service "backend|passing" }}
server {{ .Address }}:{{ .Port }};
{{ end }}
}
서비스 변경 시 nginx config 자동 갱신·reload.
시험 직전 한 번 더 — 자주 헷갈리는 함정 모음
여기까지가 3편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.
- 서비스 등록 2가지 — HCL 파일 / HTTP API PUT
- 등록은 에이전트 책임 — 노드 다운 시 자동 비활성
- 조회 2가지 — DNS (8600) / HTTP API
- DNS 형식 —
<service>.service.consul/<tag>.<service>.service.consul /catalog/service= 모든 인스턴스/health/service?passing= 통과만 (운영 트래픽 표준)- 헬스 체크 7종 — HTTP / TCP / gRPC / Script / Docker / TTL / Alias
- HTTP — 200~299 passing / 429 warning / 그 외 critical
- TCP — 연결 성공 = passing
- Script 보안 주의 —
enable_local_script_checks권장 (enable_script_checks위험) - TTL 체크 = 앱이 능동 푸시 (다른 체크는 Consul이 호출)
- TTL 푸시 멈추면 자동 critical
- Alias = 다른 서비스 헬스 따라감
- 헬스 상태 — passing / warning / critical
- warning은 기본 트래픽 받음
- 태그 =
tags = ["v1", "primary"]/ DNS 필터 가능 - 메타 = 풍부한 KV / DNS X (API만)
- Prepared Query = 페일오버·가까운 DC·태그 매칭
- DNS 위임 —
*.consul만 Consul로 domain/alt_domain으로 짧은 이름- Consul Template = 설정 파일 자동 갱신
시리즈 다른 편
- 1편 — Consul 입문
- 2편 — 단일 DC 배포
- 3편 — Service Discovery (현재 글)
- 4편 — Key/Value 저장소
- 5편 — 백업 & 복구
- 6편 — Service Mesh (Connect)
- 7편 — 보안 운영
공식 문서: Consul Service Discovery에서 더 깊이.
다음 글(4편)에서는 KV 저장소 — CLI/HTTP API/UI 3가지 접근, prefix 기반 권한, watch·envconsul·consul-template 통합까지 풀어 갑니다.