Istioの最新バージョン 1.4.2 を、パソコン上のKubernetesクラスタで実行して、動作を検証したメモである。
Istio とは
サービスメッシュのプロダクトの中で、Istio は、獲得したスターの数がもっとも多い、すなわち、最も人気のあるサービスメッシュのOSSである。他には、CNCFがプロジェクトを支援する LINKERD、そして、HashCorpが推進する Consul などが有名である。また、2019年5月のKubeCon バルセロナで、マイクロソフトが推進する Service Mesh Interface (SMI)のOSSプロジェクトが発表されたが、スターの数からは、それほどの支持がない様に思われる。
Istioは、Google,IBM などが開発したマイクロサービスの監視と運用のためのツールで、CNCFのプレミアムメンバーが推進するプロジェクトである。
Istio には、Envoy, Kiali, Jaeger, Grafana などが含まれており、リクエストの流量制御、マイクロサービスの関係可視化、分散トレーシング、メトリックス管理ができる。
それぞれのOSSは、別々の独立したプロジェクトであるため、それぞれのウェブ画面を起動してアクセスする必要がある。
学習環境の設定変更
検証に使用した環境は、IBM Cloud などパブリック・クラウドや、Red HatのOpenShiftではなく、15Stepで習得 Dockerから入るKubernetes コンテナ開発からK8s本番運用まで (StepUp!選書)のために、学習用として作成した Windows10 や macOS の仮想環境で動作する 3ノードのアップストリームのKunerneteクラスタである。(本書の中では学習環境2と表記) この様な簡単にパソコンで動かせるKubernetes環境は、クラウドの利用料金を気にせずに、個人のスキルアップに利用でき、簡単に作って壊すこともできるし、インスタンスを停止すれば、CPUやRAMのリソースを占有することもないため、細切れの時間を使って学習を続けることもできる。
学習環境2 のワーカーノードのデフォルトから、CPUコア数 2、RAM割り当て量 4GBへ変更する。Istio のコンポーネントのインストール先は、ワーカーノードとなるため、マスターノードは、デフォルトの割り当てから変更する必要はない。
git clone https://github.com/takara9/vagrant-kubernetes でローカルに Vagrantファイルをクローンした後、Vagrantfileのパラメータを修正する。以下に修正するべき部分を挙げておく。node1とnode2について修正し、masterは変更する必要はない。
machine.vm.provider "virtualbox" do |vbox|
vbox.gui = false
vbox.cpus = 2
vbox.memory = 4096
end
当然、この変更に伴って、パソコンのCPUコア数、メモリ量を消費することになるので、十分なCPUコア数、メモリ搭載量のあるパソコンでなければ、実行できない。筆者の環境では、CPU 8コア、RAM 32GB の Macを利用した。VagrantとVirtualBoxの環境があれば、Windows10やLinuxの環境でも、同等のことができる。パソコンでのKubernetesクラスタの起動方法は、https://github.com/takara9/vagrant-kubernetes にガイドしてあるので、参照していただきたい。Kubernetesクラスタを起動したあとは、パブリッククラウドのKubernetesと変わらないため、次のセクションからは、パブリッククラウドのサービスを利用しても同じことができる。
Kubernetesクラスタが起動して、以下のコマンドで、ワーカーノードが2つ確認できたら、Istioについての検証作業が開始できる状態である。
maho:k8s-istio maho$ export KUBECONFIG=`pwd`/kubeconfig/config
maho:k8s-istio maho$ kubectl get node
NAME STATUS ROLES AGE VERSION
master Ready master 16m v1.14.3
node1 Ready <none> 15m v1.14.3
node2 Ready <none> 15m v1.14.3
パブリッククラウドのKubernetesサービス GKE,IKSなどでは、マスターノードが表示されないが、検証に影響はない。
Istioのインストール
Isitoのドキュメント (https://istio.io/docs/setup/getting-started/) に従って、インストールを進める。curlコマンドで、Istioのクライアントコマンド、クラスタサイドのためのマニフェスト一式を、ダウンロードして、パソコンのローカルディレクトリに展開する。
$ curl -L https://istio.io/downloadIstio | sh -
<中略>
Istio has been successfully downloaded into the istio-1.4.2 folder on your system.
Next Steps:
See https://istio.io/docs/setup/kubernetes/install/ to add Istio to your Kubernetes cluster.
To configure the istioctl client tool for your workstation,
add the /Users/maho/vm1/k8s-istio/istio-1.4.2/bin directory to your environment path variable with:
export PATH="$PATH:/Users/maho/vm1/k8s-istio/istio-1.4.2/bin"
Begin the Istio pre-installation verification check by running:
istioctl verify-install
Need more information? Visit https://istio.io/docs/setup/kubernetes/install/
展開先のディレクトリに移動して、istioctl コマンドにパスを通しておく。
maho:k8s-istio maho$ cd istio-1.4.2
maho:istio-1.4.2 maho$ ls
LICENSE bin manifest.yaml tools
README.md install samples
maho:istio-1.4.2 maho$ export PATH=$PWD/bin:$PATH
istioctl manifestコマンドで、Istioに必要なコンポーネントをインストールする。コマンドのオプションの説明は、https://istio.io/docs/reference/commands/istioctl/#istioctl-manifest-apply にある。
以下のコマンド実行時のメッセージから判る通り、Istioを実行するためには、多くのCNCFに参加する団体のOSSが含まれている事が判る。コンポーネントの選択は、--set profile=プロファイル名 で指定する事ができる。具体的な説明は https://istio.io/docs/setup/additional-setup/config-profiles/ を参照のこと。
maho:istio-1.4.2 maho$ istioctl manifest apply --set profile=demo
Preparing manifests for these components:
- Policy
- Prometheus
- Injector
- Galley
- CoreDNS
- Kiali
- Pilot
- PrometheusOperator
- Grafana
- Tracing
- Base
- Citadel
- CertManager
- Telemetry
- IngressGateway
- NodeAgent
- EgressGateway
- Cni
<中略>
Component CertManager installed successfully:
=============================================
Component Telemetry installed successfully:
===========================================
メトリックス監視用ウェブUI grafana、時系列データベース prometheus、分散トレーシング jaeger他、可視化ツール Kiali など、必要なツールが一式導入される事が判る。従って、Istioは、リソースを多く必要とするので、ノードのCPUコア数やメモリ量に注意しておく必要がある。筆者の環境では、ワーカーノードのCPUコア数を2個、メモリを4GBとして起動した。
次は、Istio 1.4.2を導入したあとのサービスのリストで Istio以外に grafana, jaeger, kiali, prometheus, zipkin などが動作している事が判る。
maho:istio-1.4.2 maho$ kubectl get svc -n istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
grafana ClusterIP 10.32.0.138 <none> 3000/TCP
istio-citadel ClusterIP 10.32.0.11 <none> 8060/TCP,15014/TCP
istio-egressgateway ClusterIP 10.32.0.133 <none> 80/TCP,443/TCP,15443/TCP
istio-galley ClusterIP 10.32.0.24 <none> 443/TCP,15014/TCP,9901/TCP,1501
istio-ingressgateway LoadBalancer 10.32.0.201 <pending> 15020:30110/TCP,80:31967/TCP,44
istio-pilot ClusterIP 10.32.0.164 <none> 15010/TCP,15011/TCP,8080/TCP,15
istio-policy ClusterIP 10.32.0.151 <none> 9091/TCP,15004/TCP,15014/TCP
istio-sidecar-injector ClusterIP 10.32.0.43 <none> 443/TCP
istio-telemetry ClusterIP 10.32.0.96 <none> 9091/TCP,15004/TCP,15014/TCP,42
jaeger-agent ClusterIP None <none> 5775/UDP,6831/UDP,6832/UDP
jaeger-collector ClusterIP 10.32.0.67 <none> 14267/TCP,14268/TCP,14250/TCP
jaeger-query ClusterIP 10.32.0.217 <none> 16686/TCP
kiali ClusterIP 10.32.0.49 <none> 20001/TCP
prometheus ClusterIP 10.32.0.243 <none> 9090/TCP
tracing ClusterIP 10.32.0.97 <none> 80/TCP
zipkin ClusterIP 10.32.0.253 <none> 9411/TCP
上記のサービスのリストの中で、TYPE = LoadBalancer となっている部分がある。今回利用したパソコン上のKubernetesクラスタでは、ロードバランサを持たないので、NodePortを利用してアクセスする方法を後述していくので、Pending状態になっていることは問題にしなくても良い。
次は、名前空間 istio-system のポッドのリストである。Istioの主要なコンポーネントの名前を伺い知る事ができる。コンポーネントについては、後述したい。
maho:istio-1.4.2 maho$ kubectl get pod -n istio-system
NAME READY STATUS RESTARTS AGE
grafana-5f798469fd-hcqnz 1/1 Running 0 3m46s
istio-citadel-6dc789bc4c-cq7qq 1/1 Running 0 3m47s
istio-egressgateway-75cb89bd7f-qbxtp 1/1 Running 0 3m47s
istio-galley-5bcd89bd9c-878xw 1/1 Running 0 3m46s
istio-ingressgateway-7d6b9b5ffc-8smlp 1/1 Running 0 3m47s
istio-pilot-678b45584b-5ljsk 1/1 Running 0 3m46s
istio-policy-9f78db4cb-hj68b 1/1 Running 4 3m47s
istio-sidecar-injector-7d65c79dd5-6g94x 1/1 Running 0 3m46s
istio-telemetry-fc488f958-bzmg7 1/1 Running 1 3m47s
istio-tracing-cd67ddf8-p4q2c 1/1 Running 0 3m47s
kiali-7964898d8c-zvs26 1/1 Running 0 3m46s
prometheus-586d4445c7-4928l 1/1 Running 0 3m47s
次は、Istioを導入直後のCPUとメモリ使用量を表示した結果である。アプリケーションが稼働していない状態で、ワーカノードのメモリ使用量が、既に1.3ギガバイトとなっており、デフォルトの設定では動かない事が判る。
maho:istio-1.4.2 maho$ kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
master 102m 5% 743Mi 83%
node1 99m 4% 1316Mi 34%
node2 89m 4% 1375Mi 35%
主要なパブリック・クラウド、OpenShiftへのIstioのインストール方法は、https://istio.io/docs/setup/platform-setup/ に記載されているので、必要に応じて参照して頂きたい。
Istioの主要なコンポーネントと機能概説
前述のポッドのリストから、コンポーネントについての解説を試みたい。役割でグルーピングして並べたポッドのリストごとに進める。
Ingress Gatwway と Egress Gateway
次のポッドは、Istio サービスメッシュ の入口と出口を担当する。
istio-ingressgateway-7d6b9b5ffc-8smlp 1/1 Running 0 3m47s
istio-egressgateway-75cb89bd7f-qbxtp 1/1 Running 0 3m47s
Kubernetesでは、内部のサービスを外部に公開する方法として、頻繁に Ingress を利用するが、Istio のサービスメッシュでは、さらに良い方法を提供する。それが Istio Gateway であり、その一部である Istio Ingress Gateway を利用してモニタリング、経路制御などの機能を、クラスタに入るトラフィックに適用できる。その反対の出口を担当するのが Istio Egress Gateway である。
これは、Envoy によって実装され、入口トラフィックをポッド istio-ingressgateway-xxxx が、出口トラフィックをポッド istio-egressgateway-xxxx が担当する。
参考URL
- Gateway, https://istio.io/docs/reference/config/networking/gateway/
- Ingress Gateway, https://istio.io/docs/tasks/traffic-management/ingress/ingress-control/
- Egress Gateway, https://istio.io/docs/tasks/traffic-management/egress/egress-gateway/
Sidecar Injector
次のポッドは、Istioのサービスメッシュを適用する名前空間のアプリケーションのポッドに対して、サイドカーと呼ばれるコンテナを設定するためのポッドである。
istio-sidecar-injector-7d65c79dd5-6g94x 1/1 Running 0 3m46s
このポッドの役割は、対象となる名前空間にデプロイされたポッドのマニフェストを書き換え、Envoy Proxy と呼ばれるサイドカーコンテナを設定する。この Envoy Proxy は、前述の Ingress Gatwway からのトラフィックを中継して、アプリケーションのコンテナへ導く役割を担う。
Istio Control Plane
次に、Istioの核心部分に触れていく、次のポッド群が Istio のコントロール・プレーンと呼ばれるIstioの中核となるコンポーネントのポッドたちである。これらの一つ一つについて、役割を解説してみたい。
istio-pilot-678b45584b-5ljsk 1/1 Running 0 3m46s
istio-policy-9f78db4cb-hj68b 1/1 Running 4 3m47s
istio-citadel-6dc789bc4c-cq7qq 1/1 Running 0 3m47s
istio-telemetry-fc488f958-bzmg7 1/1 Running 1 3m47s
istio-tracing-cd67ddf8-p4q2c 1/1 Running 0 3m47s
istio-galley-5bcd89bd9c-878xw 1/1 Running 0 3m46s
Istio のポッドの名前と機能を、以下に注釈する。それぞれのポッド名の末尾 -xxxx は、コントローラーのハッシュが付加されており、起動のたびに変化するため、"-xxxxx" として表記した。
- istio-pilot-xxxx : Proxyのサイドカーの検出、トラフィック管理、サーキットブレイカーなどレジリエンシーを担当
- istio-policy-xxxx : アクセス制御や流量制御などのポリシーをProxyへ提供を担当
- istio-telemetry-xxxx : Proxyからテレメトリデータを取得を担当
- istio-citadel-xxxx : シタデル(Citadel:要塞の意味)は認証局、サービス間とユーザー認証を担当
- istio-tracing-xxxx : 分散トレーシングを担当
- istio-galley-xxxx : ギャレー(Galley: 調理室、ゲラ(印刷)の意味)は、構成検証、処理と分散のコンポーネントを担当
Istioのアーキテクチャで、中心的な存在がMixerであるが、Mixerと名前のついたポッドは存在しない。Mixerは、サービスメッシュ全体にアクセス制御とポリシーを適用し、Proxyなどからテレメトリデータを収集する。具体的には、Proxyは リクエストレベルの属性を抽出して、評価のためにMixerへ送信する。そして、Mixerは、Policyを通じてアクセス制御や流量制御などをProxyへ送る。
参考URL:
- Architecture, https://istio.io/docs/ops/deployment/architecture/
- Ports userd by istio, https://istio.io/docs/ops/deployment/requirements/#ports-used-by-istio
Observability (可観測性)
次のポッドのリストは、メトリックス、ログ、分散トレーシングに関するポッドのリストである。
grafana-5f798469fd-hcqnz 1/1 Running 0 3m46s
prometheus-586d4445c7-4928l 1/1 Running 0 3m47s
kiali-7964898d8c-zvs26 1/1 Running 0 3m46s
ポッドの名称と機能を注釈する。
- grafana-xxxx : メトリックス監視用のウェブUI
- prometheus-xxxx : 時系列データベース
- kiali-xxxx : Istioサービスメッシュのための可視化ツール
参考URL:
- Grafana Homepage, https://grafana.com/
- Prometheus Homepage, https://prometheus.io/
- Kiali Homepage, https://kiali.io/
Istioのアーキテクチャ
Istioのアーキテクチャについて見ていきたい。ここに二つの視点のアーキテクチャ図をあげる。一つは主なコンポーネントの関係を表すもので、後者はセキュリティ視点でのIstioアーキテクチャ図である。
はじめに、図上部の Service A -> Service Bの連携に注目する。Service A から Service B を利用するには、六角形のアイコンのProxyを経由する。これが、Envoy Proxyである。このProxyは、Pilotから構成情報を受けて、Serviceのアクセス先へ転送する。例えば、複数のバージョン違いのサービスがあった場合は、振り向ける割合などをコントロールする。Mixerは、Proxyへポリシーを適用して、Proxyからのテレメトリデータを収集する。Mixerには、柔軟なプラグインモジュールが提供され、Kubernetes API や Cloud の APIとの連携を可能にする。
Galleyは、Istioがプラットフォームに依存することから防止する役割を担う。Kubernetesの構成情報などを Galleyが収集して MixerやPilotへ提供する。Citadelは暗号通信のための証明書の作成と配布など、サービス間の認証とユーザー認証を担当する。
次のアーキテクチャ図は、セキュリティの動作を中心に説明している。Istioサービスメッシュの外部からのリクエストトラフィックは、Ingress Proxyで受ける。Ingress Proxyは転送先のポリシーを事前に与えられており、それに従って、Service AのサイドカーのProxyへ転送し、Service Aに到達する。また、Service A が、その後方で動作する Service B をアクセスする際も、Envoy Proxy経由で伝達される。これらのProxy間のルーティングと認証などを、Istio コントロール・プレーンが担当する。そして、各プロキシーは、Mixerにテレメトリー情報を送信する。 反対に、Istio サービスメッシュから、外部へアクセスが発生する場合は、Egress Proxyを使用する。
トラフィック管理 (Traffic Management)
以下は、Istioのトラフィック管理機能のリストである。
- Request Routing リクエストをマイクロサービスの複数のバージョンに動的にルーティング
- Fault Injection 模擬障害によってアプリケーションの復元力をテストする方法
- Traffic Shifting マイクロサービスのあるバージョンから別のバージョンにトラフィックを徐々に移行する方法
- TCP Traffic Shifting TCPトラフィックを古いバージョンから新しいバージョンに移行
- Request Timeouts Envoyでリクエストタイムアウトを設定する方法
- Circuit Breaking コネクションやリクエストの異常値検出時の遮断を構成する方法
- Mirroring Istioのトラフィックミラーリング機能
- Ingress 入力トラフィックの制御
- Egress 出力トラフィックの制御
セキュリティ (Security)
サービスメッシュをセキュリティが確保された状態にする機能である。
- Authentication 相互TLSおよびエンドユーザー認証の制御
- Authorization Istioサービスへのアクセスを制御する方法
- Citadel Configuration Citadel認証局のカスタマイズ
- Istio DNS Certificate Management Citadelは、独自の署名キーを維持し、IstioのCAとしても機能。Chironを介してIstioコントロールプレーンコンポーネントのDNS証明書をプロビジョニングおよび管理する方法
- Istio Webhook Management Experimental Istioには、GalleyとSidecar Injector の2つのウェブフックがあり、独自のためリスクがある。この対策としてWebhookの構成を安全に管理する方法
ポリシー (Policies)
これはポリシーを強制する機能のリストである。
- Enabling Policy Enforcement Istioポリシー適用を有効にする方法
- Enabling Rate Limits サービスへのトラフィックを動的に制限する方法
- Control Headers and Routing ポリシーアダプターを使用して要求ヘッダーとルーティングを操作する方法
- Denials and White/Black Listing 属性ベースまたはIPベースのホワイトリストまたはブラックリストでアクセス制御する方法
可観測性 (Observability)
サービスメッシュからテレメトリ情報を収集する方法である。
- Metrics メトリックス収集を構成する方法
- Logs ログ収集と処理を構成する方法
- Distributed Tracing トレーススパンを収集するためのIstio対応アプリケーションの設定方法
- Visualizing Your Mesh Kialiによる様々な側面を視覚化する方法
- Remotely Accessing Telemetry Addons クラスター外のテレメトリアドオンを公開してアクセスするようにIstioを構成する方法
サンプルアプリケーション Bookinfo
ここから、Istioのパッケージに同梱されるサンプルアプリケーションを動かして、具体的な動作を確認する。インストールする方法は、https://istio.io/docs/examples/bookinfo/#deploying-the-application に説明されているので、合わせて参照すると良い。
次のコマンドで、Istio サイドカー 自動注入の名前空間を指定する。 ここでは、defaultの名前空間を使用するが、実運用では、Istioの適用する名前空間は、defaultを使うべきではないと考えられる。デバッグ用にポッドを稼働させても、Envoy Proxyをインストールしてくるので、扱いづらくなるためである。
maho:istio-1.4.2 maho$ kubectl create namespace bookinfo
namespace/bookinfo created
maho:istio-1.4.2 maho$ kubectl label namespace bookinfo istio-injection=enabled
namespace/default labeled
アプリケーションのインストールは、次のYAMLを適用するだけで良い。
maho:istio-1.4.2 maho$ kubectl apply -n bookinfo -f samples/bookinfo/platform/kube/bookinfo.yaml
これによって、4つのサービス、6つのデプロイメントが作成される。
- service/productpage created
- service/details created
- service/reviews created
- service/ratings created
- deployment.apps/productpage-v1 created
- deployment.apps/details-v1 created
- deployment.apps/reviews-v1 created
- deployment.apps/reviews-v2 created
- deployment.apps/reviews-v3 created
- deployment.apps/ratings-v1 created
productpage は、その本のトップページのような全体感がわかるページである。そして、detailsは詳細、reviewsがそのままレビューを表示するページ、そして、ratingsが点数を設定する。 reviews が v1〜v3 のバージョンがあり、表示の内容が異なっている。サービスのreviewsが一つで、ラベルでポッドと対応づけると、v1〜v3のレビュー画面がランダムに表示される。
サービスのリストを表示したものが次である。全てマイクロサービスと見なして良い。
maho:istio-1.4.2 maho$ kubectl get services -n bookinfo
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
details ClusterIP 10.32.0.222 <none> 9080/TCP 52s
productpage ClusterIP 10.32.0.150 <none> 9080/TCP 52s
ratings ClusterIP 10.32.0.223 <none> 9080/TCP 52s
reviews ClusterIP 10.32.0.33 <none> 9080/TCP 52s
次のはアプリケーションのポッドのリストで、上記のサービスから転送されるポッドのリストである。 ここで、READYの部分に注目して欲しい。READYの列は2/2
と表示されている。これはポッドの中で2つのコンテナが動作することを表している。つまり、元のアプリケーションのポッドに、Envoy Proxyのコンテナが注入されているために、ポッド内でコンテナが二つ動作していることを表している。
maho:istio-1.4.2 maho$ kubectl get pods -n bookinfo
NAME READY STATUS RESTARTS AGE
details-v1-c5b5f496d-wvw5q 2/2 Running 0 91s
productpage-v1-c7765c886-c5tks 2/2 Running 0 90s
ratings-v1-f745cf57b-mqzj8 2/2 Running 0 90s
reviews-v1-75b979578c-lpprp 2/2 Running 0 90s
reviews-v2-597bf96c8f-876n6 2/2 Running 0 91s
reviews-v3-54c6c64795-tghf7 2/2 Running 0 91s
次のコマンドで、簡単なアクセステストを実行して、アプリが動作していることを確認する。<title>Simple Bookstore App</title>
が表示されたら、アプリケーションが正常に稼働していると見なして良い。
maho:istio-1.4.2 maho$ kubectl exec -it $(kubectl get pod -n bookinfo -l app=ratings -o jsonpath='{.items[0].metadata.name}') -n bookinfo -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
Istio ゲートウウェイの設定
前述までの操作で、Istio の Proxy が設定されたアプリケーションが起動した。次に Istio サービスメッシュの外からのトラフィックを受け入れる用に設定する。
maho:istio-1.4.2 maho$ kubectl apply -n bookinfo -f samples/bookinfo/networking/bookinfo-gateway.yaml
gateway.networking.istio.io/bookinfo-gateway created
virtualservice.networking.istio.io/bookinfo created
Gatewayは、Istioによって拡張された Kubernetesのリソースであり、Istioが導入されていない kubernetesクラスタでは利用できない。
maho:istio-1.4.2 maho$ kubectl get gateway -n bookinfo
NAME AGE
bookinfo-gateway 18s
以下の内容から、セレクターに、Ingress Gateway が記述されていることから、それと連携することが判る。
maho:istio-1.4.2 maho$ kubectl describe gateway -n bookinfo
Name: bookinfo-gateway
Namespace: bookinfo
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"networking.istio.io/v1alpha3","kind":"Gateway","metadata":{"annotations":{},"name":"bookinfo-gateway","namespace":"default"...
API Version: networking.istio.io/v1alpha3
Kind: Gateway
Metadata:
Creation Timestamp: 2019-12-11T07:08:34Z
Generation: 1
Resource Version: 7509
Self Link: /apis/networking.istio.io/v1alpha3/namespaces/default/gateways/bookinfo-gateway
UID: 0b7e6b1c-1be5-11ea-9c24-02b444486472
Spec:
Selector:
Istio: ingressgateway
Servers:
Hosts:
*
Port:
Name: http
Number: 80
Protocol: HTTP
Events: <none>
だだし、istio-ingressgateway の LoadBalancerは機能していないので、このままでは、Kubernetesクラスタの外部からアクセスすることはできない。この解決策について、次で解説する。
NodePortの設定
Kubernetesクラスタに、LoadBalancerが組み込まれていない場合でも、istio-ingressgateway は 各サービスを NodePortで開いているので、ワーカーノードのIPアドレスとNodePortのポート番号でアクセスできる。
$ kubectl get service -n istio-system istio-ingressgateway -o yaml
を実行することで、NodePortとサービスの対応関係を知ることができる。
ここでは、JSON形式の出力から、jsonpathを使って値を取り出す方法をみていく。ここでは、アプリケーションのポッドへ繋がるHTTP/HTTPSのポート番号を取得する。
maho:istio-1.4.2 maho$ export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')
maho:istio-1.4.2 maho$ echo $INGRESS_PORT
31128
次に、ingressgatewayが動作するワーカーノードのIPアドレスを取得する。
maho:istio-1.4.2 maho$ export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
maho:istio-1.4.2 maho$ echo $INGRESS_HOST
172.16.20.13
NodePortのポート番号と、ワーカーノードのIPアドレスが揃ったので、環境変数で組み立てて、アクセスを試みる。
maho:istio-1.4.2 maho$ export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT
maho:istio-1.4.2 maho$ curl -s http://${GATEWAY_URL}/productpage | grep -o "<title>.*</title>"
<title>Simple Bookstore App</title>
<title>Simple Bookstore App</title>
が表示され、Istio Gateway で、Istioサービスメッシュ内のアプリケーションにアクセスできた事がわかる。
ブラウザからアクセスした場合は、次のような画面が表示される。再読み込みすると、画面右側のBook Reviews は、3つのバージョンがデプロイされていて、v1,v2,v3と順番に表示される。v1はスターなし、v2は黒いスターつき、v3は赤いスターつきとなっている。

可観測性機能の利用
最初に、マイクロサービスで作られたアプリケーションの構成から、確認を始める。
Isitoに組み込まれたKialiを起動するには次のコマンドを実行する。パソコンのブラウザが立ち上がり、Kialiのトップ画面が表示される。
maho:istio-1.4.2 maho$ istioctl dashboard kiali
http://localhost:61684/kiali
または、https://localhost:61684/kiali/console/overview
でログイン画面がでるので、admin/adminでログインする。
KialiのOverview画面では、名前空間ごとにアプリケーションの数が表示されるので、bookinfoをクリックして進む。

Kialiは、最新状態で画面を表示するため、アプリケーションに対してアクセス実績がなければ、グラフを表示できない。そこで、ブラウザなどから http://${GATEWAY_URL}/productpage を 20秒〜30秒の間、再読み込みを繰り返して、Kialiの画面で状態を確認する。
次の画面の設定では、アプリケーションのマイクロサービスの構造、そして、各区間の待ち時間を表示してくれる。これで、どのマイクロサービスのメッシュの中で、時間を要しているアプリケーションを特定する事ができる。このモードでは,三角のアイコンはサービスを表し、円のアイコンは アプリケーションのワークロードを表す。

次に画面の中の円アイコン productpage-v1をクリックすることで、そのアプリケーションのワークロードを中心とした拡大図に切り替える事ができる。ここでは reviews というサービスの下に、reviews-v1, reviews-v2, reviews-v3 の3種類のアプリケーション(ポッド)のバージョンが存在する事がわかる。そして、reviews-v2, reviews-v3 からは ratings というサービスを利用している事が視覚的に把握できる。
次のスクリーンは、productpage-v1をクリックして表示された拡大図である。緑色のラインの途中に、応答時間が表示されている。これは サービスとアプリケーションのコンテナの間に入った Envoy Proxyで計測した応答時間である。これによって、マイクロサービスの連携の中で、具体的な問題箇所を把握する事ができる。さらに、リクエストの内容といった部分になると、分散トレーシングのツールを利用して観測する事ができる。

リクエストトラフィックの流量制御
二つのバージョンのアプリケーション、すなわち reviews-v1 と reviews-v2 への振分比率を制御することで、Itisoのトラフィック管理の機能を確かめてみたい。これは、新しい機能を追加したアプリケーションのリリースを一期に実行するのではなく、段階的にリリースするといったカナリーリリースを実施するために有用な機能である。
この振分比率の制御には、Istioの二つのリソースを用いる。一つは Destination Rule であり、もう一つは Virtual Service である。
Destination Rule は、ルーティングが発生した後、サービスを対象としたトラフィックに適用されるポリシーを定義します。このルールは、負荷分散アルゴリズムの選択、接続数の上限、応答が遅いなどの異常なホストを検出し振分対象から削除するなどがある。
Virtual services は、Destination Rule と共に、Istioの流量制御の代表的な機能である。 Istioサービスメッシュ内へリクエストをルーティングする方法を構成する。ルーティングルールを順に評価して、マッチしたルールから最終的なルーティング先を決定する。
次は、Istioの導入によって機能が拡張された VirtualService の Kubernetesのリソースで、subset: v1 と v2 に対して weight の値で重み付けを指定している。この中で v1 は 90パーセント、v2 は 10パーセントの比率でルーティングすることになっている。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90
- destination:
host: reviews
subset: v2
weight: 10
上記の subset は、DestinationRule で設定された hostに対するsubsetsの中から、指定されたものである。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
これらの設定をサンプルコードから適用するには、次のようにコマンドを実行する。
はじめに、DestinationRuleの設定を適用する。
maho:networking maho$ cd samples/bookinfo/networking/
maho:networking maho$ kubectl apply -f destination-rule-all.yaml -n bookinfo
destinationrule.networking.istio.io/productpage created
destinationrule.networking.istio.io/reviews created
destinationrule.networking.istio.io/ratings created
destinationrule.networking.istio.io/details created
maho:networking maho$ kubectl get destinationrule -n bookinfo
NAME HOST AGE
details details 7s
productpage productpage 7s
ratings ratings 7s
reviews reviews 7s
次に、VirtualService の設定を実行する。
maho:networking maho$ kubectl apply -f virtual-service-reviews-90-10.yaml -n bookinfo
virtualservice.networking.istio.io/reviews created
maho:networking maho$ kubectl get -f virtual-service-reviews-90-10.yaml -n bookinfo
NAME GATEWAYS HOSTS AGE
reviews [reviews] 14s
maho:networking maho$ kubectl get virtualservices -n bookinfo
NAME GATEWAYS HOSTS AGE
bookinfo [bookinfo-gateway] [*] 11h
reviews [reviews] 33s
これで、ブラウザから、http://${GATEWAY_URL}/productpage をアクセスして、目視で確認できる。さらに、正確に状況を知りたい場合は、Kialiを利用する。
次のスクリーンショットは、サービス reviews から、ポッド reviews-v1 と reviews-v2 に対して、実績値として振分られた比率を表示している。この内容から、三角のアイコン reviewsに Virtual Services が設定され、v1に対して 91.1パーセント、v2に対して 8.9パーセントの比率で、ルーティングされている事がわかる。 この結果を得るために、約1分の間、ブラウザからリロードを繰り返して、統計的に安定な値が出るようにした。

VirtualService の マニフェスト virtual-service-reviews-90-10.yaml を変更することで、比率を変更して、v2 から v3 へのカナリア・リリースに適用するなど、さまざな応用が考えられる。
参考URL:
- Destination Rules コンセプト, https://istio.io/docs/concepts/traffic-management/#destination-rules
- Destination Rule リファレンス, https://istio.io/docs/reference/config/networking/destination-rule/
- Virtual services コンセプト, https://istio.io/docs/concepts/traffic-management/#virtual-services
- Virtual Service リファレンス, https://istio.io/docs/reference/config/networking/virtual-service/
メトリックスのモニタリング
Istioのインストールの際に、オプション --set values.grafana.enabled=true
または --set profile=demo
を追加することで、PrometheusとGrafanaがインストールされるので、メトリックスのグラフィックデータを参照できる。
Grafanaへのアクセスするには、次のコマンドでサーバーポートを、自身のパソコンへフォワードしておき、ブラウザからアクセスする。
maho:networking maho$ kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana -o jsonpath='{.items[0].metadata.name}') 3000:3000 &
[1] 98492
maho:networking maho$ Forwarding from 127.0.0.1:3000 -> 3000
Forwarding from [::1]:3000 -> 3000
Handling connection for 3000
Handling connection for 3000
ブラウザで次のURLをアクセスすると、Grafanaのウェブ画面が表示される。http://localhost:3000/dashboard/db/istio-mesh-dashboard
次のダッシュボードでは、全体のリクエスト量、成功応答、URLアドレス等の間違いのエラー応答 4xx系、内部エラーなどサーバー側のエラー応答 5xx系 が、集計されて表示される。それに加えて、サービスとワークロードのオブジェクト名、そのペアでの応答時間をレポートしてくれる。

Galley や Pilot のメトリックス表示で、メモリ,CPU, Disk, Go routine などの資源消費状況、ランタイムに関するメトリック情報を表示する。次の例は Galleyダッシュボードである。

参考URL:
Installation Configuration Profiles, https://istio.io/docs/setup/additional-setup/config-profiles/
Visualizing Metrics with Grafana, https://istio.io/docs/tasks/observability/metrics/using-istio-dashboard/
分散トレーシング
Jagerは、アプリケーションの開発言語、フレームワーク、プラットフォームに関係なくトレースできる。
Kialiのグラフィック表示では、サービスとワークロードの間のレスポンス時間から、問題の箇所を特定する事ができる。しかし、アプリケーションの開発の段階では、特定の操作や、特定の画面を表示した際に、応答が遅い、エラーが発生するといった課題が発生する。このようなケースの対策を検討するには、Kialiのモニタリング方法では不十分である。個々のリクエストについて、関連するマイクロサービスの応答状況を知るためのツールが分散トレーシングであり Jaeger の機能である。Istioには、Jaegerだけでなく、Zipkin,LightStepなどのツールも利用する事ができるが、ここでは、Jaegerについて注目してみる。
分散トレーシングをIstioで利用するには、インストール・コマンドのオプションに、--set values.tracing.enabled=true
または --set profile=demo
を追加することで、デプロイされる。
Istioの Jaegerがインストールされている状態で、次のコマンドを実行すると、パソコンのブラウザが起動して、Jaegerのウェブ画面が表示される。
maho:istio-1.4.2 maho$ istioctl dashboard jaeger
http://localhost:49763
次の画面では、画面上部のグラフの横軸に時間、縦軸に応答にかかった時間が表示される。そして、その下に、それぞれのリクエストについて、応答時間が表示される。この中から詳細を分析したいリクエストをクリックすると、そのリクエストについての詳細が表示される。

Istioメッシュの外からリクエストを受けて、応答が帰るまでの時間の中で、階層的にコールされたサービスの名前と、それぞれの時間を参照する事ができる。

まとめ
Istioは、Envoy Proxyをコアとして、流量制御と認証の機能が中心であるが、インストール時のオプションとして、全体構造の表示、メトリックス監視、分散トレーシングなどの便利なツールがバンドルされる。素晴らしいツールである。このようなツールが整備されていることで、マイクロサービス化の敷居が、これまでより一段と下がる事が期待される。
Istioを利用していれば、サブシステム毎にマイクロサービス化した方が、パフォーマンス管理や障害箇所を見つけ易くなり、アプリケーションの開発や保守を担当する者にとっての利益が大きいのではないかと思われる。
本記事で取り上げた内容は、Istioの代表的な一部の機能であり、これが全ての機能ではない。