Istio 서비스 메시 · 트래픽 관리 · 실습
라우팅 규칙과 복원력 설정 쓰기
목표
VirtualService 로 요청을 조건에 따라 나누고, DestinationRule 로 대상의 성질과 복원력을 정하는 감각을 손에 넣습니다.
왜 중요한가
두 리소스의 역할 분리는 취향이 아니라 운영 구조입니다. 배포 파이프라인이 매번 건드리는 것은 라우팅(VirtualService)이고, 서비스 소유자가 한 번 정해 오래 두는 것은 대상의 성질(DestinationRule)입니다. 이 경계를 흐리면 배포 때마다 연결 풀 설정까지 함께 흔들립니다. 그리고 매칭 순서와 subset 의 라벨 일치, 이 두 가지가 메시 트러블슈팅의 절반입니다. 조건 없는 기본 경로를 위에 두면 아래 규칙이 죽고, subset 라벨이 파드 라벨과 어긋나면 엔드포인트가 비어 503(UH)이 납니다. 복원력 설정도 감으로 정하면 안 됩니다 — 전체 타임아웃이 시도 시간의 합보다 짧으면 재시도는 한 번도 못 하고 끝나고, 격리 상한이 없으면 서킷 브레이커가 전면 장애를 만듭니다.
이 환경에서는 패킷이 흐르지 않으므로, 채점은 매니페스트의 구조와 istioctl analyze 결과를 봅니다.
단계
시작 전 준비. 실습 파드는 실습마다 새로 뜨므로 앞 실습에서 설치한 메시 설정은 남아 있지 않습니다. kubectl get crd virtualservices.networking.istio.io 가 비어 있으면 먼저 istioctl manifest generate --set profile=minimal > /root/istio/manifest.yaml 로 매니페스트를 만들고 kubectl apply -f /root/istio/manifest.yaml 을 두 번 실행하세요(CRD 가 먼저 등록된 뒤에야 나머지가 붙습니다). 그다음 kubectl create ns mesh-lab && kubectl label ns mesh-lab istio-injection=enabled 로 네임스페이스를 준비합니다.
1. /opt/lab/fixtures/istio/workload-v1v2.yaml 을 mesh-lab 네임스페이스에 적용하세요. Service reviews 의 첫 포트 이름은 http 여야 하고, Deployment reviews-v1·reviews-v2 의 파드 라벨은 각각 app: reviews 와 version: v1/version: v2 여야 합니다.
2. mesh-lab 에 DestinationRule reviews 를 만드세요. spec.host 는 reviews 이고, spec.subsets 에 이름이 v1(labels: {version: v1})과 v2(labels: {version: v2})인 subset 두 개를 두세요.
3. mesh-lab 에 VirtualService reviews 를 만드세요. spec.hosts 에 reviews 를 두고, spec.http 의 마지막 항목에는 match 를 넣지 말고 destination 을 host: reviews, subset: v1 로 두세요.
4. 같은 VirtualService 의 앞쪽에 조건부 라우트를 추가하세요. 조건은 헤더 end-user 가 정확히 labhub-tester 인 경우이고, 목적지는 subset: v2 입니다. 이 라우트는 마지막 기본 경로보다 위에 있어야 합니다.
5. mesh-lab 에 ratings 워크로드를 만드세요 — Service ratings(포트 이름 http, 포트 9080)와 Deployment ratings-v1(파드 라벨 app: ratings, version: v1). 그다음 VirtualService ratings 를 만들어 match 의 uri.prefix 를 /api/ratings 로, rewrite.uri 를 /ratings 로 두고 destination 은 host: ratings 로 하세요.
6. 같은 VirtualService ratings 의 라우트에 timeout: 3s 와 retries 를 붙이세요. attempts: 3, perTryTimeout: 1s, retryOn 에는 5xx, connect-failure 를 포함하세요. 그리고 /root/istio/traffic/out/retry-note.txt 에 멱등하지 않은 요청(POST 등)을 재시도하면 왜 위험한지 적으세요.
7. mesh-lab 에 DestinationRule ratings 를 만들고 trafficPolicy.outlierDetection 에 consecutive5xxErrors: 5, interval: 10s, baseEjectionTime: 30s, maxEjectionPercent: 50 을 넣으세요. 또 VirtualService ratings 에 fault.delay 를 추가해 percentage.value: 10, fixedDelay: 2s 로 두세요.
8. istioctl analyze -n mesh-lab 결과를 /root/istio/traffic/out/analyze.txt 에 저장하세요(Error [ 가 남으면 안 됩니다). 그리고 /root/istio/traffic/out/routes.json 을 만드세요. routes 배열의 길이는 실제 VirtualService reviews 의 spec.http 항목 수와 같아야 하고, 배열의 마지막 원소에는 match 키를 넣지 마세요. default_subset 키의 값은 v1 입니다. mesh-lab 에는 VirtualService 가 2개 이상이어야 합니다.
참고
- 실습 파드는 실습마다 새로 뜨므로 앞 실습의 클러스터 상태는 남아 있지 않습니다. 그래서 메시 설정을 매니페스트로 남겨 두는 것이 곧 재현 가능성입니다. 선언적 설정의 가치가 추상적인 원칙이 아니라 이 실습에서 바로 체감되는 이유입니다.
kubectl apply -f - -n mesh-lab로 표준 입력에서 바로 적용할 수 있습니다. 적용 뒤에는kubectl get virtualservice reviews -n mesh-lab -o yaml로 실제 저장된 모습을 확인하세요.- 8번의 라우트 개수는
kubectl get virtualservice reviews -n mesh-lab -o json | jq '.spec.http | length'로 뽑으면 실수가 없습니다. - 5번에서 대상 워크로드를 만들지 않고 VirtualService 만 만들면 정적 분석이 "참조한 호스트를 찾을 수 없음" 오류를 냅니다. 8번이 그 오류를 잡아냅니다.
- 흔한 실수 1: 조건부 라우트를 배열 맨 뒤에 두는 것. 기본 경로가 먼저 잡아채 버려 조건이 무의미해집니다.
- 흔한 실수 2: subset 에
labels를 빠뜨리고 이름만 적는 것. 이름은 Envoy 클러스터 이름에 쓰일 뿐, 파드를 고르는 것은 라벨입니다.
단계 8개
- 대상 워크로드와 버전 라벨 올리기
- 버전별 subset 정의하기
- 기본 경로를 v1 으로 보내기
- 헤더 조건으로 v2 로 보내기
- 경로 접두어 매칭과 재작성
- 타임아웃과 재시도 붙이기
- 이상치 감지와 결함 주입
- 설정 검증하고 라우트 순서 정리하기