DB 연결의 Istio Egress 경유 제외 구성 제안 excludeOutboundPorts 채택 타당성 검토
istio-egressgateway로 DB 연결을 관리하는 방안에 대한 타당성 검증·조사 결과,
DB 트래픽은 sidecar 인터셉트에서 제외(excludeOutboundPorts)하고
기존 3층 통제로 관리할 것을 제안합니다.
상태 검토 완료 · 2026-08-03작성 2026-08 · Platform/DevOps결론 exclude 채택 — 직접 연결
범위 k8s 앱 → 사내 DB 연결 경로범위 외 외부 HTTPS egress 체계 (유지·확장)
본문의 모든 외부 주장에 근거 등급을 부착함 —공식벤더발표커뮤니티규제사내
Part 01
요약 — 결론과 핵심 논거
결론
k8s 앱의 사내 DB 연결은 sidecar → istio-egressgateway 경유 구성을 채택하지 않고,
traffic.sidecar.istio.io/excludeOutboundPorts로 DB 포트를 sidecar 인터셉트에서 제외하여
앱이 DB에 직접 연결하도록 구성함. 통제는 기존 3층 — ① 존 경계 방화벽,
② Calico egress NetworkPolicy, ③ DB 계정·TLS·접속기록 — 이 담당하며,
이 3층은 egress gateway 방식을 채택하더라도 어차피 필요한 기반임(4.1절).
핵심 논거 3가지
① DNS: 조정 불가한 사내 TTL=1 표준과 mesh의 상시 폴링 구조가 충돌함.
DB 도메인 TTL=1초는 failover 즉각 대응을 위한 사내 표준으로 플랫폼에서 조정할 수 없고 준수 대상임
사내. mesh 경유(ServiceEntry resolution: DNS) 시 스코프 내
모든 프록시(sidecar 포함)가 트래픽 유무와 무관하게 1초마다 재질의하며, 이 부하는 nodelocaldns를
거쳐도 소거되지 않고 사내 DNS(paydns)에 상시 부하로 수렴함 — 장애 유발 요인이 됨.
exclude 채택 시 이 문제군은 원천적으로 존재하지 않음. → 3.1절
② TCP: 장수명 DB 커넥션을 프록시 홉에 태우면 세션 수명주기 리스크가 생김.
gateway 재시작·업그레이드·scale-in은 해당 파드가 들고 있던 전체 DB 커넥션의 강제 재수립 이벤트가 되고
(장수명 TCP는 drain으로 살릴 수 없음), 전 앱의 커넥션이 소수 파드에 수렴(chokepoint)하며,
Envoy idle timeout 등 관리 층이 중첩됨. → 3.2절
③ 업계 표준·레퍼런스가 직접 연결 + 정책 통제 모델을 지목함.
Istio 공식 문서 스스로 "egress gateway 경유 강제는 NetworkPolicy·방화벽이 담당해야 한다"고 명시하고
공식, PCI 계열 3대 클라우드 레퍼런스는 세그먼테이션 수단으로 NetworkPolicy를
지목하며 벤더, mesh 벤더 자신이 DB 포트를 특별취급해 왔음
공식. Istio를 전면 운영하는 토스의 공개된 DB 연결 구조도 도메인 → VIP
직접 연결이며 DB 경로에 mesh 장치가 개입하는 서술은 공개 자료에 없음
발표. → 4절
그림 1 · 검토안(경유)과 제안안(직접 연결)의 경로·통제 비교
※ 본 제안은 DB 연결에 한정됨. 외부 HTTPS 통신(Squid 경유)의 egress gateway 체계 —
ISTIO_MUTUAL·SPIFFE 기반 워크로드 인가 — 는 구성·테스트·검증이 완료된 별개 체계로 유지·확장 대상임(2.1절).
Part 02
배경 — 현행 구성·기본 개념·사내 제약
2.1현행 구성과 이번 결정의 범위
현행(외부 HTTPS 통신): istio-egressgateway 기반 외부 통신 집약 구조의
구성·테스트·검증을 완료함. sidecar ↔ egressgateway 구간은 ISTIO_MUTUAL mTLS로 구성해
SPIFFE(Secure Production Identity Framework for Everyone — 워크로드에 암호학적 신원을 부여하는 표준)
기반으로 소스 워크로드를 확인하며, 외부 목적지는 사내 Squid를 경유함. ServiceEntry는 TCP로 등록하고
도메인의 VIP 대응은 istio proxy DNS(DNS proxying)로 처리함.
이번 결정의 성격: 후속 과제로 "DB 연결(MySQL·PostgreSQL·MongoDB·OpenSearch 등)도
istio-egressgateway로 관리하는 방안"에 대한 타당성 검증·조사를 수행했고, 본 문서는 그 결과임.
결론의 방향: 조사 결과, DB 연결은 egress gateway 관리 대상에 포함하지 않고
sidecar 인터셉트에서 제외(exclude)하는 것이 타당하다고 판단함. 근거는 3·4절, 구성안은 5절에 기술함.
2.2배경지식 — 앱은 DB에 어떻게 연결되어 있는가
이후 분석의 전제가 되는 기본 모델임. DB 연결은 HTTP 요청과 근본적으로 다른 성질을 가짐.
항목
내용
연결 수립 비용
DNS 조회 → TCP 3-way handshake → (TLS) → DB 프로토콜 인증. 왕복 다수·수~수십 ms 소요, DB 측도 세션당 자원 소모함
Connection Pool
이 비용 때문에 앱은 연결 N개를 미리 열어 재사용함(borrow → query → return). 연결은 수 시간 유지되는 장수명 TCP임
DNS 소비 시점
연결을 새로 만들 때만 조회함. 기존 연결은 IP에 이미 붙어 있어 TTL과 무관함
TTL(Time To Live)의 의미
"failover 후 신규 연결이 얼마나 빨리 새 IP를 보는가"를 결정함. TTL=1 = 신규 연결이 항상 최신 레코드를 봄
failover 시 흐름
기존 연결 에러 감지(socketTimeout·validation) → pool이 폐기 → 신규 연결 생성 → 이때 DNS가 새 primary를 가리키면 복구됨
표 1 — 앱 ↔ DB 연결의 기본 모델
핵심: 직접 연결 모델에서 DNS 질의는 on-demand(연결 생성 시점)로만 발생함.
pool 안정 상태(예: pool 20 × maxLifetime 30분)의 질의량은 앱당 시간당 수십 회 = 약 0.01 QPS 수준임.
이 기준선이 3.1절 분석의 비교 대상이 됨.
2.3사내 제약사항 사내
DB 도메인 TTL=1초는 사내 표준임. DB failover 시 즉각 대응(신규 연결의 즉시 신규 primary 반영)을
목적으로 설정된 정책으로, 플랫폼에서 TTL 값을 임의로 조정할 수 없으며 준수 대상임.
DNS 상류는 사내 DNS(paydns)로 단일 수렴함. 클러스터의 외부 이름 질의는
nodelocaldns(kubespray 기본 노드 로컬 캐시) → paydns 경로를 가짐. paydns는 전사 공용 핵심 인프라임.
따라서 아키텍처 선택지는 "TTL=1을 전제로 각 방식이 DNS 계층에 어떤 부하·결합을 만드는가"로 평가해야 함. → 3.1절
Part 03
기술 분석 — mesh 경유 시 발생하는 문제
mesh 경유안(ServiceEntry + egressgateway)을 채택했을 때 발생하는 기술 문제를
① DNS 계층과 ② TCP/세션 계층으로 나눠 분석함.
각 항목은 "왜 생기는가(메커니즘) → 얼마나 발생하는가(산식·수치) → 무엇이 깨지는가(증상)" 순서로 기술하며,
검토 과정에서 실측으로 기각된 항목은 기각 사실과 근거를 남겨 둠(3.1.4).
3.1DNS 문제 — on-demand에서 상시 폴링으로의 구조 회귀
3.1.1 한눈에 보는 변화
구분
현행 모델 (직접 연결)
mesh 경유 모델 (SE resolution: DNS)
질의 주체
앱 (연결 생성 시점의 리졸버)
SE가 보이는 모든 Envoy 프록시 (sidecar + egressgateway)
질의 시점
연결을 새로 만들 때만 (on-demand)
상시 — 트래픽 유무와 무관, TTL 주기 타이머
질의량
≈ 0.01 QPS/앱 (pool 안정 상태)
(스코프 내 프록시 수 × 호스트 수) ÷ TTL(1s)
paydns 도달 부하
사실상 0
폴링 프록시 보유 노드 수 × 호스트 수 QPS 상시
DNS ↔ 커넥션 결합
없음 (질의 결과는 신규 연결에만 반영)
신규 연결 방향만 — 기존 커넥션 강제 종료는 없음 (3.1.4 실측)
표 2 — DNS 소비 모델 비교 (색인 · 상세 해설은 아래)
3.1.2 왜 생기는가 — 메커니즘 5단계
STRICT_DNS cluster 생성. ServiceEntry를 resolution: DNS로 등록하면
Envoy에 STRICT_DNS 타입 cluster가 생성됨. 이 타입은 트래픽이 없어도 타이머 기반으로 지속 재질의하여
질의 결과의 IP 집합을 endpoint로 유지함 [5].
TTL 주기 준수. Istio는 레코드 TTL을 따르므로(respect_dns_ttl) TTL=1이면 1초 주기로 재질의함.
사내 파일럿 환경에서 egressgateway가 TTL 주기로 재질의·캐싱함을 실측으로 확인함
사내.
폴링 주체는 gateway만이 아님. cluster는 SE가 스코프에 보이는 모든 프록시에 생성됨.
exportTo 기본값(*)이면 mesh 전체 sidecar가 각자 폴링함.
트래픽이 VirtualService에 의해 gateway로 라우팅되어 sidecar의 해당 cluster를 사용하지 않아도 폴링은 수행됨.
스코프를 좁혀도 하한이 있음 — sidecar가 VIP 할당·라우팅을 위해 SE를 봐야 하므로
"DB 사용 네임스페이스의 전 sidecar + gateway"까지만 축소 가능함.
실질 질의 주체의 이동. 현행 DNS proxying 구조에서 앱의 질의는 istio-agent가 auto-allocated VIP로
로컬 응답하므로 앱 측 질의는 paydns에 도달하지 않음. 즉 mesh 경유안에서 DNS 부하의 실체는 전부 Envoy 폴링임.
nodelocaldns는 소거가 아니라 축약임. TTL=1인 레코드는 nodelocaldns에서도 1초만 캐시됨.
캐시는 같은 노드 안 여러 프록시의 질의를 합쳐줄 뿐이므로, 부하는
"프록시 수 → 노드 수"로 축약될 뿐 사라지지 않고 상류인 paydns에 상시 도달함.
폴링 프록시가 노드당 1개꼴로 분산되어 있으면 캐시 이득은 0임.
그림 2 · mesh 경유 시 DNS 폴링 구조 — 캐시는 노드 단위 축약일 뿐, paydns 상시 부하는 유지됨
3.1.3 얼마나 발생하는가 — 부하 산식
폴링 총량 = (스코프 내 프록시 수 × DB 호스트 수) ÷ TTL(1s) paydns 도달량 = (폴링 프록시 보유 노드 수 × DB 호스트 수) QPS — 24시간 상시 ※ 예시 수치(노드 30 · 호스트 10 → 300 QPS)는 산정 예시임. 적용 검토 시 실제 노드 수·SE 스코프·DB 호스트 수로 치환 필요함
부하의 절대량 이전에 성격의 변화가 문제임: 현행은 연결 생성에 비례하는 on-demand 소비인데,
mesh 경유는 트래픽과 무관한 상시 고정 부하를 전사 공용 paydns에 추가하는 구조임.
완화 수단(exportTo 축소, Sidecar 리소스, 캐시 계층 검증)은 존재하나 이는
"문제를 상시 관리하는 선택"이고, exclude는 "문제가 존재하지 않는 선택"임 —
SE 자체가 없으므로 폴링이 0임.
TTL=1은 사내 표준으로 조정 불가하므로(2.3절) 이 폴링 주기는 우리가 제어할 수 없는 상수임.
3.1.4 검토했으나 논거에서 제외한 항목 — DNS 응답 변화와 기존 커넥션
교정
본 검토의 초안에는 "STRICT_DNS에서는 DNS 응답이 바뀌면 그 endpoint로 향하던
기존 커넥션이 강제 종료된다"는 서술이 있었으나,
자체 검증 랩 실측(Istio 1.30.0)에서 성립하지 않음을 확인하여 철회하고 논거에서 제외함[29]사내.
3.1의 논거는 폴링 부하(3.1.1~3.1.3)로 한정되며, 제안의 결론은 이 항목 없이 성립함(3.2·4절).
실측으로 확인한 동작은 다음과 같음. DNS 응답 변화는 cluster membership — 즉 다음 연결이 붙을 대상만
바꾸고, 이미 맺어진 커넥션에는 개입하지 않음.
1초마다의 응답 상황
Envoy 동작
기존 커넥션 영향 (실측)
이전과 동일한 결과
no-op
없음
IP 교체 (정상 failover)
cluster membership 갱신 — endpoint가 새 IP로 교체됨
기존 연결 유지 — 강제 종료 없음. DB 경로에 해당하는 L4(tcp_proxy)에는 connection pool 자체가 없어, 이미 맺어진 소켓이 CDS/EDS 갱신과 무관하게 살아 있음. L7(pool) 경로에서도 in-flight 요청은 완주하며 정리는 요청이 끝난 뒤에 일어남
응답 셋 플래핑 (GSLB 단일 레코드 로테이션 등)
매초 membership 갱신
같은 이유로 기존 연결에 영향 없음. 바뀌는 것은 이후 신규 연결이 붙는 대상뿐임
빈 응답 / NXDOMAIN (레코드 삭제→재등록형 작업 창)
endpoint 0건
신규 연결만 불가(503 UH 계열). 기존 연결의 종료 여부는 실측하지 않음 — 미검증으로 표기함
질의 실패 (타임아웃·SERVFAIL)
마지막 성공 결과 유지·재시도
없음 — DNS 서버 장애가 곧 DB 단절은 아님
표 3 — DNS 응답 변화 시 Envoy 동작과 기존 커넥션 영향 (자체 검증 랩 실측 기준)
남는 사실은 방향이 하나임 — DNS 응답은 신규 연결에만 반영됨.
이는 mesh 경유안과 직접 연결안 양쪽에서 동일하므로 커넥션 안정성은 두 방식을 가르는 축이 아님.
exclude 채택 시 달라지는 것은 resolve 주체뿐임 — Envoy가 아니라 앱(JVM 등)이 해석하므로 관리 포인트가
앱 측 DNS 캐시(networkaddress.cache.ttl)로 이동함. 표준값은 5.5절에 제시함.
3.2TCP/세션 문제 — 장수명 상태를 프록시 홉에 태우는 비용
DB 커넥션은 수 시간 유지되는 상태(stateful) 자원임. 요청 단위로 소멸하는 HTTP와 달리,
경로 위 프록시의 수명주기·설정이 곧 커넥션의 수명주기·설정이 됨. 문제 4가지를 색인 후 해설함.
문제
원인
증상
완화 가능성
① 재시작 = 재연결 폭증
gateway 파드 종료 시 보유 커넥션 전체 단절
롤아웃·업그레이드·scale-in마다 전사 DB 재연결 이벤트
완화만 가능, 제거 불가
② chokepoint 수렴
전 앱 pool 커넥션이 소수 파드에 집중
용량 관리·재분배 문제 (커넥션은 재접속 시에만 재분배됨)
replicas 고정 등 관리로 대응
③ 타임아웃 층 중첩
Envoy tcp_proxy idle_timeout(기본 1시간) 등
유휴 커넥션 절단 — "한가한 시간대 첫 쿼리 실패" 패턴
pool keepalive로 우회 (관리 포인트 증가)
④ DB 측 시야 상실
소스 IP가 gateway로 수렴
user@host grant·방화벽·DB 감사로그의 앱 식별 불가
gateway 로그 상관분석 체계 별도 구축 필요
표 4 — mesh 경유 시 TCP/세션 계층 문제 (색인 · 해설은 아래)
① gateway 수명주기 = 커넥션 수명주기
gateway 파드가 종료되면(롤아웃·Istio 업그레이드·노드 드레인·HPA scale-in) 그 파드가 중계하던
모든 DB 커넥션이 강제 단절됨. 장수명 TCP는 drain 시간(terminationDrainDuration) 안에 끝나지 않으므로
graceful drain으로 살릴 수 없음.
PDB·점검 시간대 롤아웃·pool 재연결 견고화로 완화는 가능하나,
"gateway 재시작 = 전사 DB 재연결 이벤트"라는 성질 자체는 구조적으로 제거 불가함.
Istio 정기 업그레이드 주기가 곧 DB 재연결 이벤트 주기가 됨.
참고: Google이 GKE→Cloud SQL 연결에서 중앙 프록시 서비스 대신 파드별 sidecar 분산을 권장하는 명시 사유가
바로 "단일 장애점 방지 — 각 앱의 DB 접근이 서로 독립적"임 [14]벤더. 중앙 경유점의 상태 결합 문제를 벤더가 문서화한 사례임.
② 커넥션의 chokepoint 수렴
전 앱의 pool 커넥션 합계(앱 수 × pool size)가 소수 gateway 파드에 상시 유지됨.
파드당 커넥션·메모리 산정, FD 한도 관리가 새로 필요함.
TCP 커넥션은 로드밸런싱 단위가 "연결"이므로 scale-out해도 기존 커넥션은 재분배되지 않고,
scale-in은 곧 ①의 재연결 이벤트임 — HPA를 쓸 수 없고 replicas 고정 운영이 강제됨.
③ 타임아웃·프로토콜 층의 중첩
Envoy tcp_proxy의 idle_timeout 기본값은 1시간임. TCP keepalive 패킷은 데이터가 아니라 이 타이머를 리셋하지 못하므로,
1시간 이상 유휴한 pool 커넥션은 중간에서 절단됨 → 트래픽 적은 시간대 이후 첫 쿼리 실패 패턴이 발생함.
pool의 keepalive(validation ping = 실제 데이터)로 우회 가능하나, 전 앱의 pool 설정과 Envoy 설정의 정합이라는
상시 관리 항목이 추가됨.
MySQL 등 server-first 프로토콜(서버가 먼저 발화)은 Istio protocol sniffing과 비호환이라 포트 protocol을 TCP로 명시해야 하며
[3]공식, 오구성 시 연결이 hang되는 알려진 함정임 —
mesh 경유 구성에서만 존재하는 실수 표면임.
④ DB 측 소스 식별 상실
모든 연결의 소스가 gateway (파드/노드) IP로 수렴함 → DB의 user@host grant, DB존 방화벽 룰,
DB 감사로그에서 "어느 앱의 연결인가"를 IP로 식별할 수 없게 됨.
보완하려면 gateway access log의 downstream principal과 DB 세션의 상관분석 체계를 별도 구축해야 함 —
직접 연결에서는 존재하지 않는 비용임.
3.3공정성 확보 — 사용하지 않는 논거와 유지되는 가치
FAIRNESS
latency는 반대 논거로 사용하지 않음. Istio 공식 성능 실측(외부 MongoDB 대상 egress gateway 추가 실험)에서
응답시간 분포에 유의미한 차이가 없었음 [7]공식.
"DNS 응답 변화가 기존 커넥션을 끊는다"도 사용하지 않음. 초안의 서술이었으나 자체 실측으로 기각함(3.1.4).
따라서 본 제안의 근거는 DNS 폴링 부하(3.1.1~3.1.3)와 세션 수명주기(3.2), 업계 표준(4절)으로 한정됨.
egress gateway 체계의 가치는 유지됨. SPIFFE 기반 워크로드 인가·고정 egress 지점·중앙 로그는
외부 HTTPS 통신에서 계속 유효하며, 본 제안은 그 체계를 축소하지 않음.
다만 DB(L4)에는 mesh의 L7 가치(retry·timeout·circuit breaking·HTTP 텔레메트리)가 적용 자체가 되지 않고,
gateway 경유 강제조차 NetworkPolicy·방화벽이 담당해야 하므로(4.1절) DB에서의 순가치가 얇다는 것이 논지임.
Part 04
업계 레퍼런스 — 표준·구현 사례·토스
주장의 강도를 구분하기 위해 모든 항목에 근거 등급을 표기함:
공식 프로젝트 공식 문서 ·
벤더 클라우드/벤더 공식 가이드 ·
발표 기업 공식 컨퍼런스 ·
커뮤니티 정리글/권고문 ·
규제 규제기관 자료 ·
사내 사내 확인 사항.
4.1Istio 스스로의 명시 — "gateway 방식조차 NetworkPolicy·방화벽을 전제로 함" 공식
Istio 공식 문서(Egress Gateways task)는 Istio가 모든 egress 트래픽의 gateway 경유를 스스로 강제할 수 없으며,
sidecar를 우회한 트래픽은 gateway 없이 외부에 직접 도달할 수 있으므로, 우회 방지는
Kubernetes NetworkPolicy나 방화벽 등 Istio 외부 메커니즘이 담당해야 한다고 명시함
[1].
Security Best Practices 문서는 outboundTrafficPolicy: REGISTRY_ONLY가 보안 경계가 아니며,
egress 통제는 gateway와 NetworkPolicy의 결합으로 성립한다고 기술함 [2].
실증: 파드 내부에서 UID를 1337로 변경하면 iptables 리다이렉션을 우회할 수 있다는 보안 권고문이 공개되어 있음
[25]커뮤니티.
논리적 귀결
DB를 gateway에 태우든 태우지 않든 존 방화벽 + Calico egress NetworkPolicy는 어차피 구축·유지해야 하는 기반임.
따라서 exclude안은 "통제를 빼는 선택"이 아니라, gateway 방식의 필수 기반만으로 충분한 트래픽 유형(DB)에서
부가 홉을 생략하는 선택임. 통제 수준의 후퇴가 없음(5.2절 매핑).
4.2컴플라이언스 표준 — 세그먼테이션 수단은 NetworkPolicy임
커뮤니티 PCI SSC는 2022년 컨테이너·오케스트레이션 보안 가이드(Information Supplement)를 발행했고,
네트워크 항목의 best practice는 "default deny 기반 + 운영에 필요한 접근만 명시 허용" — NetworkPolicy 지원 CNI 기반의 정책 통제임
[24].
벤더 Microsoft AKS의 PCI DSS 4.0.1 공식 아키텍처: k8s 워크로드에서는 전통적 방화벽 규칙 같은
네트워크 구조물에만 의존하는 것이 불충분하며, NetworkPolicy 등 Kubernetes-native 통제를 강조함
[15].
벤더 Google GKE PCI DSS 가이드: 네트워크 세그먼테이션은 pod-level network policy로
수행하라고 명시함 [16].
벤더 AWS EKS PCI 아키텍처 가이드: 네임스페이스 격리와 pod 간 통신 제한으로 CDE(카드정보 처리 환경)를 분리함
[17].
3대 클라우드의 PCI 레퍼런스 어느 것도 DB 경로 요건으로 mesh egress gateway를 두지 않음.
PCI 환경의 세그먼테이션 정석은 NetworkPolicy 기반 통제이며, 이는 exclude안의 통제 모델과 정확히 일치함.
4.3mesh 계층 스스로의 DB 특별취급 공식
Linkerd는 2.9까지 3306(MySQL)·5432(PostgreSQL)를 기본 skip-port로 출고했음 —
DB 트래픽이 데이터플레인 프록시를 완전히 우회하는 것이 벤더 출고 기본값이었음. 2.10부터는 opaque(프록시 통과·detection 생략)로 전환함
[8][9].
Istio는 server-first 프로토콜의 잘 알려진 포트를 자동으로 TCP 간주하며 protocol sniffing 비호환을 문서화함
[3][4].
함의: mesh가 DB 트래픽에 제공하는 것은 L4 릴레이뿐이며, L7 가치(retry·timeout·circuit breaking·요청 단위 텔레메트리)는
DB 프로토콜에 적용 자체가 되지 않음을 벤더들이 스스로 문서화한 것임.
연결 관리·failover를 DB 프로토콜을 이해하는 전용 계층(VTGate)에서 해결 — mesh가 아닌 층의 해법
고정 egress IP (CNI 층)
Cilium(Corner Banca 은행 사례)·OpenShift EgressIP [19][20]벤더
좁은 고정 소스 IP가 규제 요건인 경우조차 업계 정석은 mesh가 아닌 CNI/L3 층임. Calico는 해당 기능이 Enterprise 전용 [11]
표 5 — k8s 앱 → 외부 DB 연결의 문서화된 구현 패턴
부재의 보고: 반대 방향 — "mesh egress gateway로 프로덕션 DB를 경유"한 실명 기업 공개 사례는
조사 범위에서 발견되지 않음. 존재하는 것은 공식 레퍼런스 구현(MongoDB 예제 [6])·
벤더 가이드·커뮤니티 시도 스레드 수준임.
4.5토스 사례 — Istio 전면 운영 환경의 공개된 DB 연결 구조 발표
확인된 사실과 추론을 구분해 기술함. 국내에서 우리와 가장 유사한 환경(온프렘 k8s + Istio + 금융)의 공개 자료임.
확인된 사실 (SLASH 21 공식 세션)
토스는 Active-Active 이중 데이터센터에서 Kubernetes와 Istio Service Mesh를 운영함을 공식 발표함
[21].
같은 컨퍼런스의 DB 세션("토스의 Database DR 구조")에 따르면 [22][23]:
MySQL HA는 MMM(MySQL Multi-master replication Manager)이 담당하고, DB 서버에 올린
서비스 IP(VIP — rw.toss.bz, ro1.toss.bz 등의 도메인이 가리킴)를 MMM이 이동시켜 앱 failover를 수행함.
평상시 앱의 DB 커넥션 도메인은 이 서비스 IP를 직접 가리키며 L7을 경유하지 않음.
DC 간 비계획 전환은 도메인 타겟 변경(앱이 재접속 시 DNS를 새로 resolve), 계획 전환 시에만 도메인을 L7 VIP로
임시 전환해 L7 failover로 커넥션을 일괄 이동시킴.
추론 (근거와 함께 명시)
DB 경로 설명 전체가 DNS·VIP·L7의 언어로만 기술되고 ServiceEntry·egress gateway 등 mesh 오브젝트 언급이 없으며,
failover 서사의 resolve 주체가 Envoy가 아닌 앱임 → DB 연결은 mesh의 관리 대상 밖(직접 연결)으로 추정됨.
단, 기계적 처리 방식(excludeOutboundPorts 사용 여부 vs sidecar L4 단순 통과)은 비공개이며,
해당 발표는 2021년 자료로 이후 구성 변화 가능성이 있음. 본 문서는 이 한계를 명시한 채로만 인용함.
그림 3 · 토스의 공개된 DB 연결·failover 구조 (SLASH 21 발표 기준 재구성)
4.6국내 규제 관점 규제
전자금융감독규정·개인정보의 안전성 확보조치 기준이 요구하는 것은 접근통제·최소권한·접속기록 보관이며,
특정 네트워크 구현 방식(어떤 홉을 경유할 것)을 지정하지 않음. exclude안의 3층 통제(5.2절)는 이 요구에 그대로 매핑됨.
규제 방향성 참고: 금융위원회는 2024년 8월 망분리 개선 로드맵에서 중장기적으로
자율보안-결과책임 원칙으로의 전환을 제시했고, 이후 단계적 개정이 진행 중임
[27] — "경계 구현 고정"이 아닌 "계층 통제와 기록으로 입증"하는 접근과 정합함.
Part 05
제안 구성 — exclude 적용·통제 매핑·검증
5.1excludeOutboundPorts 적용
동작 원리: istio-init이 설정하는 iptables 규칙에서 지정 포트의 outbound 트래픽에 RETURN 규칙을 추가함 —
해당 포트 트래픽은 Envoy를 커널 레벨에서 아예 거치지 않고 목적지로 직행함
[5]. ServiceEntry가 불필요하므로 STRICT_DNS cluster도, DNS 폴링도 생성되지 않음(폴링 0).
# 파드(Deployment) 단위 적용 — DB 연결 워크로드에 부착
apiVersion: apps/v1
kind: Deployment
metadata:
name: payment-api
spec:
template:
metadata:
annotations:
traffic.sidecar.istio.io/excludeOutboundPorts: "3306,5432,27017,9200"# ^ 사내 DB 포트 목록으로 확정 필요 (MySQL·PostgreSQL·MongoDB·OpenSearch 등)
적용 단위: 파드 어노테이션 우선(대상 워크로드 명시적 관리). 파일럿 검증 후 전사 표준화 시
전역 기본값(values.global.proxy.excludeOutboundPorts)으로의 승격을 별도 검토함
[13].
배포 표준화: 공통 Helm 차트/ArgoCD 템플릿에 어노테이션을 표준 항목으로 편입해 누락을 방지함.
주의: exclude는 파드의 모든 컨테이너에 적용됨(포트 기준).
DB 포트를 앱 외 용도로 쓰는 컨테이너가 없는지 확인 필요함.
5.2통제 매핑 — "빠지는 통제가 없음"의 증명
층
통제 질문
수단
담당
① 경계
어느 네트워크가 DB존에 도달 가능한가
존 방화벽 — 클러스터 egress 대역 → DB존:포트 허용
네트워크·보안
② 클러스터
어느 워크로드가 나갈 수 있는가
Calico egress NetworkPolicy (라벨 기반 목적지·포트 제한)
플랫폼
③ 엔드포인트
누가·무엇을 했는가
DB 계정·비밀번호/TLS·DB 접속기록(감사)
DBA·보안
표 6 — exclude안의 3층 통제 매핑
핵심: 4.1절에서 확인했듯 ①·②층은 gateway 경유안을 채택해도 어차피 필요한 기반임(우회 방지가 NetworkPolicy·방화벽 몫이므로).
exclude안은 이 필수 기반 위에서 부가 홉만 생략하는 것이며, 통제 관점의 후퇴가 없음.
gateway 경유안이 추가로 제공했을 것(SPIFFE 단위 인가·중앙 로그)의 DB 맥락 대체:
워크로드 단위 통제는 ②층(라벨 기반 NP)이, 감사는 ③층(DB 접속기록)이 담당함 — 규제 요구(4.6절)와 정합함.
그림 4 · 제안안의 통제 3층 — 경로에서 홉을 빼되 통제는 전부 유지됨
5.3대안 비교
평가 항목
(a) egressgateway 경유
(b) sidecar 통과 SE resolution: NONE
(c) exclude [채택]
DNS 폴링 (paydns)
스코프 내 전 프록시 상시 폴링
0 (resolution: NONE 전제)
0 (SE 자체 없음)
커넥션 경로 홉
sidecar + gateway 2홉
sidecar 1홉
0홉 (직결)
프록시 수명주기 결합
gateway 재시작 = 전사 재연결
sidecar 재시작 = 해당 파드 재연결(파드와 동일 운명이라 영향 최소)
없음
Envoy 타임아웃 관리
필요 (idle 1h 등, 전 앱 pool 정합)
필요 (동일)
불필요
DB측 소스 식별
gateway IP로 수렴 — 식별 상실
파드/노드 소스 유지
파드/노드 소스 유지
mesh 관측성(TCP 메트릭)
있음
있음
없음 — DB측·APM으로 대체(5.5)
워크로드 단위 통제
SPIFFE AuthorizationPolicy
Calico NP
Calico NP
운영 복잡도
높음 (SE·GW·VS·DR + 5.1~5.4의 상시 관리)
중간 (SE 스코프·리스너 관리)
낮음 (어노테이션 표준화만)
표 7 — 대안 비교 (색인 · 해설은 아래)
(a) 경유안: 3절의 문제 전부를 상시 관리 항목으로 떠안음. 고유 이점(SPIFFE 인가·중앙 로그)은 존재하나
DB 맥락에서는 ②·③층으로 대체 가능하고, 그 대가(재연결 이벤트·chokepoint·식별 상실)가 큼.
(b) sidecar 통과안: 차선책으로 검토 가치가 있음. resolution: NONE(앱이 resolve한 원 목적지로 통과)을 쓰면
폴링이 0이고 Kiali의 TCP 메트릭을 유지함. 단 0.0.0.0:포트 리스너라 목적지 구분이 포트 단위로 거칠고,
sidecar 홉의 타임아웃 관리가 남으며, MySQL 등 server-first 프로토콜의 sniffing 함정 표면이 유지됨.
mesh 관측성 요구가 확정될 경우의 fallback으로 문서화해 둠.
(c) exclude안 [채택]: DNS·세션 문제군이 구조적으로 소멸하고 운영 표면이 가장 작음.
상실하는 것은 mesh 관측성 하나이며 5.5절의 대체 수단으로 보완함.
5.4적용·검증·롤백 절차
사전 확인 (적용 전 필수) 사내
방화벽 정책 단위 확인: DB존 방화벽이 "클러스터 egress 대역(서브넷) → DB존:포트" 형태의 허용을 수용하는지
보안팀과 확정 필요함. (수용 불가 시 본 제안의 ①층 전제가 성립하지 않으므로 고정 egress IP 계층 논의로 회귀함 — 6.2절)
Calico natOutgoing 확인: 현재 설정에 따라 DB가 보는 소스가 노드 IP인지 파드 IP인지 달라짐 —
방화벽 룰의 실체(노드 대역 vs 파드 CIDR)를 결정하는 항목임.
대상 포트 목록 확정: 사내 DB 유형별 포트 인벤토리(MySQL·PostgreSQL·MongoDB·OpenSearch·Redis 등) 작성 필요함.
검증 커맨드
# 1) iptables 반영 확인 — istio-init 로그에서 exclude 포트의 RETURN 규칙
kubectl logs deploy/<app> -c istio-init | grep -i exclude
# 2) Envoy 구성에서 DB 목적지 cluster 부재 확인 (SE 미등록이므로 없어야 정상)
istioctl proxy-config cluster <pod> -n <ns> --fqdn <db-host> # -> 결과 없음이 정상# 3) DNS 폴링 0 확인 — 해당 노드에서 DB 호스트 질의가 관측되지 않아야 함
tcpdump -i any port 53 | grep <db-host> # -> 연결 생성 시점 외 무출력# 4) 연결 경로 확인 — 앱 컨테이너에서 DB VIP로의 직접 ESTABLISHED 세션
kubectl exec <pod> -c <app> -- ss -tn state established '( dport = :5432 )'
# 5) failover 리허설 — DB팀 협조 하에 전환 수행, pool 재수립 소요시간 실측
롤백
어노테이션 제거 후 롤링 재기동만으로 원상 복귀됨 — 클러스터 공용 설정 변경이 없어 롤백 범위가 파드 단위로 국소적임.
5.5남는 리스크·한계와 보완
항목
내용
보완
mesh 관측성 상실
Kiali·Istio TCP 메트릭에 DB 트래픽 미표시
DB측 세션·성능 모니터링 + 앱 APM(커넥션 풀 메트릭) + 필요 시 노드 플로우 로그. 요구 확정 시 (b)안 전환 가능
앱측 DNS 캐시가 관리 포인트로 복귀
mesh를 빼면 resolve 주체가 앱(JVM)이 됨 — JVM 기본 캐시(30초 등)가 TTL=1보다 김
DB는 L4 장수명 프로토콜이라 mesh의 L7 가치(retry·timeout·circuit breaking·요청 텔레메트리)가 적용 자체가 되지 않음[3][8]. 남는 것은 L4 릴레이뿐인데, 그 릴레이가 3절의 비용(상시 폴링·재연결 이벤트·chokepoint)을 수반함.
gateway 경유 강제조차 NetworkPolicy·방화벽 몫이므로 [1][2], DB에서 gateway를 생략해도
통제 기반은 동일하게 유지됨(5.2절). mesh 벤더 스스로 DB 포트를 기본 우회로 출고했던 이력이 이 판단의 선례임
[8].
Q2"향후 DB존 방화벽이 좁은 고정 소스 IP를 요구하면?"
그 경우에도 업계 정석은 mesh가 아니라 CNI/L3 층의 고정 egress IP임 — 은행 실사례(Cilium Corner Banca)와
OpenShift EgressIP가 대표임 [19][20]. 현행 Calico OSS에는 해당 기능이 없어(Enterprise 전용
[11]) 요건 발생 시 CNI 전략과 함께 별도 검토가 필요하며,
DB존 앞 L4 프록시 티어(HAProxy 등)도 대안임. 요건이 확인되기 전에는 서브넷 단위 허용(①층)으로 충분함.
Q3"감사·통제 수준이 후퇴하는 것 아닌가?"
통제 3층 매핑(5.2절)으로 워크로드 단위 통제(Calico NP)와 감사(DB 접속기록)가 유지되며, 이는 규제가 요구하는
접근통제·기록 요건에 그대로 매핑됨(4.6절). 오히려 경유안은 DB측 소스 식별을 상실시켜(3.2-④) DB 감사 관점에서 후퇴 요소가 있음.
PCI 계열 3대 클라우드 레퍼런스의 세그먼테이션 수단이 정확히 이 모델(NetworkPolicy)임
[15][16][17].
[28]사내사내 조사 — DB 도메인 TTL=1 정책(failover 즉각 대응 목적·조정 불가), DNS 상류 paydns 단일 수렴, egressgateway의 TTL 주기 재질의 실측 (2026.08)
[29]사내자체 검증 랩 실측 — ServiceEntry resolution(STRICT/LOGICAL) × 경로(L7 origination / L4 passthrough) 2×2 매트릭스, GSLB flip 시 in-flight·기존 커넥션의 운명 (Istio 1.30.0, 2026.07). 3.1.4의 교정 근거 — 네 칸 모두에서 기존 커넥션이 강제 종료되지 않았고, L4에는 connection pool 자체가 없어 CDS/EDS 갱신이 소켓과 무관함을 확인함
Part 08
개정 이력
판
일자
변경 내용
v1.1
2026-08-03
3.1.4 철회 — "DNS 응답 변화가 기존 커넥션을 강제 종료한다"는 초안 서술을
자체 검증 랩 실측(Istio 1.30.0)으로 기각하고 논거에서 제외함
[29]. 부수 수정: 표 3을 실측 기준으로 재작성,
표 2의 "DNS ↔ 커넥션 결합" 행 정정, 3.3(공정성)에 기각 항목 추가, 출처 [29] 신설.
제안의 결론과 나머지 논거(폴링 부하 3.1.1~3.1.3 · 세션 수명주기 3.2 · 업계 표준 4절)는 변경 없음.
v1.0
2026-08
최초 작성 — "DB 연결도 istio-egressgateway로 관리하는 방안"의 타당성 검증·조사 결과와
exclude 채택 제안.