Kubernetesやクラウドネイティブをより便利に利用する技術やツールの概要、使い方を凝縮して紹介する連載。今回は、Istioのトラフィック制御機能によってブルーグリーンデプロイメント、カナリアリリース、フォールトインジェクション、サーキットブレーカーを簡単に実現する方法を解説する。
この記事は会員限定です。会員登録(無料)すると全てご覧いただけます。
Kubernetesやクラウドネイティブをより便利に利用する技術やツールの概要、使い方を凝縮して紹介する本連載「Cloud Nativeチートシート」。前回に引き続き、サービスメッシュのOSS(オープンソースソフトウェア)「Istio」を紹介します。前回はIstioのインストール手順やサンプルアプリを紹介しました。今回からは下記のIstioの機能を試していきます。
今回は「Traffic Management」(トラフィック制御)について設定をしながら紹介します。トラフィック制御機能を使うと、アプリケーションを変更することなくサービス間のルーティングやトラフィックフローを制御できます。
Istio公式サイトのチュートリアルを参考に、代表的な機能を紹介します。
基本的に前回紹介したサンプルアプリ「Bookinfo」に設定をします。
前回記事の手順を実行し、IstioのインストールとサンプルアプリケーションBookinfoのデプロイを行っておいてください。
本稿でデプロイしているYAMLは、Istio 1.11.3に含まれるBookInfoアプリケーションを利用します。YAMLのみ参照したい方は、istio-1.11.3のアーカイブからダウンロードして、解凍してご参照ください。
Istioはルーティング制御機能によって、トラフィックのルーティング先となるPodを柔軟に変更できます。この機能を活用して、異なるバージョンのPod(アプリケーション)を並行して稼働させ、切り替えるデプロイ手法(「ブルーグリーンデプロイメント」「カナリアリリース」など)を利用できます。
Request Routingのチュートリアルを参考に、このルーティング制御機能の動作を確認します。
設定をする前に、現状のルーティング動作を確認します。前回記事で紹介した通り、Bookinfoのreviewsサービスはv1、v2、v3の3バージョンが動作しており、それぞれ下記のような挙動をします。
Istioは、デフォルトではラウンドロビンで振り分けるので、Bookinfoにアクセスするたびに、これら3バージョンのいずれかを使用します。試しにBookinfoにブラウザでアクセスして何度か更新してください。更新するたびに、画面右側の「Book Reviews」が下記のいずれかの表示となることを確認できます。
各バージョンの動作を確認できたところで、ルーティング制御を設定します。まずは、reviewsサービスについてv1のみが使用されるようにします。ルーティング制御には、「DestinationRule」「VirtualService」リソースを使用します。
DestinationRuleは、特定のサービスへのトラフィックに適用されるポリシーを定義するリソースです。PodのLabelを用いた“まとまり”(サブセット)の作成や負荷分散ルールの構成、接続数の設定などができます。
VirtualServiceは、サービスにリクエストをルーティングする方法を構成するリソースです。特定のサービスへのリクエストが発生した際に、HTTPヘッダやパスなどを条件化することでルーティング先を定義したり、DestinationRuleと組み合わせることでサブセット単位にルーティングのルールを設定したりすることができます。
DestinationRuleとVirtualServiceの詳細については前回記事の「VirtualServiceとDestinationRule」の解説をご覧ください。
DestinationRuleについて確認する前に設定を一部変更します。Bookinfoのデフォルト設定ではサブセット名とラベルの値が同じ命名規則(v1、v2、v3)となっており、設定の対応関係が分かりづらいので、紹介の都合上サブセットの名前を変更します。サブセットは、VirtualServiceの設定の中でルーティング先のPodを示す際に使う値です。DestinationRuleの中で定義します。
reviewsサービスのDestinationRuleを編集して、サブセットの名前を変更します。
$ kubectl edit destinationrules reviews
spec: host: reviews subsets: - labels: version: v1 name: v1 - labels: version: v2 name: v2 - labels: version: v3 name: v3
spec: host: reviews subsets: - labels: version: v1 name: subset-v1 ※変更箇所 - labels: version: v2 name: subset-v2 ※変更箇所 - labels: version: v3 name: subset-v3 ※変更箇所 trafficPolicy: tls: mode: ISTIO_MUTUAL
DestinationRuleを確認します。「reviews」というDestinationRuleにはサブセットとPodのラベル情報の関連が定義されています。下記の設定の場合、VirtualServiceにおけるサブセット「subset-v1」は、「version=v1というラベルを持つPod」を指すことになります。
$ kubectl get destinationrules reviews -o yaml (略) spec: host: reviews #DestinationRuleの対象となるService名。VirtualServiceの「destination.host」と同じ値にする。 subsets: #サブセット定義部分 - labels: version: v1 #Podのラベル情報 name: subset-v1 #サブセットの名前(VirtualService内ではこの名前を指定する) - labels: version: v2 #Podのラベル情報 name: subset-v2 #サブセットの名前(VirtualService内ではこの名前を指定する) - labels: version: v3 #Podのラベル情報 name: subset-v3 #サブセットの名前(VirtualService内ではこの名前を指定する) trafficPolicy: tls: mode: ISTIO_MUTUAL
次に、VirtualServiceを作成します。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: #VirtualServiceが適用されるトラフィック送信先(KubernetesのServiceリソース名) - reviews # reviews Serviceへのトラフィックに以下のルールを適用する http: #HTTPトラフィックに適用されるルールの記載部 - route: #ルーティング先の記載部 - destination: #ルーティング先の一つを記載する箇所 host: reviews #reviews Serviceに登録されたEndpointのうち、subset-v1で定義されたPodにのみルーティングする subset: subset-v1 #hostとsubsetはDestinationRuleで定義した値を利用する
VirtualServiceを作成します。
$ kubectl apply -f virtual-service-all-v1.yaml
各サービス(details、productpage、ratings、reviews)のVirtualServiceが作成されました。
$ kubectl get virtualservice NAME GATEWAYS HOSTS AGE bookinfo ["bookinfo-gateway"] ["*"] 164m details ["details"] 7m21s productpage ["productpage"] 7m24s ratings ["ratings"] 7m22s reviews ["reviews"] 7m23s
VirtualServiceの作成前は、reviewsサービス宛てのトラフィックはIstioのデフォルト挙動であるラウンドロビンで振り分けられ、Bookinfoにアクセスするたびに3バージョンのいずれかが使用されていました。
VirtualServiceを作成した後は、reviewサービスに対するトラフィックはsubset-v1でマッピングされたv1のPodにルーティングされるようになります。Bookinfoにアクセスすると、画面右側の「Book Reviews」に、評価を表す星マークが表示されなくなったことを確認できます。
VirtualServiceの動きをもう少し詳しく見ます。
VirtualServiceでは、hostsフィールドで指定した宛先(KubernetesのServiceリソースなど)のHTTPトラフィックに、「http」フィールドに記載したルーティングルールが適用されます。ルーティングルールの適用後、最終的にトラフィックがルーティングされる先は、「destination.host」(=DestinationRuleのhost)に設定したエンドポイントです。
そのため、上記のVirtualServiceは、「reviews Serviceリソース宛てのHTTPトラフィックは、reviews Serviceリソースにひも付くPodの中でサブセットが"subset-v1"であるものにルーティングされる」という内容です。前述の通り、VirtualServiceにおけるsubset-v1はDestinationRuleに定義されており、「version-name=label-v1というラベルを持つPod」を示します。結果として、reviews Serviceへのトラフィックは、reviews Podのv1にのみルーティングされることになります。
ブルーグリーンデプロイメントを想定して設定を変更します。
ブルーグリーンデプロイメントとは、古いバージョンのアプリケーションを稼働させたまま新しいバージョンのアプリケーションを稼働させ、接続先を切り替えるデプロイ手法です。もし新しいバージョンのアプリケーションに不具合があった場合は、接続先を元に戻すことで、迅速にロールバックできるメリットがあります。
今、reviewsサービスはv1のみが使用されています。ここで、新しいバージョンとしてreviewsサービスのv2がデプロイされたと仮定します。v2に切り替えたい場合は、VirtualServiceを変更するだけです。下記のようにVirtualService内のsubset設定を「subset-v1」から「subset-v2」に変更してください。
$ kubectl edit virtualservice reviews
spec: hosts: - reviews http: - route: - destination: host: reviews subset: subset-v1 #変更箇所
spec: hosts: - reviews http: - route: - destination: host: reviews subset: subset-v2 #変更箇所
ブラウザでBookinfoにアクセスすると、画面右側の「Book Reviews」に、評価を表す黒い星マークが表示されるようになり、reviewsサービスがv2に切り替えられたことが分かります。
あくまでルーティング先を切り替えただけなので、reviewsサービスのv1もまだKubernetes内で稼働しています。そのため、もし切り替え後にv2に何か問題があることが分かった場合は、迅速にv1にロールバックできます。このロールバックについても、VirtualService内のsubset設定を「subset-v2」から「subset-v1」に戻すだけで実施可能なので、気になる方は実施してみてください。
このように、VirtualServiceを構成することで、複数バージョンのアプリケーションへのルーティングを制御できることを確認しました。これにより、ブルーグリーンデプロイメントも簡単に実現できます。
上記VirtualService例ではhttpフィールドを使用していますが、「tcp」「tls」といったフィールドを使うことで、TCPトラフィックのルーティング制御も可能です。より詳細な設定項目については、Istio公式サイトのVirtualServiceの項目をご参照ください。
Copyright © ITmedia, Inc. All Rights Reserved.