まっしろけっけ

めもてきなやーつ

Istio を利用して HTTP Request 時に問題があったら retry してもらう

はじめに

Istio is
istio.io

service mesh の一種で色々な事ができるので上記参照(雑)
内部的に envoy を使ってたりする。

今回やる事

特定の pod から別の pod にアクセスする際に稀にネットワーク的な問題で繋がらなかったり、アクセス先の pod が高負荷でたまたま処理に失敗するなどが発生する時がある。

そういう時に pod で動いているアプリケーション側で retry の機構を実装する事も可能なのだけれど、外部との通信で毎回書くのはダルかったりコードが複雑になったりするわけなのでそれを service mesh 層でやってもらおうという作戦。

Retry してもらう

istio の install などは省きます。

設定方法はここにそのまま書いてあるのですが実際に動作確認したいよねとなるので動作確認用のアプリケーションを書いたのがこちら

main という web アプリケーションから sub というアプリケーションに Request を送るだけの簡単なもの

deployment にはまだ istio-proxy 等が追加されていないので apply する際は追加してあげる必要がある

$ istioctl kube-inject -f manifests/deployments.yaml | kubectl apply -f -
$ kubectl apply -f manifests/services.yaml
$ kubectl apply -f manifests/virtual-services.yaml

これで準備終わり。別の pod から curl http://istio-example-app-main-svc:9080/ を打つとこの設定だと普通に Response が受け取れるはず。

sub のアプリは 2s sleep 後に Response を返す実装なので VirtualService の設定の timeout を 2s 以下に変更する。
変更箇所はここ

$ kubectl apply -f manifests/virtual-services.yaml

この状態で curl http://istio-example-app-main-svc:9080/ すると upstream request timeout となり Response が受け取れません。
なぜかというと istio-proxy が VirtualService で設定されている perTryTimeout で設定されている時間で一旦接続を切り attempts の回数分再度同じ Request を行なっているからです。

この様子をログで確認する方法は下記

$ kubectl logs -f main-pod istio-proxy
$ kubectl logs -f sub-pob istio-proxy

これで Response Time によって Retry を設定する方法がわかったので次は HTTP status などによって Retry する設定です。
これはここの retryOn で設定ができます。

どういう設定を書けばいいのかは envoy の docs に書いてあります。

動作確認をしたい場合はこちらを使用して上記と同じ手順を辿れば確認できます。

最後に

今回紹介した機能以外にも istio にはいっぱい機能がある(ありすぎる)ので何かしらの課題を解決する為に導入してみるのも良いかと思います。