요청 라우팅 — VirtualService로 트래픽 배분하기
요청 라우팅 — VirtualService로 트래픽 배분하기
이 태스크에서는 마이크로서비스의 여러 버전으로 요청을 동적으로 라우팅하는 방법을 다뤄요. Istio의 VirtualService 규칙 하나만으로 "모든 트래픽은 v1로" 같은 단순한 배분부터 "특정 사용자는 v2로" 같은 헤더 기반 라우팅까지 손쉽게 표현할 수 있어요. 카나리 배포나 A/B 테스트의 출발점이 되는 주제이기도 하죠.
시작하기 전에
- 설치 가이드를 따라 Istio를 설치해요.
- Bookinfo 샘플 애플리케이션을 배포해요.
- Traffic Management 개념 문서를 훑어봐요.
이 태스크가 풀려는 문제
Bookinfo 샘플은 각각 여러 버전을 가진 네 개의 마이크로서비스로 이뤄져 있어요. 그중 reviews 서비스만 v1/v2/v3 세 버전이 동시에 떠 있죠. 브라우저로 http://$GATEWAY_URL/productpage($GATEWAY_URL은 인그레스의 External IP)를 몇 번 새로고침해 보면, 리뷰에 별점이 나왔다 안 나왔다 하는 게 보여요.
이유는 명시적인 기본 라우팅 규칙이 없을 때 Istio가 모든 버전으로 요청을 round robin으로 돌리기 때문이에요. 이 태스크의 첫 목표는 모든 트래픽을 마이크로서비스의 v1로 보내는 규칙을 적용하는 거고, 그다음엔 HTTP 요청 헤더 값을 기준으로 라우팅하는 규칙을 만들어 볼 거예요.
v1으로 라우팅하기
Istio는 가상 서비스(virtual service)로 라우팅 규칙을 정의해요. 다음 명령으로 모든 트래픽을 각 마이크로서비스의 v1로 보내는 가상 서비스를 적용해요.
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
설정 전파가 eventual consistency라 몇 초 기다려야 가상 서비스가 적용돼요. 적용된 라우트를 확인해 볼게요.
$ kubectl get virtualservices -o yaml
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- details
http:
- route:
- destination:
host: details
subset: v1
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- productpage
http:
- route:
- destination:
host: productpage
subset: v1
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
- apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
대응되는 subset 정의는 다음 명령으로 볼 수 있어요.
$ kubectl get destinationrules -o yaml
이제 Bookinfo 마이크로서비스, 특히 reviews 서비스가 모두 v1로 라우팅되도록 설정된 거예요.
새 라우팅 설정 테스트
다시 /productpage를 새로고침해 보면, 몇 번을 새로고침해도 reviews 영역에 별점이 나오지 않는 걸 볼 수 있어요. reviews의 모든 트래픽을 reviews:v1로 보내도록 설정했고, 이 버전은 별점 서비스를 호출하지 않기 때문이에요.
사용자 ID 기반 라우팅
이번엔 특정 사용자의 트래픽만 특정 버전으로 보내는 규칙을 만들어 볼게요. 여기선 jason이라는 사용자의 모든 트래픽을 reviews:v2로 보내요.
이 예시는 productpage 서비스가 reviews 서비스로 나가는 모든 아웃바운드 HTTP 요청에 커스텀 end-user 헤더를 추가한다는 점 덕분에 동작해요. 별점 기능이 포함된 버전은 reviews:v2라는 점을 기억해 두세요.
인그레스 게이트웨이에서 강하게 인증된 JWT 기반 라우팅도 지원하는데, 자세한 내용은 JWT claim 기반 라우팅 문서를 참고해요.
사용자 기반 라우팅을 켜는 명령을 실행해요.
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml@
규칙이 만들어졌는지 확인해 볼게요.
$ kubectl get virtualservice reviews -o yaml
apiVersion: networking.istio.io/v1
kind: VirtualService
...
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
이제 Bookinfo의 /productpage에서 사용자 jason으로 로그인하고 새로고침하면 리뷰마다 별점이 보여요. 다른 이름으로 로그인해서 새로고침하면 별점이 사라져요. jason을 제외한 모든 사용자는 reviews:v1로 라우팅되기 때문이죠. 이렇게 사용자 ID 기반 라우팅도 완성했어요.
무슨 일이 벌어졌나
이 태스크에서 Bookinfo 서비스 각각의 v1로 트래픽의 100%를 보내는 규칙을 적용했고, 그다음 productpage 서비스가 요청에 추가한 커스텀 end-user 헤더를 기준으로 reviews 서비스의 v2로 선택적으로 보내는 규칙을 설정했어요.
쿠버네티스 서비스가 Istio의 L7 라우팅 기능을 쓰려면 몇 가지 제약을 지켜야 해요. Pods와 Services의 요구사항 문서를 참고하세요. 이어지는 traffic shifting 태스크에서는 여기서 배운 패턴을 그대로 써서 한 버전에서 다른 버전으로 트래픽을 점진적으로 옮기는 법을 다뤄요.
정리
적용한 라우팅 규칙을 제거해요.
$ kubectl delete -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
뒤이어 배울 태스크가 없다면 Bookinfo 정리 지침대로 애플리케이션을 종료해요.