LabHub

Istio 심화 — 왜 그렇게 흐르는가 · 네 리소스의 역할 · 이론

무엇이 무엇을 담당하나

LabHub 에서 이어서 보기

한 줄 요약

VirtualService 는 "어디로 보낼지" 를, DestinationRule 은 "보낸 뒤 어떻게 다룰지" 를 정한다. 카나리 배포에 둘 다 필요한 이유가 이것이다.

왜 이게 필요했나

Istio 를 처음 쓰면 대부분 이 실수를 한다.

# VirtualService 만 쓴 카나리 — 동작하지 않는다http:  - route:      - destination: { host: shop, subset: v1 }        weight: 90      - destination: { host: shop, subset: v2 }        weight: 10

subset: v1 이 무엇을 가리키는지 아무도 모른다. 서브셋은 DestinationRule 에서 정의한다.

# DestinationRule — 서브셋의 정의spec:  host: shop  subsets:    - name: v1      labels: { version: v1 }    - name: v2      labels: { version: v2 }

이제야 v1 이 version: v1 라벨이 붙은 파드를 뜻하게 된다. 앞 코스에서 본 Envoy 용어로 옮기면 — DestinationRule 의 subset 이 클러스터를 만들고(outbound|8080|v1|shop...), VirtualService 의 weight 가 라우트의 가중치가 된다.

네 리소스

| 리소스 | 하는 일 | Envoy 로는 |
|---|---|---|
| Gateway | 메시 바깥에서 들어오는 트래픽의 입구(포트·호스트·TLS) | Listener |
| VirtualService | 어떤 요청을 어디로 보낼지(매칭·가중치·재시도·타임아웃) | Route |
| DestinationRule | 목적지를 어떻게 다룰지(서브셋·LB·커넥션풀·이상치·TLS) | Cluster |
| ServiceEntry | 메시가 모르는 외부 서비스를 목록에 등록 | Cluster + Endpoint |

Gateway 는 입구만 연다. Gateway 하나로는 트래픽이 흐르지 않는다 — 그 Gateway 를 gateways: 로 참조하는 VirtualService 가 있어야 비로소 라우팅이 생긴다. 이것도 흔한 함정이다.

mTLS 는 언제 걸리나

PeerAuthentication 이 mode 를 정한다.

| mode | 뜻 |
|---|---|
| PERMISSIVE | 평문도 mTLS 도 받는다 (기본값, 마이그레이션용) |
| STRICT | mTLS 만 받는다 |
| DISABLE | mTLS 안 씀 |

기본이 PERMISSIVE 인 이유는 사이드카가 없는 파드가 남아 있을 수 있어서다. 그래서 "Istio 를 깔았으니 암호화된다" 는 말은 틀렸다. STRICT 로 바꾸기 전까지는 평문도 그대로 통한다.

STRICT 로 바꿀 때 흔히 깨지는 것: 사이드카가 없는 파드(예: Job), 헬스체크를 보내는 kubelet, 그리고 메시 밖의 모니터링. kubelet 은 Istio 가 프로브 경로를 우회시켜 처리하지만, 직접 만든 체크 스크립트는 깨진다.

흔한 착각

"Istio 를 넣으면 관측성이 생긴다" — 사이드카가 내는 지표는 L7 요청 지표(요청 수·지연·상태코드)다. 애플리케이션 안에서 무슨 일이 있었는지는 여전히 모른다. 트레이스도 마찬가지로, 사이드카는 스팬을 만들지만 애플리케이션이 헤더를 이어 주지 않으면 체인이 끊긴다. 코드를 안 고쳐도 되는 것은 아니다.

실무에서 진짜 중요한 것

설정이 의도대로 갔는지는 프록시에게 묻는다.

istioctl analyze                     # 정적 검사 — 서브셋 미정의 같은 것을 잡는다istioctl proxy-status                # 각 사이드카가 최신 설정을 받았나(SYNCED)istioctl proxy-config route <pod>    # 실제로 받은 라우트istioctl proxy-config cluster <pod> --fqdn shop.default.svc.cluster.local

proxy-statusSTALE 이면 설정이 아직 안 갔다는 뜻이고, 그때 YAML 을 아무리 봐도 소용없다.