IstioでのTCPトラフィックシフトの設定
IstioはHTTPトラフィックだけでなく、TCPトラフィックも柔軟に管理でき、バージョンごとにトラフィックを段階的に振り分けることが可能です。本記事では、Istioを使用してTCPトラフィックを異なるサービスバージョン間で段階的にシフトする方法をご紹介します。
参考にしたのは、Istio公式ドキュメントのこちらのページです。
また、今回のシナリオは、KillerCodaのIstio Playgroundで提供されている環境で実施しました。
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