ICA — 이스티오 인증 어소시에이트 · 트래픽 관리 · 실습
복원력 설정값 산정하기
목표
재시도·타임아웃·서킷브레이커·장애 주입·미러링을 직접 작성하면서, 각 값이 서로 어떤 제약을 거는지 이해합니다.
왜 중요한가
복원력 설정은 복사해 오면 대개 동작하지 않거나, 더 나쁘게는 장애를 증폭시킵니다. 재시도를 호출 체인의 모든 계층에 걸면 3단 체인에서 최악의 경우 9배, 4단이면 27배의 요청이 가장 안쪽 서비스로 몰립니다. 이미 죽어가는 서비스에 재시도가 마지막 일격이 되는 구조입니다.
타임아웃도 마찬가지입니다. timeout 은 재시도를 포함한 전체 데드라인이므로 perTryTimeout x (attempts + 1) 보다 작으면 재시도 설정이 장식이 됩니다. 반대로 바깥 계층의 타임아웃이 안쪽보다 짧으면, 안쪽이 성실하게 처리 중인데 바깥이 먼저 끊고 재시도해 "절대 완료될 수 없는 작업"을 반복하게 만듭니다.
서킷브레이커는 값이 너무 크면 사실상 꺼진 것과 같고, 너무 작으면 평시에도 503 이 납니다. 그래서 실측 동시성을 기준으로 산정하고, maxEjectionPercent 로 안전판을 둡니다. 이 실습은 그 감각을 매니페스트로 옮기는 훈련입니다.
Kubernetes 기본 리소스는 실제로 apply 하고, Istio CRD 는 /root/ica-resilience/ 아래 파일로 작성합니다.
단계
1. 네임스페이스 ica-resilience 를 만들고 라벨 istio-injection=enabled 를 붙이세요.
2. 네임스페이스 ica-resilience 에 디플로이먼트 inventory 를 3 레플리카로 배포하세요. 파드 라벨은 app=inventory, 이미지는 nginx:1.27-alpine 입니다.
3. 같은 네임스페이스에 서비스 두 개를 만드세요. inventory 와 inventory-canary 이며 둘 다 포트 8080, 포트 이름 http 입니다. inventory 의 selector 는 app=inventory 입니다.
4. /root/ica-resilience/vs-inventory-retry.yaml 에 VirtualService 를 작성하세요. spec.hosts[0] 은 inventory.ica-resilience.svc.cluster.local, http 규칙에 timeout: 3s, retries.attempts: 2, retries.perTryTimeout: 1s, retries.retryOn 에는 5xx 와 connect-failure 를 포함하세요.
5. /root/ica-resilience/vs-inventory-fault.yaml 에 VirtualService 를 작성하세요. 규칙 두 개입니다. 첫 규칙은 헤더 x-chaos-test 가 true 인 요청에만 적용되며 fault.delay.fixedDelay: 3s / fault.delay.percentage.value: 50 / fault.abort.httpStatus: 503 / fault.abort.percentage.value: 10 을 갖습니다. 두 번째 규칙은 match 도 fault 도 없이 그냥 라우팅만 합니다.
6. /root/ica-resilience/dr-inventory.yaml 에 DestinationRule 을 작성하세요. spec.host 는 inventory.ica-resilience.svc.cluster.local 이고 trafficPolicy 아래에 outlierDetection(consecutive5xxErrors 5, interval 10s, baseEjectionTime 30s, maxEjectionPercent 50)과 connectionPool(tcp.maxConnections 100, http.http1MaxPendingRequests 50)을 둡니다.
7. /root/ica-resilience/vs-inventory-mirror.yaml 에 VirtualService 를 작성하세요. inventory.ica-resilience.svc.cluster.local 로 100% 라우팅하면서 inventory-canary.ica-resilience.svc.cluster.local 로 20% 미러링하고, 전체 timeout 은 5s 로 둡니다.
참고
retryOn은 쉼표로 이어 붙인 문자열입니다.5xx,connect-failure,reset처럼 씁니다.percentage는value필드를 가진 객체입니다. 숫자만 덜렁 쓰면 안 됩니다.- 흔한 실수 1: 장애 주입 규칙에 catch-all 을 만들지 않아 헤더 없는 일반 트래픽이 갈 곳을 잃는 것.
- 흔한 실수 2: 미러링에 weight 두 개를 주는 것. 미러는 응답을 버리므로 실제 route 는 하나입니다.
- 미러 요청도 DB 쓰기 같은 부수 효과를 일으킵니다. 쓰기 경로를 미러링하려면 대상 애플리케이션이 섀도 모드로 동작해야 합니다.
단계 7개
- 실습 네임스페이스 준비
- 인스턴스 3개짜리 디플로이먼트 배포
- 본 서비스와 카나리 서비스 만들기
- 타임아웃과 재시도의 관계 맞추기
- 헤더로 게이팅한 장애 주입
- 서킷브레이커 한도 정하기
- 섀도 트래픽 흘려보내기