だいごろうのブログ

熊本出身で大阪、東京、パリを転勤して、今は福岡でデータエンジニアです

[MEMO] katacodaでService Mesh with Istio: ver4 Simple Routings

IstioのRoutingを扱う

www.katacoda.com

oc は openshiftのコマンドです。

実践

まず、前回の章と同じ状態から、コードを変更した新しいバージョンのdocker imageをkubernetesにistioctl経由でデプロイします。

 $ docker build -t example/recommendation:v2 .
 $ oc apply -f <(istioctl kube-inject -f ../../kubernetes/Deployment-v2.yml) -n tutorial

で、podsを確認すると2つのrecommedationのバージョンが確認できます。

$ oc get pods -w
NAME                                 READY     STATUS    RESTARTS   AGE
customer-fc4cb47f9-cckgw             2/2       Running   0          15m
preference-v1-6976458fcf-96qs6       2/2       Running   0          14m
recommendation-v1-5857848d45-nb6q9   2/2       Running   0          13m
recommendation-v2-7c98cb4d-7gsgd     2/2       Running   0          11m

customer->preference->recommendationと呼び出すマイクロサービスになってるので、customerにcurlアクセスすると、v1とv2に交互にアクセスしてるのがわかる。これは、kubernetesがデフォルトだとround robinでroutingするように設定されてるかららしい。

$ while true; do curl http://customer-tutorial.2886795293-80-kitek03.environments.katacoda.com; sleep .5; done
customer => preference => recommendation v1 from '5857848d45-nb6q9': 2
customer => preference => recommendation v2 from '7c98cb4d-7gsgd': 3
customer => preference => recommendation v1 from '5857848d45-nb6q9': 3
customer => preference => recommendation v2 from '7c98cb4d-7gsgd': 4
customer => preference => recommendation v1 from '5857848d45-nb6q9': 4
customer => preference => recommendation v2 from '7c98cb4d-7gsgd': 5

version2のscaleを2にすると、2対1の割合でv2,v1にアクセスするようになったのが確認できる。

$ oc scale --replicas=2 deployment/recommendation-v2

$ while true; do curl http://customer-tutorial.2886795293-80-kitek03.environments.katacoda.com; sleep .5; done
customer => preference => recommendation v2 from '7c98cb4d-qsdkx': 15
customer => preference => recommendation v1 from '5857848d45-nb6q9': 26
customer => preference => recommendation v2 from '7c98cb4d-7gsgd': 27
customer => preference => recommendation v2 from '7c98cb4d-qsdkx': 16
customer => preference => recommendation v1 from '5857848d45-nb6q9': 27
customer => preference => recommendation v2 from '7c98cb4d-7gsgd': 28
customer => preference => recommendation v2 from '7c98cb4d-qsdkx': 17
customer => preference => recommendation v1 from '5857848d45-nb6q9': 28

Yamlでコントロールする

ただ、大半の用途だと、手動でアクセスの分岐をコントロールしたいはずなので、それをコントロールするためにDestinationRuleとVertualServiceの2つを設定する。

まずはBlueGreenの例かな。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: recommendation
spec:
  host: recommendation
  subsets:
  - labels:
      version: v1
    name: version-v1
  - labels:
      version: v2
    name: version-v2
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - route:
    - destination:
        host: recommendation
        subset: version-v2
      weight: 100
---
$ istioctl create -f ~/projects/istio-tutorial/istiofiles/destination-rule-recommendation-v1-v2.yml -n tutorial
$ istioctl create -f ~/projects/istio-tutorial/istiofiles/virtual-service-recommendation-v2.yml -n tutorial

これで、recommendationへのアクセスが100% version-v2に行くことが確認できる。

ここらへんのコマンドで、現在のvirtualServiceの確認ができる。

$ istioctl get virtualservice
$ istioctl get virtualservice recommendation -o yaml -n tutorial

これがカナリーリリースを行う場合。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: recommendation
spec:
  hosts:
  - recommendation
  http:
  - route:
    - destination:
        host: recommendation
        subset: version-v1
      weight: 90
    - destination:
        host: recommendation
        subset: version-v2
      weight: 10
---

こういう感じで、routingのコントロールができるみたい。

見た感じなんとなくやりたいことはわかるが、違いのわかる男になるために、ちょっと公式で勉強する。

DestinationRule

https://istio.io/docs/reference/config/networking/v1alpha3/destination-rule/

[簡易翻訳]

  • host - 簡単に言うとKubernetesに登録されてるService 名を置く。ただ、kubernetesの"reviews.default.svc.cluster.local”のような、省略しない書き方のほうが将来のミスを避けるための好まれるみたい。
  • trafficPolicy - これらを設定するところ(load balancing policy, connection pool sizes, outlier detection)。今回の設定ファイルには書かれてない。
  • subsets - ここに、各バージョンの管理を書くみたい。で、それぞれのsubesetでTraficPolicyをかける。その場合、servicelevelの設定は、上書きされる。

ラウンドロビン

  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN

ハッシュ値を利用してbalancing。ユーザのCookieを利用する。

   trafficPolicy:
     loadBalancer:
       consistentHash:
         httpCookie:
           name: user
           ttl: 0s

VirtualService

traffic routingに影響する設定らしい。

[翻訳] "VirtualServiceは指定したホストへのアクセスが有った場合の、複数のtraffic routingルールの定義になる。"。

そういえば、IngressGatewayでも出てきたな。

[翻訳] 例えば、下記のKubernetes上の例だと、すべてのreviews serviceへのHTTPアクセスは“version: v1”にルートされる。そして、/wpcatalog/ or /consumercatalog/だと、 /newcatalogに上書きされた上で“version: v2”にルートされる。

で、上が先に評価される(たしか)なので、指定のURLの場合、“version: v1に転送されないはず。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - name: "reviews-v2-routes"
    match:
    - uri:
        prefix: "/wpcatalog"
    - uri:
        prefix: "/consumercatalog"
    rewrite:
      uri: "/newcatalog"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
  - name: "reviews-v1-route"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1