GKEのistioでサンプルアプリを動かす(フォールトインジェクション、タイムアウト編)
前回、前々回に引き続き、GKE上のistioでサンプルアプリケーションを動かして設定を確認していきます。
今回の目標は、タイムアウトの設定と動作を確認することです。
参考にするページは以下のとおりです。
フォールトインジェクション
タイムアウトの設定を確認するまえに、タイムアウトする状態を作り出す必要があります。 そこで、フォールトインジェクションについて学びます。
まず、用意されたVirtualServiceを適用させます。
1 2 |
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml $ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml |
設定された内容を確認してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews namespace: default spec: hosts: - reviews http: - match: - headers: end-user: exact: jason route: - destination: host: reviews subset: v2 - route: - destination: host: reviews subset: v1 |
end-userという名前のheaderにjasonという文字列が入っている場合のみ、reviewsへのリクエストをv2に転送するという設定になっています。 その他のreviewsのリクエストはすべてv1に転送されます。
それでは、フォールトインジェクションしてトラフィックを遅延させます。
1 |
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml |
設定された内容を確認します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings namespace: default spec: hosts: - ratings http: - fault: delay: fixedDelay: 7s percentage: value: 100 match: - headers: end-user: exact: jason route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1 |
faultが追加されて、ratingsへのアクセスに固定の遅延7秒が100%で発生するように設定されました。
ここで、サンプルアプリケーションのタイムアウトの仕様の確認しておきます。
- reviewsからratingsの通信は、10秒でタイムアウトするようにハードコーディングされている
- productpageからreviewsへの通信は、3秒間のタイムアウトで再試行の回数は1になっている
- つまり、初回3秒と再試行3秒で、合計6秒でタイムアウトする
- productpageはreviewsに依存して、reviewsはratingsに依存する
この場合、ratingsに7秒の遅延が発生する場合、どのような影響がでるか考えてみてください。
では、実際にブラウザから検証していきます。
まず、productpageを開いてみると、遅延は発生せずに表示されます。
headerに特定の内容を含まない通常のアクセスの場合は、遅延が発生しません。
次に、jasonでログインしてみます。
すると、遅延が発生し、レビューが表示されてないことが確認できます。
reviewsからratingsへの通信は、タイムアウトが10秒なので7秒遅延しても、実際にタイムアウトすることはありません。
しかし、productpageからreviewsへの通信は6秒なので、reviewsがratingsへ7秒以上かけて通信する前に、productpage側でタイムアウトしてしまいます。
なので、reviewsからratingsへの通信は成功していても、実際にレビューを取得して表示することができなかったのです。
リクエストのタイムアウト
フォールトインジェクションの例では、ハードコードされたタイムアウトでしたが、今回はVirtualServiceでタイムアウトを設定します。
istioからタイムアウトを設定すると、アプリケーション側でタイムアウトをハードコードする必要がなくなり、よりサービス自体の役割に集中できます。
まず、ルーティングを初期化します。
1 |
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml |
この状態だと、すべてv1へのリクエストになるのですが、reviewsからratingsへの通信を有効にしたいので、reviewsをv2にします。(v1だとratingsへアクセスしません)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 EOF |
次に、ratingsへ2秒の遅延をフォールトインジェクションします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - fault: delay: percent: 100 fixedDelay: 2s route: - destination: host: ratings subset: v1 EOF |
ブラウザでアクセスすると、2秒遅延していることが確認できます。
この状態で、reviewsサービスの呼び出しに0.5秒のタイムアウトを設定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
$ kubectl apply -f - <<EOF apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 timeout: 0.5s EOF |
ブラウザでアクセスすると、約1秒でレスポンスが返り、レビューが取得できてないのが確認できます。
productpageは上記の通り、reviewsへ通信します、ここのタイムアウトは0.5秒です。
そして、reviewsはratingsへ通信しますが、2秒の遅延が発生します。
よって、reviewsがratingsへ通信している間に、productpageからreviewsの通信が0.5秒でタイムアウトしています。
実際には、約1秒かかるわけですが、これはフォールトインジェクションのところで説明したとおり、productpageは1回だけ再試行するので、実際には0.5秒+0.5秒の1秒でレスポンスが返ります。
まとめ
フォールトインジェクションとタイムアウトの設定と動作を確認しました。
フォールトインジェクションは、遅延に対するバグを発見するときに非常に有用だと思いました。
タイムアウトは、サービス側で実装する必要がなくなるので、サービスの実装コストやバグを抑えられると思います。
特に、通信の遅延から発生する障害は、サービス全体に影響を及ぼす可能性があるので、リリース前にしっかりと確認したいところです。

tkr2f

最新記事 by tkr2f (全て見る)
- <Goのパッケージ放浪記> ioパッケージに定義されている「Writerインターフェイス」について - 2020年11月24日
- <Goのパッケージ放浪記> ioパッケージに定義されている「Readerインターフェイス」について - 2020年10月23日
- google/wireを使ってGoでDI(dependency injection)してみる - 2020年8月6日
- GKEにArgo CDを導入してアプリケーションをデプロイする - 2020年7月9日
- WSL2のDebianにAnsibleの最新版をインストールする - 2020年6月16日
おすすめ関連記事
最新記事