デプロイする前に間違いを見つける
한국어 원문으로 표시합니다.
목표
Istio 설정은 문법이 맞아도 동작하지 않는 경우가 대부분입니다. 이름이 서로를 가리키는 구조라서, 한쪽 이름만 바뀌어도 조용히 끊깁니다.
이 실습은 클러스터 없이 배포하기 전에 그런 것들을 찾아냅니다.
두 도구의 차이
| 보는 것 | 잡는 것 | |
|---|---|---|
istioctl validate |
한 파일의 문법 | 오타, 알 수 없는 필드 |
istioctl analyze |
리소스 사이의 참조 | 없는 subset·게이트웨이, 호스트 충돌 |
쿠버네티스는 둘 다 안 잡아 줍니다. CRD 스키마에서 알 수 없는 필드는 조용히
버려지므로 kubectl apply 는 성공하고 트래픽만 안 흐릅니다.
쓰는 법
istioctl validate -f vs.yaml
istioctl analyze --use-kube=false vs.yaml dr.yaml
echo $? # 0 이면 깨끗, 79 면 문제 있음
--use-kube=false 는 클러스터를 안 보고 파일만 본다는 뜻입니다.
단계
- 오타 →
01-validate.txt - 참조가 깨진 것 →
02-analyze.txt - 고쳐서 통과 →
vs.yaml,dr.yaml - 호스트 충돌 →
04-conflict.txt - 없는 게이트웨이 →
05-gateway.txt - 사이드카 주입 →
06-inject.txt - analyze 가 못 잡는 것 →
07-blind.txt - 정리 →
08-notes.md
참고
7단계는 아무 문제도 안 나오는 것이 정답입니다. 정적 분석의 한계를 직접 보는 것이 목적입니다.
오타를 잡는다
필드 이름이 틀린 VirtualService 를 만들고 istioctl validate 로 잡아 01-validate.txt 에 남기세요.
http: 아래를 route: 대신 rout: 으로 써 보세요. istioctl validate -f x.yaml 이 unknown field "rout" 이라고 알려 줍니다. 쿠버네티스는 이걸 안 잡아 줍니다 — CRD 스키마에서 알 수 없는 필드는 조용히 버려지므로, apply 는 성공하고 트래픽만 안 흐릅니다.
스키마는 맞는데 동작은 틀린 것
subset: v1 로 보내는 VirtualService 만 만들고(DestinationRule 없이) istioctl analyze 가 잡아내게 해 02-analyze.txt 에 남기세요.
istioctl analyze --use-kube=false vs.yaml. IST0101 Referenced host+subset in destinationrule not found 가 나옵니다. validate 는 통과하는데 analyze 는 잡습니다 — 앞은 문법, 뒤는 참조 관계를 봅니다. Istio 에서 '설정은 넣었는데 503' 의 1번 원인입니다.
고쳐서 통과시킨다
subset 을 정의한 DestinationRule 을 추가해 istioctl analyze 가 종료 코드 0 으로 끝나게 하세요. 파일 이름은 vs.yaml 과 dr.yaml 로 합니다.
DestinationRule 의 host 는 VirtualService 의 destination.host 와 같아야 하고, subsets[].name 이 destination.subset 과 같아야 합니다. 확인: istioctl analyze --use-kube=false vs.yaml dr.yaml; echo $? — 0 이어야 합니다(문제가 있으면 79).
같은 호스트를 둘이 잡으면
같은 호스트를 가리키는 VirtualService 를 하나 더 만들어 충돌을 내고 04-conflict.txt 에 남기세요.
IST0109 가 나옵니다 — 'define the same host ... which can lead to undefined behavior'. 어느 쪽이 이길지 정해져 있지 않습니다. 팀이 둘로 나뉘어 각자 VirtualService 를 만들면 이 일이 납니다. 해결은 하나로 합치는 것입니다.
없는 게이트웨이를 가리키면
존재하지 않는 게이트웨이를 참조하는 VirtualService 를 만들어 05-gateway.txt 에 남기세요. 두 종류의 진단이 나와야 합니다.
gateways: [nope-gw]. IST0101 Referenced gateway not found 와 IST0132(호스트가 게이트웨이에 없음)가 함께 나옵니다. 둘 다 남기세요.
사이드카가 실제로 어떻게 생기나
Deployment 하나에 사이드카를 주입하고, 주입 뒤 컨테이너 목록을 06-inject.txt 에 남기세요.
이 파드에는 진짜 istiod 가 없으므로 설정을 파일로 넘깁니다. 세 개가 다 있어야 합니다 — 둘만 주면 istioctl 이 나머지 하나를 찾아 클러스터로 나갑니다.
istioctl kube-inject -f dep.yaml \
--injectConfigFile /opt/istio/inject-config.yaml \
--meshConfigFile /opt/istio/mesh-config.yaml \
--valuesFile /opt/istio/values-config.yaml
istio-proxy 컨테이너와 istio-init 초기화 컨테이너가 붙습니다. istio-init 이 iptables 를 고쳐서 모든 트래픽이 프록시를 지나게 만드는 쪽입니다.
analyze 가 못 잡는 것
PeerAuthentication 을 STRICT 로, 같은 서비스의 DestinationRule 을 tls.mode: DISABLE 로 두고 istioctl analyze 를 돌려 아무 문제도 안 나오는 것을 07-blind.txt 에 남기세요. 왜 위험한지도 한 줄 적으세요.
analyze 는 깨끗하다고 하지만 실제로는 서버는 mTLS 를 요구하는데 클라이언트는 평문으로 붙어서 전부 실패합니다. 정적 분석이 만능이 아니라는 뜻입니다 — 파일만 봐서는 알 수 없고 클러스터 상태와 함께 봐야 하는 것들이 있습니다. 그래서 실무에서는 istioctl analyze 를 클러스터에 붙여서(--use-kube 기본값) 돌립니다.
세 가지를 정리한다
08-notes.md 에 세 줄 이상. validate 와 analyze 의 차이, 같은 호스트 충돌이 위험한 이유, 정적 분석이 못 잡는 것 하나.
본문에 참조, 충돌, mTLS 가 들어가야 합니다.