HashiCorp Consul 마스터 노트 시리즈 6편. Service Mesh의 본질 — 사이드카 프록시 패턴, mTLS 자동 암호화·상호 인증, 업스트림 vs 다운스트림, Intentions로 서비스 간 접근 제어, Envoy 프록시 통합과 등록 vs 시작의 차이까지 — Objective 6 완전 정리.
이 글은 HashiCorp Consul 마스터 노트 시리즈의 여섯 번째 편입니다. 3편(Service Discovery)이 "어떤 서비스가 어디에 있는가"였다면, 6편은 그 서비스들이 어떻게 안전하게 통신하는가 — Service Mesh, Consul에서는 Connect.
마이크로서비스가 늘어날수록 IP 기반 방화벽으로는 통제 불가능해져요. 서비스 메시는 이 문제의 표준 해법.
Service Mesh의 본질
해결하는 5가지 문제:
- 서비스 간 통신 암호화 (기본 평문)
- 동적 환경의 IP 기반 방화벽 한계
- 서비스 신원 확인 (인증)
- 세밀한 접근 제어 (인가)
- 트래픽 가시성 (Observability)
핵심 특징
- 제로 트러스트 — 내부 네트워크도 신뢰 X
- mTLS — 모든 서비스 간 암호화 + 상호 인증
- 사이드카 프록시 — 애플리케이션 코드 수정 X
- 플랫폼 무관 — 물리·클라우드·Kubernetes 모두
- Intentions — 서비스 간 통신 허용/거부 정책
Connect 활성화
# /etc/consul.d/consul.hcl
connect {
enabled = true
}
sudo systemctl restart consul
여기서 시험 함정이 하나 있어요. Connect는 기본 비활성. 명시 활성 + 재시작 필요. Dev 모드만 자동 활성.
consul agent -dev # Connect 자동 활성
사이드카 프록시 패턴
┌─────────────────────────────────────────────────────────┐
│ 노드 A │
│ ┌──────────────┐ ┌─────────────────────────┐ │
│ │ Application │────▶│ Sidecar Proxy (Envoy) │ │
│ │ (localhost) │◀────│ (mTLS, 정책 강제) │ │
│ └──────────────┘ └────────────┬────────────┘ │
└──────────────────────────────────────│──────────────────┘
│ mTLS 암호화
▼
┌─────────────────────────────────────────────────────────┐
│ 노드 B │
│ ┌─────────────────────────┐ ┌──────────────┐ │
│ │ Sidecar Proxy (Envoy) │────▶│ Application │ │
│ │ (mTLS, 정책 강제) │◀────│ (localhost) │ │
│ └─────────────────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
핵심 — 앱은 localhost로 프록시와 통신, 프록시가 mTLS 암호/복호화 + 정책 강제. 앱은 Consul 존재 모름.
Upstream vs Downstream
| 용어 | 역할 | 예시 |
|---|---|---|
| Upstream | 의존하는 대상 | DB, API 서버 |
| Downstream | 대상에 의존 | 프론트엔드, 웹 |
"프론트엔드(downstream)가 DB(upstream)에 의존".
서비스 + 프록시 등록
기본 사이드카
service {
name = "counting"
port = 9003
connect {
sidecar_service {} # 빈 블록 = 내장 프록시
}
}
Upstream 포함
service {
name = "dashboard"
port = 9002
connect {
sidecar_service {
proxy {
upstreams = [
{
destination_name = "counting"
local_bind_port = 5000 # localhost:5000으로 접근
}
]
}
}
}
}
의미 — dashboard는 localhost:5000으로 counting에 접근. 프록시가 mTLS 터널로 전달.
여러 Upstream
service {
name = "frontend"
port = 8080
connect {
sidecar_service {
proxy {
upstreams = [
{ destination_name = "backend-api", local_bind_port = 5001 },
{ destination_name = "database", local_bind_port = 5002 }
]
}
}
}
}
등록 vs 시작은 별개
여기서 정말 중요한 시험 함정 — 등록만으로 프록시 시작 X.
# 1. 서비스 등록 (Consul에 알림)
consul services register /etc/consul.d/counting.hcl
consul services register /etc/consul.d/dashboard.hcl
# 2. 실제 앱 시작
./counting-service &
./dashboard-service &
# 3. 사이드카 프록시 시작 (별도)
consul connect proxy -sidecar-for counting &
consul connect proxy -sidecar-for dashboard &
운영에서는 systemd로 프록시도 관리.
mTLS와 인증서
동작 흐름
1. 서비스 A 프록시 → 서비스 B 프록시 연결 시도
2. 두 프록시가 CA 발급 mTLS 인증서 교환
3. 상호 인증 완료 → 암호화 채널
4. 서비스 B 프록시 → Consul API 인텐션 검사
5. 허용이면 연결 / 거부면 차단
CA 옵션
# 기본: Connect 내장 CA
connect {
enabled = true
# ca_provider = "consul" # 기본
}
# Vault CA 사용
connect {
enabled = true
ca_provider = "vault"
ca_config {
address = "https://vault.example.com:8200"
token = "<VAULT_TOKEN>"
root_pki_path = "connect-root"
intermediate_pki_path = "connect-intermediate"
}
}
Intentions — 서비스 간 접근 제어
서비스 간 누가 누구에게 통신 가능한지 정의.
CLI 관리
# 허용
consul intention create web db
consul intention create dashboard counting
# 거부
consul intention create -deny web payment
# 모든 서비스 리스트 반환
consul intention list
# 매치 확인
consul intention check web db
# Allowed
와일드카드
# 모든 서비스가 web에 접근 허용
consul intention create '*' web
# 모든 web → 모든 다른 서비스 거부 (안전한 기본값)
consul intention create -deny web '*'
우선순위
1. 명시적 source/destination 매치
2. * 와일드카드보다 정확한 룰 우선
3. 충돌 시 deny 우선
여기서 정말 중요한 시험 함정 — Intentions 기본 정책:
- default_policy = "deny" (ACL 활성·default deny일 때) — 명시 허용만 통신
- default_policy = "allow" (또는 ACL 비활성) — 명시 거부만 차단
운영 = deny가 기본 (제로 트러스트).
L4 vs L7 Intentions
| 종류 | 적용 |
|---|---|
| L4 (기본) | 서비스 단위 허용/거부 |
| L7 (Enterprise) | HTTP path·method·header 단위 |
Associate 시험은 주로 L4.
DNS로 Connect 서비스 조회
# Connect 서비스 IP·포트
dig @127.0.0.1 -p 8600 counting.connect.consul
기본 service.consul이 아니라 connect.consul 도메인 — Connect 활성 서비스만.
Envoy 통합
Envoy를 사이드카로
# Consul 내장 프록시 대신 Envoy
consul connect envoy -sidecar-for counting
Envoy = 프로덕션 표준. 내장 프록시는 단순 사용·테스트.
Envoy 메트릭
# Prometheus 형식 메트릭 노출
curl http://localhost:19000/stats/prometheus
요청 수·지연·에러율·연결 풀 — 모든 트래픽 가시성.
Service Identity
Connect 사용 서비스는 자동 X.509 인증서 부여.
spiffe://<trust-domain>/ns/<namespace>/dc/<datacenter>/svc/<service>
예: spiffe://example.consul/ns/default/dc/dc1/svc/web.
이 신원으로 Intentions 정책 적용.
Ingress / Terminating Gateway (간단)
| Gateway | 역할 |
|---|---|
| Ingress | 외부 → Mesh 안 (인입 게이트웨이) |
| Terminating | Mesh 안 → 외부 서비스 (메시 외 시스템) |
| Mesh Gateway | 다른 DC와 통신 |
복잡한 토폴로지에서 사용. Associate는 개념 정도.
실습 — 단순 데모
# 1. counting 서비스 (포트 9003)
cat > /etc/consul.d/counting.hcl <<EOF
service {
name = "counting"
port = 9003
connect { sidecar_service {} }
}
EOF
# 2. dashboard 서비스 (counting upstream)
cat > /etc/consul.d/dashboard.hcl <<EOF
service {
name = "dashboard"
port = 9002
connect {
sidecar_service {
proxy {
upstreams = [{ destination_name = "counting", local_bind_port = 5000 }]
}
}
}
}
EOF
# 3. 등록
consul services register /etc/consul.d/counting.hcl
consul services register /etc/consul.d/dashboard.hcl
# 4. 앱 시작
./counting-service &
./dashboard-service &
# 5. 프록시 시작
consul connect proxy -sidecar-for counting &
consul connect proxy -sidecar-for dashboard &
# 6. Intention 허용
consul intention create dashboard counting
# 7. 테스트
curl http://localhost:9002 # dashboard UI에서 counting 표시
시험 직전 한 번 더 — 자주 헷갈리는 함정 모음
여기까지가 6편의 핵심입니다. 시험 직전 또는 실무에서 헷갈릴 때 다시 펼쳐 볼 수 있게 압축 노트로 마무리할게요.
- Service Mesh = 사이드카 프록시 + mTLS + Intentions
- Consul Connect = HashiCorp의 Service Mesh 구현
- 5가지 문제 — 암호화·IP 한계·인증·인가·가시성
- 제로 트러스트 = 내부도 신뢰 X
- Connect 기본 비활성 —
connect { enabled = true }명시 - Dev 모드만 자동 활성
- 사이드카 패턴 — 앱 ↔ 프록시 (localhost) ↔ mTLS ↔ 다른 프록시 ↔ 앱
- 앱은 Consul 존재 모름 — 코드 수정 X
- Upstream (의존 대상) / Downstream (의존하는 측)
- 서비스 등록 =
sidecar_service {}빈 블록 - Upstream 정의 =
local_bind_port로 localhost 접근 - 등록과 프록시 시작은 별개 — 시험 단골
consul connect proxy -sidecar-for <service>별도 실행- mTLS = 인증서 교환 + 상호 인증 + 암호화
- CA — 내장 / Vault / 외부
- Intentions = 서비스 간 접근 제어
- 와일드카드
*— 모든 서비스 - 충돌 시 deny 우선
- ACL deny 정책 = 명시 허용만 통신 (제로 트러스트)
- L4 (서비스 단위) / L7 (Enterprise)
- DNS =
<service>.connect.consul - Envoy = 프로덕션 표준 프록시
- 내장 프록시는 단순용
- Service Identity = SPIFFE URI 기반 X.509
- Gateway 3종 — Ingress / Terminating / Mesh
시리즈 다른 편
- 1편 — Consul 입문
- 2편 — 단일 DC 배포
- 3편 — Service Discovery
- 4편 — KV Store
- 5편 — 백업 & 복구
- 6편 — Service Mesh (현재 글)
- 7편 — 보안 운영
공식 문서: Consul Connect에서 더 깊이.
다음 글(7편 완결)에서는 보안 운영 — TLS 인증서 (verify_incoming/outgoing/server_hostname), ACL 시스템, Gossip 암호화·키 로테이션까지 — Objective 7·8·9 정리.