TCP 트래픽 이동
TCP 트래픽 이동 (TCP Traffic Shifting)
이 태스크는 마이크로서비스의 한 버전에서 다른 버전으로 TCP 트래픽을 이동하는 방법을 보여줘요.
출처: Istio 문서
본문
이 태스크는 마이크로서비스의 한 버전에서 다른 버전으로 TCP 트래픽을 이동하는 방법을 보여줘요.
일반적인 사용 사례는 마이크로서비스의 이전 버전에서 새 버전으로 TCP 트래픽을 점진적으로 마이그레이션하는 거예요. Istio에서는 트래픽의 일정 비율을 한 목적지에서 다른 목적지로 리다이렉트하는 일련의 라우팅 규칙을 설정해서 이 목표를 달성해요.
이 태스크에서는 TCP 트래픽의 100%를 tcp-echo:v1로 보낼 거예요. 그런 다음 Istio의 가중치 라우팅 기능을 사용해 TCP 트래픽의 20%를 tcp-echo:v2로 라우팅할 거예요.
Istio는 Kubernetes Gateway API를 지원하며, 향후 트래픽 관리의 기본 API로 만들려고 하고 있어요. 아래 지침을 통해 메시에서 트래픽 관리를 설정할 때 Gateway API를 쓸지 Istio 설정 API를 쓸지 선택할 수 있어요. 선호에 따라 Gateway API 탭이나 Istio APIs 탭 중 하나의 지침을 따르면 돼요.
이 문서는 실험 단계(experimental)에 있는 Gateway API 기능을 사용해서 Istio를 설정해요. Gateway API 지침을 사용하기 전에 다음을 반드시 확인해요:
-
Gateway API CRD의 실험 버전을 설치해요:
$ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.6.0" | kubectl apply -f - -
Istio를 설치할 때
PILOT_ENABLE_ALPHA_GATEWAY_API환경 변수를true로 설정해서 Istio가 alpha Gateway API 리소스를 읽도록 설정해요:$ istioctl install --set values.pilot.env.PILOT_ENABLE_ALPHA_GATEWAY_API=true --set profile=minimal -y
시작하기 전에
- 설치 가이드의 지침을 따라 Istio를 설정해요.
- 트래픽 관리(Traffic Management) 개념 문서를 검토해요.
테스트 환경 설정
-
시작하려면 TCP 트래픽 이동을 테스트할 네임스페이스를 만들어요.
$ kubectl create namespace istio-io-tcp-traffic-shifting -
요청을 보내는 테스트 소스로 사용할 curl 샘플 앱을 배포해요.
$ kubectl apply -f @samples/curl/curl.yaml@ -n istio-io-tcp-traffic-shifting -
tcp-echo마이크로서비스의v1과v2버전을 배포해요.$ kubectl apply -f @samples/tcp-echo/tcp-echo-services.yaml@ -n istio-io-tcp-traffic-shifting
가중치 기반 TCP 라우팅 적용
-
모든 TCP 트래픽을
tcp-echo마이크로서비스의v1버전으로 라우팅해요.Istio APIs
$ kubectl apply -f @samples/tcp-echo/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shiftingGateway API
$ kubectl apply -f @samples/tcp-echo/gateway-api/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting -
인그레스 IP와 포트를 확인해요:
Istio APIs
인그레스 IP와 포트 확인(Determining the ingress IP and ports) 문서의 지침을 따라
TCP_INGRESS_PORT와INGRESS_HOST환경 변수를 설정해요.Gateway API
다음 명령을 사용해서
SECURE_INGRESS_PORT와INGRESS_HOST환경 변수를 설정해요:$ kubectl wait --for=condition=programmed gtw tcp-echo-gateway -n istio-io-tcp-traffic-shifting $ export INGRESS_HOST=$(kubectl get gtw tcp-echo-gateway -n istio-io-tcp-traffic-shifting -o jsonpath='{.status.addresses[0].value}') $ export TCP_INGRESS_PORT=$(kubectl get gtw tcp-echo-gateway -n istio-io-tcp-traffic-shifting -o jsonpath='{.spec.listeners[?(@.name=="tcp-31400")].port}') -
TCP 트래픽을 조금 보내서
tcp-echo서비스가 정상 동작하는지 확인해요.$ export CURL=$(kubectl get pod -l app=curl -n istio-io-tcp-traffic-shifting -o jsonpath={.items..metadata.name}) $ for i in {1..20}; do \ kubectl exec "$CURL" -c curl -n istio-io-tcp-traffic-shifting -- sh -c "(date; sleep 1) | nc $INGRESS_HOST $TCP_INGRESS_PORT"; \ done one Mon Nov 12 23:24:57 UTC 2022 one Mon Nov 12 23:25:00 UTC 2022 one Mon Nov 12 23:25:02 UTC 2022 one Mon Nov 12 23:25:05 UTC 2022 one Mon Nov 12 23:25:07 UTC 2022 one Mon Nov 12 23:25:10 UTC 2022 one Mon Nov 12 23:25:12 UTC 2022 one Mon Nov 12 23:25:15 UTC 2022 one Mon Nov 12 23:25:17 UTC 2022 one Mon Nov 12 23:25:19 UTC 2022 ...모든 타임스탬프 앞에 one 이라는 접두어가 붙어 있는 것을 볼 수 있을 거예요. 즉 모든 트래픽이
tcp-echo서비스의v1버전으로 라우팅됐다는 뜻이에요. -
다음 명령으로 트래픽의 20%를
tcp-echo:v1에서tcp-echo:v2로 옮겨요:Istio APIs
$ kubectl apply -f @samples/tcp-echo/tcp-echo-20-v2.yaml@ -n istio-io-tcp-traffic-shiftingGateway API
$ kubectl apply -f @samples/tcp-echo/gateway-api/tcp-echo-20-v2.yaml@ -n istio-io-tcp-traffic-shifting -
새 규칙이 전파될 때까지 몇 초 기다린 다음 규칙이 교체됐는지 확인해요:
Istio APIs
$ kubectl get virtualservice tcp-echo -o yaml -n istio-io-tcp-traffic-shifting apiVersion: networking.istio.io/v1 kind: VirtualService ... spec: ... tcp: - match: - port: 31400 route: - destination: host: tcp-echo port: number: 9000 subset: v1 weight: 80 - destination: host: tcp-echo port: number: 9000 subset: v2 weight: 20Gateway API
$ kubectl get tcproute tcp-echo -o yaml -n istio-io-tcp-traffic-shifting apiVersion: gateway.networking.k8s.io/v1 kind: TCPRoute ... spec: parentRefs: - group: gateway.networking.k8s.io kind: Gateway name: tcp-echo-gateway sectionName: tcp-31400 rules: - backendRefs: - group: "" kind: Service name: tcp-echo-v1 port: 9000 weight: 80 - group: "" kind: Service name: tcp-echo-v2 port: 9000 weight: 20 ... -
tcp-echo마이크로서비스에 TCP 트래픽을 조금 더 보내요.$ export CURL=$(kubectl get pod -l app=curl -n istio-io-tcp-traffic-shifting -o jsonpath={.items..metadata.name}) $ for i in {1..20}; do \ kubectl exec "$CURL" -c curl -n istio-io-tcp-traffic-shifting -- sh -c "(date; sleep 1) | nc $INGRESS_HOST $TCP_INGRESS_PORT"; \ done one Mon Nov 12 23:38:45 UTC 2022 two Mon Nov 12 23:38:47 UTC 2022 one Mon Nov 12 23:38:50 UTC 2022 one Mon Nov 12 23:38:52 UTC 2022 one Mon Nov 12 23:38:55 UTC 2022 two Mon Nov 12 23:38:57 UTC 2022 one Mon Nov 12 23:39:00 UTC 2022 one Mon Nov 12 23:39:02 UTC 2022 one Mon Nov 12 23:39:05 UTC 2022 one Mon Nov 12 23:39:07 UTC 2022 ...이제 타임스탬프의 약 20% 앞에 two 라는 접두어가 붙어 있는 것을 볼 수 있을 거예요. 즉 TCP 트래픽의 80%는
tcp-echo서비스의v1버전으로, 20%는v2로 라우팅됐다는 뜻이에요.
무슨 일이 있었는지 이해하기
이 태스크에서는 Istio의 가중치 라우팅 기능을 사용해 TCP 트래픽을 tcp-echo 서비스의 이전 버전에서 새 버전으로 부분 마이그레이션했어요. 참고로 이것은 인스턴스 스케일링으로 트래픽을 관리하는 컨테이너 오케스트레이션 플랫폼의 배포 기능을 사용하는 버전 마이그레이션과는 아주 다르다는 점을 알아두세요.
Istio를 사용하면 tcp-echo 서비스의 두 버전이 서로 간 트래픽 분산에 영향을 주지 않으면서 독립적으로 스케일 업/다운될 수 있어요.
오토스케일링과 함께하는 버전 라우팅에 대한 더 자세한 내용은 Canary Deployments using Istio 블로그 글을 확인해 보세요.
정리
-
라우팅 규칙을 제거해요:
Istio APIs
$ kubectl delete -f @samples/tcp-echo/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shiftingGateway API
$ kubectl delete -f @samples/tcp-echo/gateway-api/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting -
curl샘플,tcp-echo애플리케이션, 테스트 네임스페이스를 제거해요:$ kubectl delete -f @samples/curl/curl.yaml@ -n istio-io-tcp-traffic-shifting $ kubectl delete -f @samples/tcp-echo/tcp-echo-services.yaml@ -n istio-io-tcp-traffic-shifting $ kubectl delete namespace istio-io-tcp-traffic-shifting