---
title: mTLS Passthrough — 홉별 DestinationRule·connectionPool (홉 2는 tls 없는 DR)
date: 2026-07-05
type: guide
domain: istio
tags: [egress, mtls, destinationrule, connection-pool]
---
> [!abstract]
> **mTLS Passthrough**(HTTPS over mTLS, [용어 정본](/docs/istio/egress/https-pattern-map/))에서
> 홉 1(sidecar→egressgateway)과 홉 2(egressgateway→외부) 각각에 connectionPool을 거는 방법을 다룬다.
> 머릿속에 넣을 한 문장: **DR은 두 벌이되 홉 2 DR엔 `tls` 블록이 아예 없다** — gateway는 앱의 TLS
> ciphertext를 raw TCP로 흘릴 뿐이므로, `tls.mode`를 고르는 문제가 아니라 **생략하는** 문제다
> (`tls.mode: tcp`라는 값은 존재하지 않고 CRD가 거부한다 — T91 실측). connectionPool은 두 홉 모두
> 유효하며 "그 홉의 연결을 여는 프록시"에 발효된다: 홉 1 값은 호출자 sidecar, 홉 2 값은 gateway.
> 패턴 자체의 해부(이중 봉투·leg-2 tcp 필수)는 [정본](/docs/istio/egress/https-over-mtls/),
> 이 문서는 그 위의 **DR 두 벌 구성**만 좁혀 다룬다.
**대상 환경:** Istio **1.30.0**, sidecar mesh (homelab k8s 1.30.6 기준 컨벤션)
**검증:** 본문의 모든 주장은 실제 클러스터 E2E 실측으로 확인했다 (검증 ID **T91** — 문서 끝 "검증 기록"에 원자료·재현 스크립트). 본문의 "(T91)"은 그 기록의 해당 항목을 가리킨다.
---
## 0. 패턴 요약 — 두 홉, 두 봉투, DR 두 벌
mTLS Passthrough는 "**종단간 암호화는 건드리지 않으면서, egress에서 누가 나가는지(SPIFFE 신원)는 확인하고 싶다**"에 대한 답이다. 동작은 봉투 두 겹으로 요약된다:
- 앱은 평소처럼 `https://`를 직접 호출한다 — 이 TLS(**inner**)는 앱↔외부 서버 사이에서만 열리고, 중간의 누구도 풀지 않는다.
- sidecar가 그 위에 메시 mTLS(**outer**, `ISTIO_MUTUAL`)를 한 겹 더 입혀 egressgateway로 보낸다 (홉 1).
- gateway는 **outer만 종단**해 호출 워크로드의 SPIFFE 신원을 암호학적으로 검증한 뒤, 안에 든 inner TLS bytes를 복호화 없이 **raw TCP로 그대로** 외부에 흘린다 (홉 2).
```mermaid
flowchart LR
subgraph appns["ns: mesh-test"]
APP["app
curl https://
(inner TLS 생성)"] --> SC["sidecar Envoy
outer ISTIO_MUTUAL 래핑
← DR-hop1 (tls + pool)"]
end
subgraph sysns["ns: istio-system"]
GW["egressgateway
outer 종단 = SPIFFE 확인
← DR-hop2 (pool만, tls 없음)"]
end
EXT["api.partner.example.com:443
(inner TLS를 서버가 종단)"]
SC -->|"홉 1: outer mTLS
(속: inner TLS 그대로)"| GW
GW -->|"홉 2: raw TCP relay
(inner TLS 그대로)"| EXT
```
여기서 이 문서의 주제가 나온다. 각 홉의 커넥션을 **여는 프록시가 서로 다르다** — 홉 1 연결은 각 클라이언트 pod의 sidecar가, 홉 2 연결은 gateway가 연다. DestinationRule의 connectionPool은 항상 "연결을 여는 쪽" Envoy에 설정으로 박히므로(§2), 홉별로 풀을 걸려면 **DR이 두 벌** 필요하고, 두 벌의 생김새가 상당히 다르다(§1). 패턴 자체를 더 깊이 — 왜 gateway 뒤 라우트가 `tcp`여야 하는지, passthrough/origination 대비 트레이드오프 — 는 [해부 문서](/docs/istio/egress/https-over-mtls/)와 [패턴 지도](/docs/istio/egress/https-pattern-map/)가 다룬다.
## 1. DR 두 벌 — 그리고 홉 2 "일반 TCP"의 올바른 표현
이 패턴의 두 홉은 성격이 완전히 다르다:
| | DR-hop1 | DR-hop2 |
|---|---|---|
| `host` | gateway Service의 레지스트리 FQDN | ServiceEntry 외부 host |
| `tls` | `ISTIO_MUTUAL` + `sni` (outer 봉투 생성) | **블록 자체가 없음** (raw TCP) |
| `connectionPool` 발효 위치 | **호출자 sidecar**의 upstream cluster | **gateway**의 upstream cluster |
| 존재 이유 | mTLS 래핑 + SNI 적재 + 홉 1 풀 | 홉 2 풀 튜닝 **전용** |
| `exportTo` | **두지 않는다** (기본 `*` = mesh 전체) | `["."]` — gateway ns로 한정 |
**가시성이 반대인 이유 — 소비자가 누구인가로 갈린다.** DR-hop1의 소비자는 **모든 호출 네임스페이스의 sidecar**다(트래픽 없이도 각 클라이언트 sidecar의 cluster에 컴파일돼야 outer mTLS가 성립). 그래서 exportTo를 생략해 mesh 전체에 공개한다 — 클라이언트가 gateway와 같은 ns여야 한다는 제약은 **없다**(istio-system의 DR을 mesh-test의 sidecar가 집는 것이 표준 배치). 반대로 좁혀버리면(예: `exportTo: ["."]`) 클라이언트 sidecar가 DR을 못 보고 **평문으로** gateway의 `ISTIO_MUTUAL` listener에 부딪혀 handshake가 거부된다. DR-hop2는 소비자가 gateway pod 하나뿐이라 `["."]`로 좁히는 것이 위생이다(§5의 같은-ns 한계 포함).
**홉 2가 "일반 TCP"라는 말의 정확한 의미**: gateway가 outer `ISTIO_MUTUAL`을 종단하고 나면 손에 남는 건 앱이 만든 inner TLS ciphertext다. gateway는 이걸 복호화도 재암호화도 하지 않고 `tcp_proxy`로 그대로 외부에 흘린다. 와이어가 평문인 게 아니라 — **gateway 입장에서 TCP relay**라는 뜻이고, 종단간 암호화는 앱↔외부 서버의 inner TLS가 책임진다.
이걸 DR로 표현하는 방법은 셋이고, **셋 다 결과가 같다** (외부 host는 `MESH_EXTERNAL`이라 auto-mTLS 대상이 아니므로):
1. **DR-hop2를 아예 안 만든다** — 기본값 = TLS origination 없음 = raw forward. 풀 튜닝이 필요 없다면 이게 정답.
2. **`tls` 블록 없이 `connectionPool`만 있는 DR** — 풀 튜닝이 필요할 때의 표준형 (이 문서의 §3).
3. `tls.mode: DISABLE` 명시 — 방어적 명시가 필요할 때. 기능상 2와 동일.
반면 `tls.mode: tcp`는 **존재하지 않는 값**이다. `ClientTLSSettings.mode`의 enum은 넷뿐이고, apply 시점에 CRD validation이 거부한다 (T91 실측):
```
The DestinationRule "..." is invalid:
* spec.trafficPolicy.tls.mode: Unsupported value: "tcp":
supported values: "DISABLE", "SIMPLE", "MUTUAL", "ISTIO_MUTUAL"
```
> [!note]
> 자매 패턴과의 경계: [이중 mTLS](/docs/istio/egress/double-mtls-gateway-connection/)는 DR-hop2가
> `MUTUAL` + `credentialName`으로 **gateway가 새 TLS를 시작**한다. mTLS Passthrough에서 DR-hop2의
> mode만 바꿔서 그 패턴이 되는 게 아니다 — 앱 호출(https→http), Gateway protocol(TLS→HTTPS),
> VS 라우트 타입(tls·tcp→http·http)이 함께 바뀌어야 한다([패턴 지도](/docs/istio/egress/https-pattern-map/) §3 시그니처 표).
## 2. connectionPool은 어느 Envoy에서 발효되나
동작 원리부터. istiod는 DR의 `trafficPolicy`를 "그 DR의 host를 향한 **upstream cluster** 설정"으로 컴파일해 Envoy에 내려준다. 그런데 upstream cluster는 **프록시마다 따로** 존재한다 — 같은 host라도 sidecar의 cluster와 gateway의 cluster는 별개다. 따라서 설정이 실제로 힘을 갖는 곳은 **그 host로 연결을 여는 프록시**의 cluster다. 이 문서에선 이를 "발효(effective) 위치"라 부른다. 홉 1 연결은 클라이언트 sidecar가, 홉 2 연결은 gateway가 열므로:
- **DR-hop1 풀** → 호출자 sidecar의 `outbound|||` cluster. 한도는 Envoy별 독립 집행이라 **클라이언트 pod당 상한**이다. `maxConnections`는 여유 있게, `connectTimeout`은 in-cluster 홉이므로 짧게(3s).
- **DR-hop2 풀** → gateway의 `outbound|443||<외부host>` cluster. sidecar 시절 pod마다 분산되던 연결이 gateway로 **전사 합류**하는 지점 — DR 없이 방치하면 Envoy 기본 상한(1,024)에 gateway가 먼저 부딪힌다. `maxConnections`·`tcpKeepalive`·`maxConnectionDuration`의 주 전장 ([TCP 처방전](/docs/istio/egress/tcp-tuning/) P1).
이 원칙은 실측으로 확인된 것이다(T91): 두 DR을 구분 추적하려고 `maxConnections`에 서로 다른 식별값을 넣고(DR-hop1=111, DR-hop2=222) 양쪽 프록시의 cluster 설정을 각각 덤프했더니, 111은 클라이언트 sidecar에만, 222는 gateway에만 나타났다 — 확인 절차는 §4. 같은 원칙이 origination 계열(gateway가 외부로 TLS를 새로 시작하는 [이중 mTLS](/docs/istio/egress/double-mtls-gateway-connection/) 패턴, T90)에서도 동일하게 성립한다.
한 가지 이 패턴 특유의 제약: **홉 2는 TCP 라우트이므로 `connectionPool.http.*`가 무의미하다.** 이중 mTLS(홉 2가 L7)와 달리 여기선 gateway가 요청 단위를 모르므로 `http.idleTimeout`·`maxRequestsPerConnection` 같은 다이얼이 적용될 대상이 없다. 커넥션 수명 관리는 `tcp.idleTimeout`·`tcp.maxConnectionDuration`·`tcp.tcpKeepalive`로만 한다. 홉 1도 마찬가지로 TLS(tcp_proxy) 라우트라 `tcp.*`만 유효하다.
## 3. 전체 YAML — 표준 배치 한 벌
표준 배치(공유 istio-egressgateway, Service `443 → targetPort 8443`, 클라이언트는 mesh-test) 기준. 검증 하네스(T91)는 전용 gateway·다른 포트를 썼으며 원자료는 검증 기록 참조. 레지스트리 도메인이 표준이 아니면(`istioctl proxy-config cluster`에 보이는 이름 기준) k8s Service host를 그에 맞출 것.
```yaml
# 1) ServiceEntry — 외부 host 등록 (protocol TLS: gateway가 L7을 파싱하지 않음)
apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata: { name: partner-api, namespace: istio-system }
spec:
hosts: [api.partner.example.com]
ports:
- { number: 443, name: tls, protocol: TLS }
resolution: DNS
location: MESH_EXTERNAL
---
# 2) Gateway — outer ISTIO_MUTUAL 종단 서버 (protocol TLS — HTTPS 아님, inner는 opaque)
apiVersion: networking.istio.io/v1
kind: Gateway
metadata: { name: egress-partner, namespace: istio-system }
spec:
selector: { istio: egressgateway }
servers:
- port: { number: 8443, name: tls-partner, protocol: TLS } # 컨테이너 포트
hosts: [api.partner.example.com]
tls: { mode: ISTIO_MUTUAL } # client cert 강제 + SPIFFE 검증 + outer만 종단
---
# 3) DR-hop1 — outer mTLS 래핑 + 홉 1 풀 (호출자 sidecar cluster에 컴파일)
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata: { name: egressgateway-partner, namespace: istio-system }
spec: # exportTo 없음(기본 *) — 소비자 = 모든 클라이언트 ns의 sidecar
host: istio-egressgateway.istio-system.svc.cluster.local # 레지스트리 FQDN
subsets:
- name: partner
trafficPolicy:
portLevelSettings:
- port: { number: 443 } # Service 포트 기준
tls:
mode: ISTIO_MUTUAL # sidecar가 SPIFFE cert 제시
sni: api.partner.example.com # gateway filter chain 매칭 키
connectionPool: # tls와 같은 포트 엔트리에 — 통째 교체 규칙(§5)
tcp:
maxConnections: 1024 # pod당 상한 — 여유 있게
connectTimeout: 3s
tcpKeepalive: { time: 300s, interval: 30s, probes: 3 }
---
# 4) DR-hop2 — tls 블록 없음(raw TCP), 홉 2 풀 전용 (gateway cluster에 컴파일)
apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata: { name: partner-tcp-pool, namespace: istio-system } # gateway ns 배치
spec:
host: api.partner.example.com # ServiceEntry hosts와 정확 일치
exportTo: ["."] # 타 ns sidecar 오적용 차단 (§5 스코프 주의)
trafficPolicy:
connectionPool:
tcp: # http.* 는 TCP 라우트라 무의미 — tcp만
maxConnections: 4096 # 전사 합류 지점 — peak x 2~3 (측정 기반)
connectTimeout: 3s
idleTimeout: 1800s # 채널 최장 유휴보다 길게
maxConnectionDuration: 3600s # 수명 상한 — 재분배·drain 자연 소멸
tcpKeepalive: { time: 300s, interval: 30s, probes: 3 } # FW idle의 1/3
---
# 5) VirtualService — leg-1 tls(SNI 생존) / leg-2 tcp(SNI 소비 후 raw relay)
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata: { name: partner-via-egress, namespace: istio-system }
spec:
hosts: [api.partner.example.com]
gateways: [mesh, istio-system/egress-partner]
tls:
- match:
- gateways: [mesh]
port: 443
sniHosts: [api.partner.example.com] # 앱 ClientHello의 SNI로 매치
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
subset: partner # -> DR-hop1
port: { number: 443 }
tcp:
- match:
- gateways: [istio-system/egress-partner]
port: 8443
route:
- destination:
host: api.partner.example.com # -> DR-hop2 (tls 없음 = raw forward)
port: { number: 443 }
```
**정렬 지도** — 한 글자 어긋나면 조용히 깨지는 문자열:
```
외부 host : SE.hosts == GW.servers.hosts == VS.hosts == VS leg-1 sniHosts
== DR-hop1 sni == DR-hop2 host
gw 대상 : DR-hop1 host(레지스트리 FQDN) == VS leg-1 destination.host
subset : DR-hop1 subsets[].name == VS leg-1 destination.subset
포트 체인 : Service 443 -> targetPort 8443 == GW.port == VS leg-2 match port
(DR-hop1 portLevelSettings와 VS leg-1 dest는 Service 포트 443 기준)
```
## 4. 검증 절차 — 홉과 프록시를 어긋나게 잡지 말 것
[DR 정본](/docs/istio/egress/destinationrule-fundamentals/) §08의 3단(설정 저장 → cluster 결부 → 실사용)을 홉별로 올바른 pod에서 실행한다. **홉 1은 클라이언트 sidecar에서, 홉 2는 gateway pod에서** — 어긋나게 잡으면 영원히 "미적용"으로 보인다.
```bash
# 홉 1 — 클라이언트 sidecar: 풀 + ISTIO_MUTUAL + sni가 subset cluster에 붙었나
istioctl proxy-config cluster deploy/ -n mesh-test \
--fqdn istio-egressgateway.istio-system.svc.cluster.local -o json | \
jq '.[] | select(.name | contains("|partner|")) |
{name, max: .circuitBreakers.thresholds[0].maxConnections,
ka: .upstreamConnectionOptions.tcpKeepalive,
sni: .transportSocket.typedConfig.sni}'
# 홉 2 — gateway pod: 풀은 붙고 transportSocket은 "없어야" 한다 (raw TCP의 시그니처)
istioctl proxy-config cluster deploy/istio-egressgateway -n istio-system \
--fqdn api.partner.example.com -o json | \
jq '.[] | {name, max: .circuitBreakers.thresholds[0].maxConnections,
ka: .upstreamConnectionOptions.tcpKeepalive,
transportSocket: (.transportSocket // "ABSENT (raw TCP)")}'
# 경유 증명 — 200이 아니라 이것이 완료 조건
kubectl -n istio-system logs deploy/istio-egressgateway --tail=5 | \
grep 'outbound|443||api.partner.example.com'
```
실측(T91)에서는 위 절차로 다음을 확인했다. 식별값 111(DR-hop1)은 **클라이언트 sidecar**의 gateway행 subset cluster에만, 222(DR-hop2)는 **gateway**의 외부 host cluster에만 나타났다 — 풀이 홉별로 정확히 갈라져 발효된다는 뜻이다. 같은 덤프에서 홉 2 cluster에는 `transportSocket`(TLS 설정)이 아예 없었고(= raw TCP의 시그니처), E2E 호출에서는 외부 서버가 앱이 보낸 **원본 SNI를 그대로** 봤으며 클라이언트는 **외부 서버의 인증서를 직접** 봤다 — 경로 중간의 누구도 TLS를 다시 만들지 않았다는 증거다. gateway listener는 `requireClientCertificate: true`로 홉 1의 신원 확인을 강제하고 있었다.
## 5. 함정
- **portLevelSettings는 통째 교체.** DR-hop1처럼 포트 엔트리를 쓰면 그 포트 cluster는 top-level trafficPolicy를 상속하지 않는다. `tls`만 적고 `connectionPool`을 빼먹으면 풀이 기본값으로 회귀 — **트래픽이 타는 포트 엔트리에 전부 재기재** ([DR 정본](/docs/istio/egress/destinationrule-fundamentals/) §05).
- **`exportTo: ["."]`는 같은 ns 안에서는 안 가린다.** T91에서 gateway와 같은 ns의 클라이언트 sidecar에도 DR-hop2가 컴파일됐다(무해 — VS tls 라우트가 트래픽을 먼저 gateway로 우회시킴). 표준 배치(gateway는 istio-system, 클라이언트는 앱 ns)에서는 의도대로 타 ns를 가린다.
- **`http.*` 풀 설정을 넣어도 조용히 무의미.** 두 홉 모두 TCP proxy 라우트라 HTTP 커넥션 풀 개념이 없다. "maxRequestsPerConnection이 안 먹어요"는 버그가 아니라 패턴의 귀결 — 요청 단위 다이얼이 필요하면 origination 계열로 가야 한다.
- **outlierDetection은 다중 IP 목적지일 때만.** 단일 IP 외부에 켜면 ejection = 채널 전체 차단 ([TCP 처방전](/docs/istio/egress/tcp-tuning/), T14).
- 그 밖의 egress 공통 함정 세 가지도 이 패턴에 그대로 적용된다: ① **DR host 문자열이 레지스트리와 다르면 에러 없이 통째로 무시**된다 — 증상은 "설정했는데 기본값"(`proxy-config cluster`에서 DR 결부가 안 보임). ② **VS 홉 1 매칭이 어긋나면** `outboundTrafficPolicy: ALLOW_ANY`에선 sidecar가 gateway를 건너뛰고 직접 외부로 나간다 — 호출은 200이라 겉보기 멀쩡하지만 신원 확인이 0겹이 된다(그래서 §4의 "완료 조건 = gateway access log"). ③ **SNI 정렬 붕괴**(DR `sni` ≠ Gateway `hosts` ≠ VS `sniHosts`)는 연결 리셋으로 나타난다. 상세 메커니즘·진단 절차는 [이중 mTLS 가이드](/docs/istio/egress/double-mtls-gateway-connection/) §4.
---
## 핵심 정리
- **홉 2 "일반 TCP" = `tls.mode`를 고르는 게 아니라 생략하는 것.** DR 미생성 / tls 없는 풀 전용 DR / `DISABLE` 명시 — 셋 다 동치. `tls.mode: tcp`는 존재하지 않아 CRD가 거부한다.
- **connectionPool은 두 홉 모두 유효하고, 발효 위치가 갈린다** — 홉 1 = 호출자 sidecar(pod당 상한), 홉 2 = gateway(전사 합류 상한). origination 계열(T90)과 동일 원칙의 passthrough 실측 확인(T91).
- **이 패턴의 풀은 `tcp.*`만.** 두 홉 다 TCP proxy라 `http.*`는 적용 대상이 없다.
- **검증은 홉과 pod를 맞춰서** — 홉 1은 sidecar, 홉 2는 gateway. 홉 2 cluster에 `transportSocket`이 없는 것이 raw TCP의 시그니처이자 정상이다.
---
## 검증 기록 (2026-07-05 · Istio 1.30.0 / k8s 1.30.6)
T91: 전용 egress gateway(주입 템플릿, Service 8443) + mesh 밖 echo 서버(self-signed HTTPS)로 본문 배선을 E2E 재현. 원자료: [workloads.yaml](files/verify/T91/workloads.yaml) · [wiring.yaml](files/verify/T91/wiring.yaml) · [dr-mode-tcp-invalid.yaml](files/verify/T91/dr-mode-tcp-invalid.yaml) · [run.sh](files/verify/T91/run.sh) · [result.txt](files/verify/T91/result.txt) · [verdict.json](files/verify/T91/verdict.json)
| # | 주장 | 실측 결과 | 판정 |
|---|---|---|---|
| N1 | `tls.mode: tcp`는 존재하지 않음 | apply 즉시 CRD validation 거부 — enum `DISABLE/SIMPLE/MUTUAL/ISTIO_MUTUAL` | ✅ 지지 |
| E1 | inner TLS end-to-end 보존 | 200. 클라이언트가 본 서버 cert = 외부 서버의 self-signed 원본(재종단 없음), 서버가 본 SNI = 앱 ClientHello 원형, `clientCertificate: {}` | ✅ 지지 |
| P1 | gateway 경유 | 서버가 본 peer IP = gateway pod IP, gateway access log `outbound\|443\|\|` 기록, `istio_tcp_*`만 생성(L7 지표 없음) | ✅ 지지 |
| C1 | DR-hop1 풀 → 호출자 sidecar | 식별값 max=111·3s·keepalive 300/30/3이 **클라이언트 sidecar**의 subset cluster에 컴파일 (+SDS `default`, sni) | ✅ 지지 |
| C2 | DR-hop2 풀 → gateway, TLS 0겹 | 식별값 max=222·keepalive가 **gateway**의 외부 host cluster에 컴파일, `transportSocket` 부재 | ✅ 지지 |
| S1 | 홉 1 SPIFFE 강제 | gateway 8443 listener `requireClientCertificate: true` | ✅ 지지 |
| B1 | `exportTo: ["."]` 스코프 | 같은 ns 클라이언트 sidecar에도 DR-hop2 컴파일(타 ns만 차단) — §5에 반영 | ✅ 지지 (+정밀화) |
검증 환경 특이사항: ① 이 클러스터는 istiod `--domain homelab.local`이라 DR-hop1 host를 `*.svc.homelab.local`로 기재(본문 예시는 표준 `cluster.local` 기준 — 반드시 `istioctl proxy-config cluster`에 보이는 레지스트리 이름과 일치시킬 것). ② gateway Envoy 네이티브 per-cluster stats(`upstream_cx_total`)는 기본 statsMatcher에 걸러져 안 보였고, 사용 증명은 access log + `istio_tcp_*` 텔레메트리로 대체(출처 미확인 추정 — 설정 증명은 cluster JSON `circuitBreakers.thresholds`로 충족).
---
## 참조
**아카이브 내부**
- [Egress HTTPS 패턴 지도](/docs/istio/egress/https-pattern-map/) — 용어 정립·4패턴 CRD 시그니처
- [mTLS Passthrough 해부](/docs/istio/egress/https-over-mtls/) — 이 패턴의 데이터 경로·CRD 4종 정본 (T07)
- [이중 mTLS — 홉마다 DR 한 벌](/docs/istio/egress/double-mtls-gateway-connection/) — 자매 패턴(origination)·발효 위치 원칙의 출처 (T90)
- [DestinationRule 만들기](/docs/istio/egress/destinationrule-fundamentals/) — host 매칭·병합·검증 3단
- [Egress TCP 처방전](/docs/istio/egress/tcp-tuning/) · [tcpKeepalive 필드 노트](/docs/istio/egress/tcp-keepalive-fields/) — 값 도출식
## 출처
- ↗ [Istio: DestinationRule reference — ClientTLSSettings.TLSmode](https://istio.io/latest/docs/reference/config/networking/destination-rule/#ClientTLSSettings-TLSmode) — mode enum 4종 (2026-07-05 대조)
- ↗ [Istio: DestinationRule reference — ConnectionPoolSettings](https://istio.io/latest/docs/reference/config/networking/destination-rule/#ConnectionPoolSettings) — tcp/http 설정 적용 범위 (2026-07-05 대조)