🔖

IstioでのTCPトラフィックシフトの設定

2024/09/10に公開

IstioはHTTPトラフィックだけでなく、TCPトラフィックも柔軟に管理でき、バージョンごとにトラフィックを段階的に振り分けることが可能です。本記事では、Istioを使用してTCPトラフィックを異なるサービスバージョン間で段階的にシフトする方法をご紹介します。

参考にしたのは、Istio公式ドキュメントのこちらのページです。
https://istio.io/latest/docs/tasks/traffic-management/tcp-traffic-shifting/

また、今回のシナリオは、KillerCodaのIstio Playgroundで提供されている環境で実施しました。
https://killercoda.com/lorenzo-g

1. テスト環境のセットアップ

まず、必要なリソースを用意します。

# Namespaceを作成し、Istioのサイドカーインジェクションを有効化
kubectl create namespace istio-io-tcp-traffic-shifting
kubectl label ns istio-io-tcp-traffic-shifting istio-injection=enabled

# SleepアプリケーションとTCP Echoサービスをデプロイ
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.23/samples/sleep/sleep.yaml -n istio-io-tcp-traffic-shifting
kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.23/samples/tcp-echo/tcp-echo-services.yaml -n istio-io-tcp-traffic-shifting

# リソースの確認
kubectl -n istio-io-tcp-traffic-shifting get po,svc -L app,version

2. TCPトラフィックのテスト

次に、デプロイされたサービスの動作を確認します。

kubectl -n istio-io-tcp-traffic-shifting get po,svc -L app,version

NAME                               READY   STATUS    RESTARTS   AGE   APP        VERSION
pod/sleep-5577c64d7c-f978f         2/2     Running   0          38s   sleep      
pod/tcp-echo-v1-55bf5d7c67-vp9pb   2/2     Running   0          26s   tcp-echo   v1
pod/tcp-echo-v2-57965bfff6-9w4qk   2/2     Running   0          26s   tcp-echo   v2

NAME               TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)             AGE   APP        VERSION
service/sleep      ClusterIP   10.98.195.188   <none>        80/TCP              38s   sleep      
service/tcp-echo   ClusterIP   10.110.1.13     <none>        9000/TCP,9001/TCP   26s   tcp-echo   

次に、サービスに対してリクエストを送信し、異なるバージョンのレスポンスが返ってくるか確認します。

echo "hello" | nc -w 1 10.110.1.13 9000
one hello
echo "hello" | nc -w 1 10.110.1.13 9000
two hello

これにより、TCPトラフィックが異なるバージョンにランダムに振り分けられていることを確認できます。

3. GatewayとVirtualServiceの設定

次に、Ingress Gatewayを介して外部からのTCPトラフィックを受け入れる設定を行います。

Gatewayの設定

以下の内容でtcp-echo-gateway.yamlを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: tcp-echo-gateway
  namespace: istio-io-tcp-traffic-shifting
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 31400
      name: tcp
      protocol: TCP
    hosts:
    - "*"

作成したファイルを適用します。

kubectl apply -f tcp-echo-gateway.yaml

VirtualServiceの設定

次に、VirtualServiceを設定します。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: tcp-echo-routing
  namespace: istio-io-tcp-traffic-shifting
spec:
  hosts:
  - "*"
  gateways:
  - tcp-echo-gateway
  tcp:
  - match:
    - port: 31400
    route:
    - destination:
        host: tcp-echo
        port:
          number: 9000

これを適用します。

kubectl apply -f tcp-echo-routing.yaml

4. トラフィックルーティングの確認

Ingress Gateway経由でリクエストを送信し、サービスの応答を確認します。

kubectl get svc -n istio-system | grep istio-ingress

kubectl get node -o wide

次に、20回のリクエストを送信し、サービスが適切に応答しているかを確認します。

for i in {1..20}; do echo hello | nc -w 1 172.30.2.2 31412; done;

応答例:

one hello
one hello
two hello
two hello
two hello
two hello
one hello
two hello
one hello
two hello
one hello
one hello
two hello
two hello
one hello
one hello
two hello
two hello

結果として、バージョン1(one hello)とバージョン2(two hello)のサービスが50/50の割合で応答していることを確認できます。

5. トラフィックシフトの設定

次に、DestinationRuleの設定を作成し、VirtualServiceの設定を変更することで、バージョン1とバージョン2の間でトラフィックを20%/80%に振り分けます。

DestinationRuleの設定

次に、バージョンごとのトラフィックルーティングを行うため、tcp-echo-destination.yamlを作成します。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: tcp-echo-destination
  namespace: istio-io-tcp-traffic-shifting
spec:
  host: tcp-echo
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2

これを適用します。

kubectl apply -f tcp-echo-destination.yaml

VirtualServiceの設定

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: tcp-echo-routing
  namespace: istio-io-tcp-traffic-shifting
spec:
  hosts:
  - "*"
  gateways:
  - tcp-echo-gateway
  tcp:
  - match:
    - port: 31400
    route:
    - destination:
        host: tcp-echo
        port:
          number: 9000
        subset: v1
      weight: 20
    - destination:
        host: tcp-echo
        port:
          number: 9000
        subset: v2
      weight: 80

これを適用します。

kubectl apply -f tcp-echo-routing.yaml

6. トラフィックシフトの確認

再度20回のリクエストを送信し、トラフィックシフトの設定が適用されているか確認します。

for i in {1..20}; do echo hello | nc -w 1 172.30.2.2 31412; done;

応答例:

two hello
two hello
two hello
two hello
two hello
one hello
two hello
two hello
two hello
two hello
two hello
two hello
two hello
two hello
two hello
one hello
two hello
two hello
two hello
one hello

結果として、20%の確率でone hello、80%の確率でtwo helloが出力されることが期待されます。

このように、Istioを使用してTCPトラフィックをバージョンごとに段階的に振り分けることが可能です。

Discussion