BookinfoデモでIstioを体感する
フォールト・インジェクション
意図的に障害を発生させるフォールト・インジェクション機能を試してみましょう。次のコマンドを実行して、意図的な遅延を組み込んだマニフェストを適用します。
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml
この構成を確認してみましょう(コード3、オリジナルはhttps://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml)。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - match: - headers: end-user: exact: jason fault: delay: percent: 100 fixedDelay: 7s route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1
http > match以下で、ユーザー名「jason」からのratingsサービスへのリクエストは全て(100%)、7秒遅延することを定義しています。ブラウザーでBookinfoアプリケーションにアクセスして適用結果を確認してみましょう。jasonにログインしたままリクエストを送ると約6秒強後に「Sorry, product reviews are currently unavailable for this book.」というメッセージとともに、画面が表示されます(図18)。
なぜマニフェストに指定した7秒ではなく、6秒でレスポンスが得られるのでしょうか。それはproductpageサービスからreviewsサービス呼出し間のタイムアウト値として6秒がハード・コーディングされているからです。すなわち、この実験は、6秒のタイムアウトが想定したとおりに動作するか、フォールト・インジェクション機能を使ってテストしていることを意味します。ユーザー「jason」以外からアクセスされた際の動作を確認してみましょう。右上の「sign out」リンクをクリックして、Bookinfoアプリケーションにアクセスすると、今度はレイティングなしのV1の画面が表示されます。
次にフォールト・インジェクションのもう一つの機能、「abort(失敗、中止)」を試してみましょう。次のコマンドを実行します。
kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml
この構成を確認してみましょう(コード4、オリジナルはhttps://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml)。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: ratings spec: hosts: - ratings http: - match: - headers: end-user: exact: jason fault: abort: percent: 100 httpStatus: 500 route: - destination: host: ratings subset: v1 - route: - destination: host: ratings subset: v1
http > match以下で、ユーザー名「jason」からratingsサービスへのリクエストについては全て(100%)、HTTPステータス「500」、すなわちサーバー・エラーを返す構成となっています。ブラウザーでBookinfoアプリケーションにアクセスして確認してみましょう。「jason」でサイン・インしていない状態でアクセスしてみると、レイティングなしのV1の画面が即座に表示されます。
次に「jason」としてサイン・インした上で、Bookinfoアプリケーションにアクセスすると「Ratings service is currently unavailable」というエラー・メッセージとともに、Webページが即座に表示されます(図19)。これはreviewsサービスがratingsサービスを呼び出した際のレスポンスとしてHTTPステータス「500」が返ってきたことに起因します。すなわちこの実験は、フォールト・インジェクションのAbort機能を利用することで、ratingsサービス障害時のreviewsサービスの例外処理が意図した通りであるか、テストしたことを意味します。
ウェイト・ベースド・ルーティング
ウェイト・ベースド・ルーティング(Weight-based routing、WBR)とは、重み付けに応じたルーティングのことです。Istioでは、百分率(%)で重み付けを行うことが可能です。例えば、全リクエストの90%をV1のサービスに、残りの10%をV2のサービスに振り分けるといったルールを定義できます。WBRの実験をする前に、一旦ルーティング・ルールを基本形に設定しておきましょう。次のコマンドを実行して、各サービスのV1にルーティングされるようにルールを適用します。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
ブラウザーでBookinfoアプリケーションに何度かアクセスしてください。レイティングが表示されないので、V1のサービスが呼び出されていることが分かります。次に、リクエストの50%をV1、残りの50%をV3に振り分けるルーティング・ルールを適用します。次のコマンドを実行してください。
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml
この構成(コード5、オリジナルはhttps://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml)を確認してみましょう。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v1 weight: 50 - destination: host: reviews subset: v3 weight: 50
http > route以下に二つのdestination要素が定義されており、それぞれreviewsサービスのV1とV3へのルーティングを規定しています。同時にweight要素で、呼び出しの重み付けをともに50%としています。ブラウザーでBookinfoアプリケーションにアクセスしてみると、レイティングなしのV1と赤い星でレイティング表示されるV3が、ほぼ50%の割合で表示されることが確認できるはずです。次は、常にreviewsサービスのV3が表示されるように構成してみましょう。次のコマンドを実行します。
kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml
この構成(コード6、オリジナルはhttps://raw.githubusercontent.com/istio/istio/release-1.0/samples/bookinfo/networking/virtual-service-reviews-v3.yaml)には、V3のreviewsサービスへのルーティング定義しかなく、重み付けのweight要素もありません。ブラウザーでBookinfoアプリケーションにアクセスしてみると、常に赤い星でレイティングを表示するV3のreviewsサービスにリクエストがルーティングされます。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v3
ここで、WBRというテーマで実験した内容を振り返って見ましょう。まず最初は全てのリクエストをV1のサービスにルーティングした上で、次にV1とV3への50%ずつのルーティング、そして最後に全てのリクエストをV3にルーティングするようにルールを変更しました。これは、V1からV3へのカナリア・リリースの実践に相当します。難しそうに感じるカナリア・リリースのオペレーションも、Istioを利用すれば簡単に実現できることを実感いただけたのではないでしょうか。
タイムアウトの設定
最後にサービス間呼び出しの通信に、タイムアウトを設定してみましょう。次のコマンドを実行し、VirtualServiceオブジェクトを作成して、各サービスのV1にルーティングするようにします。
kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
ブラウザーでBookinfoアプリケーションに何度かアクセスしてください。レイティングが表示されないので、V1のサービスが呼び出されていることが分かります。次に、reviewsサービスについては、V1ではなく、V2にルーティングされるように構成します。今回はyamlファイルではなく、CLI上でコマンド実行時に、直接インラインで構成情報を与え、Bookinfoアプリケーション・クラスターに適用します(コード7)。
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 EOF
さらに、V1のratingsサービス呼出に先立って、2秒遅延するように、フォールト・インジェクション機能を構成します。これもyamlファイルではなく、CLI上でコマンド実行時に、直接インラインで構成情報を与えます(コード8)。
cat <<EOF | kubectl apply -f - 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
ブラウザーからBookinfoアプリケーションにアクセスすると、約2秒後に、黒い星でレイティング情報が表示されます。このことからreviewsサービスはV2が呼び出されていることが確認できました。次いで、次のコマンドを実行して、reviewsサービス呼び出しに0.5秒のタイムアウトを設定します(コード9)。
cat <<EOF | kubectl apply -f - apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - route: - destination: host: reviews subset: v2 timeout: 0.5s EOF
ブラウザーからBookinfoアプリケーションにアクセスすると約1秒強後に、「Sorry, product reviews are currently unavailable for this book.」というエラー・メッセージとともに画面が表示されます(図20)。
エラー・メッセージが表示された理由は、0.5秒のタイムアウトが満了し、reviewsサービスが呼び出されなかったためです。一方で、図20下部のデベロッパー・コンソールを確認すると応答時間は1秒強となっています。なぜ応答時間は0.5秒ではなく、1秒強となったのでしょうか。その理由は、productpageサービスには2回のリトライのロジックがハード・コーディングされていたためです。すなわちreviewsサービスを2回呼び出していたため、応答時間は0.5秒X2回+α≒1秒強となっているのです。
おわりに
以上でBookinfoサンプル・アプリケーションを利用したIstioの実験は、ひとまず終了です。最後に、クリーンナップの手順をご紹介します。Bookinfoアプリケーションを削除するには、Istioに同梱されている専用のシェルを呼び出します。ISTIO_HOME・ディレクトリーから次のコマンドを実行してください。
samples/bookinfo/platform/kube/cleanup.sh
KubernetesクラスターからIstioを除去するには、こちらのWebサイト(https://istio.io/docs/setup/kubernetes/helm-install/#uninstall)を確認の上で、導入方法に応じた削除手段を取ります。今回はHelmチャートのテンプレートをマニフェストに変換してkubectlで導入しました。この場合は次のコマンドを実行してIstioを削除します。
kubectl delete -f $HOME/istio.yaml
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- コンテナ上のマイクロサービスの認証強化 ~IstioとKeycloak~
- Kubernetesをサービスメッシュ化するIstioとは?
- サービスメッシュを使ってみよう
- コンテナ上のマイクロサービスの認証強化 ~QuarkusとKeycloak~
- コンテナ上のマイクロサービスの認証強化 ~StrimziとKeycloak~
- Kubernetesの新しいネットワーク機能、Gateway APIを理解する(前編)
- CloudNative Days Fukuoka 2023、GoogleによるGKE上のGateway APIの解説セッションを紹介
- Kubeflowを構築する
- コマンドラインツールを用いずにCI/CDを行うGitOpsとは?
- NGINX Ingress Controllerの柔軟なアプリケーション制御、具体的なユースケースと設定方法を理解する