LabHub

Istio 서비스 메시 · 카나리와 트래픽 분할 · 실습

가중치·헤더·미러링으로 카나리 굴리기

LabHub 에서 이어서 보기

목표

가중치·헤더·미러링 세 가지 분할 방식을 상황에 맞게 골라 쓰고, 되돌릴 조건이 명시된 카나리 계획을 만들 수 있게 됩니다.

왜 중요한가

카나리의 본질은 "조금 준다"가 아니라 "언제 멈출지를 먼저 정한다" 입니다. 가중치를 올리는 일은 누구나 할 수 있지만, 나쁜 지표를 보고 되돌리는 판단은 사람에게 맡기면 흔들립니다. 그래서 단계마다 판단 기준을 적어 두고, 그 기준이 곧 자동화의 입력이 되게 만듭니다. 또 하나 중요한 것은 파드 개수와 트래픽 비율의 분리입니다. 메시에서는 새 버전을 다 띄워 놓고도 트래픽은 0% 로 둘 수 있고, 문제가 보이면 배포 없이 가중치만 0 으로 되돌릴 수 있습니다.

이 실습은 두 종류의 채점이 섞여 있습니다. 1·2·4·5번은 저장된 파일을 보고, 6·7·8번은 클러스터에 실제로 적용된 상태를 봅니다. 그래서 단계마다 파일을 따로 남겨야 하고, 하나를 계속 덮어쓰면 앞 단계가 다시 실패합니다. 각 vs-*.yaml 파일에는 VirtualService 문서 하나만 넣으세요(여러 문서를 한 파일에 담으면 채점이 첫 문서를 특정하지 못합니다).

단계

시작 전 준비. 실습 파드는 실습마다 새로 뜨므로 앞 실습의 메시 설정은 남아 있지 않습니다. kubectl get crd virtualservices.networking.istio.io 가 비어 있으면 istioctl manifest generate --set profile=minimal > /root/istio/manifest.yamlkubectl apply -f /root/istio/manifest.yaml두 번 실행하고, kubectl create ns mesh-lab && kubectl label ns mesh-lab istio-injection=enabled 로 네임스페이스를 만드세요. 6번은 살아 있는 파드를 라벨로 조회하므로 픽스처 워크로드의 파드가 Running 이 될 때까지 기다려야 합니다.

1. 먼저 /opt/lab/fixtures/istio/workload-v1v2.yamlmesh-lab 에 적용하고, spec.subsetsv1(labels: {version: v1}v2(labels: {version: v2})를 가진 DestinationRule reviews 를 적용해 두세요. 그다음 /root/istio/canary/vs-baseline.yaml 을 만드세요 — VirtualService 하나이며 spec.http[0].route 에 항목이 정확히 두 개, subset: v1weight 는 100, subset: v2weight 는 0 입니다.
2. /root/istio/canary/vs-90-10.yaml 을 만드세요. v1 은 weight: 90, v2 는 weight: 10 입니다(합은 100). 이 파일을 kubectl apply 하고 그 출력을 /root/istio/canary/out/applied-10.txt 에 저장하세요(configured/created/unchanged 중 하나가 보여야 합니다).
3. 가중치 합이 100 이 아닌 파일(예: /root/istio/canary/vs-bad.yaml 에 v1 90 / v2 20)을 만들어 istioctl validate -f 로 검사하고, 그 거부 메시지를 표준 에러까지 포함해 /root/istio/canary/out/weight-error.txt 에 저장하세요. 그리고 /root/istio/canary/out/weight-note.txt 에 가중치 합이 100 이어야 한다는 규칙을 적으세요.
4. /root/istio/canary/vs-header.yaml 을 만드세요. 헤더 x-canary 가 정확히 true 인 요청을 고르는 라우트를 앞쪽에 두고 목적지는 subset: v2, weight: 100 입니다. 그 뒤에 조건 없는 기본 라우트를 하나 더 두세요(조건부 라우트가 마지막이면 안 됩니다).
5. /root/istio/canary/vs-mirror.yaml 을 만드세요. spec.http[0].routesubset: v1weight: 100 이고, 같은 항목에 mirror(host: reviews, subset: v2)와 mirrorPercentage.value: 10 을 두세요. 그리고 /root/istio/canary/out/mirror-note.txt 에 미러된 요청의 응답이 버려진다는 점과 쓰기 작업의 부작용 위험을 적으세요.
6. 먼저 vs-90-10.yaml 을 다시 적용해 v1·v2 를 모두 참조하는 상태로 만드세요. 그다음 DestinationRule reviews 의 subset 이름 v2 를 잠시 v2-canary 로 바꿔 적용하고 istioctl analyze -n mesh-lab 결과를 /root/istio/canary/out/analyze-mismatch.txt 에 저장하세요. 이름을 v2(labels version: v2)로 되돌려 적용한 뒤 다시 분석해 /root/istio/canary/out/analyze-clean.txt 에 저장하세요(여기에는 Error [ 가 없어야 합니다).
7. DestinationRule reviewstrafficPolicy.loadBalancer.consistentHash.httpHeaderName: x-user-id 를 추가해 적용하세요. 그리고 /root/istio/canary/out/sticky-note.txt(50바이트 이상)에 같은 사용자가 버전 사이를 왔다 갔다 하면 왜 문제가 되는지 적으세요.
8. /root/istio/canary/rollout.yaml 을 만드세요. 최상위에 stages 배열(5단계 이상)과 rollback 키가 있어야 합니다. 각 stage 에는 weight(v2 가중치)와 criteria(다음 단계로 넘어갈 판단 기준)가 모두 있어야 하고, weight 는 0 으로 시작해 100 으로 끝나며 중간에 줄어들면 안 됩니다. 마지막으로 실제 VirtualService reviews 를 v1 50 / v2 50 으로 적용하세요(spec.http마지막 항목 기준). istioctl analyze -n mesh-lab 결과는 /root/istio/canary/out/final-analyze.txt 에 저장하고 오류가 없어야 합니다.

참고

단계 8개

  1. 100/0 시작점 매니페스트 만들기
  2. 10% 를 새 버전으로 옮기기
  3. 가중치 합이 틀렸을 때 무슨 일이 나는지 보기
  4. 내부 테스터만 새 버전으로 보내기
  5. 응답을 버리는 미러링 걸기
  6. subset 과 파드 라벨의 불일치 만들고 고치기
  7. 같은 사용자를 한 버전에 고정하기
  8. 단계별 카나리 계획 세우고 중간까지 진행하기