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 지침을 사용하기 전에 다음을 반드시 확인해요:

  1. Gateway API CRD의 실험 버전을 설치해요:

    $ kubectl kustomize "github.com/kubernetes-sigs/gateway-api/config/crd/experimental?ref=v1.6.0" | kubectl apply -f -
    
  2. 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
    

시작하기 전에

테스트 환경 설정

  1. 시작하려면 TCP 트래픽 이동을 테스트할 네임스페이스를 만들어요.

    $ kubectl create namespace istio-io-tcp-traffic-shifting
    
  2. 요청을 보내는 테스트 소스로 사용할 curl 샘플 앱을 배포해요.

    Zip

    $ kubectl apply -f @samples/curl/curl.yaml@ -n istio-io-tcp-traffic-shifting
    
  3. tcp-echo 마이크로서비스의 v1과 v2 버전을 배포해요.

    Zip

    $ kubectl apply -f @samples/tcp-echo/tcp-echo-services.yaml@ -n istio-io-tcp-traffic-shifting
    

가중치 기반 TCP 라우팅 적용

  1. 모든 TCP 트래픽을 tcp-echo 마이크로서비스의 v1 버전으로 라우팅해요.

    Istio APIs

    Zip

    $ kubectl apply -f @samples/tcp-echo/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting
    

    Gateway API

    Zip

    $ kubectl apply -f @samples/tcp-echo/gateway-api/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting
    
  2. 인그레스 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}')
    
  3. 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 버전으로 라우팅됐다는 뜻이에요.

  4. 다음 명령으로 트래픽의 20%를 tcp-echo:v1에서 tcp-echo:v2로 옮겨요:

    Istio APIs

    Zip

    $ kubectl apply -f @samples/tcp-echo/tcp-echo-20-v2.yaml@ -n istio-io-tcp-traffic-shifting
    

    Gateway API

    Zip

    $ kubectl apply -f @samples/tcp-echo/gateway-api/tcp-echo-20-v2.yaml@ -n istio-io-tcp-traffic-shifting
    
  5. 새 규칙이 전파될 때까지 몇 초 기다린 다음 규칙이 교체됐는지 확인해요:

    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: 20
    

    Gateway 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
    ...
    
  6. 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 블로그 글을 확인해 보세요.

정리

  1. 라우팅 규칙을 제거해요:

    Istio APIs

    Zip

    $ kubectl delete -f @samples/tcp-echo/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting
    

    Gateway API

    Zip

    $ kubectl delete -f @samples/tcp-echo/gateway-api/tcp-echo-all-v1.yaml@ -n istio-io-tcp-traffic-shifting
    
  2. curl 샘플, tcp-echo 애플리케이션, 테스트 네임스페이스를 제거해요:

    Zip Zip

    $ 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
    

더 알아보기 (Learn more)