はじめに
Istioが持つTraffic Management機能にて、 Virtual ServiceとDestination Ruleを組み合わせることで異なるバージョンのアプリへのトラフィックの割合を指定することが可能となります。
本記事では実際にv1のPodに80%、v2のPodに20%のトラフィックを流すように設定を入れて確認しました。
環境情報
- Openshift v4.6
- Red Hat OpenShift Service Mesh(2.1.0-0 provided by Red Hat, Inc)Operator
想定状況
サービス(reviews)に紐づくPodが複数ある状態で
$ kubectl get ep reviews -n istio-test NAME ENDPOINTS AGE reviews 172.30.189.192:9080,172.30.189.219:9080,172.30.189.225:9080 4d16h
Podは別バージョンで動作しているとします。(Istioは導入済)
$ kubectl get pod -o=wide -n istio-test ... reviews-v1-58b8568645-xmmvj 2/2 Running 0 4d16h 172.30.189.219 ... reviews-v2-5d8f8b6775-zm5cz 2/2 Running 0 4d16h 172.30.189.192 ... reviews-v3-666b89cfdf-l95zt 2/2 Running 0 4d16h 172.30.189.225 ...
また、今回はトラフィック管理のために各Podに対して以下のようなラベルが付与された状態にしておきます。
$ kubectl get pod -n istio-test --show-labels NAME READY STATUS RESTARTS AGE LABELS ... reviews-v1-58b8568645-xmmvj 2/2 Running 0 4d19h ...,version=v1 reviews-v2-5d8f8b6775-zm5cz 2/2 Running 0 4d19h ...,version=v2 reviews-v3-666b89cfdf-l95zt 2/2 Running 0 4d19h ...,version=v3 ...
weightによるトラフィック管理
事前準備の段階では、サービス(reviews)に通信が発生するとランダムで各Podに割り振られますが、ここからその割合を制御しにいきます。具体的には、バーチャルサービスとして以下のYAMLを適用します。ポイントとして、hosts欄にはService名を入れています。
apiVersion: networking.istio.io/v1beta1 kind: VirtualService metadata: name: reviews namespace: istio-test spec: hosts: - reviews http: - route: - destination: host: reviews subset: pod1 weight: 80 - destination: host: reviews subset: pod2 weight: 20
ディスティネーションルールとして以下のYAMLを適用します。name部分はVirtulService、labelの部分はPodと整合性を取ります。
apiVersion: networking.istio.io/v1beta1 kind: DestinationRule metadata: annotations: name: reviews namespace: istio-test spec: host: reviews subsets: - labels: version: v1 name: pod1 - labels: version: v2 name: pod2 - labels: version: v3 name: pod3
上記のweightに記載のある割合(上の例では8:2でv1:v2)でPodに接続に行きます。
終わりに
Istioを利用したWeight-based Routingを実施しましたが、これによって任意の割合でトラフィックを振り分けることが可能です。A/Bテストやカナリアリリースを行う際には有効な手法なので、本記事が参考になれば幸いです。