Istio によるマイクロサービス可観測性のベストプラクティス¶
Istio¶
Service Mesh とは¶
近年、ソフトウェアアプリケーションにおけるマイクロサービスの普及は急速に進み、大規模なアプリケーションは複数のマイクロサービスに分割されるようになりました。各マイクロサービスはコンテナ化により個別のコンテナで実行できますが、サービス間通信のネットワークトポロジーは依然として非常に複雑です。サービス間のネットワーク通信が極めて重要である以上、複数のサービスプロキシを実装し、制御されたサービス間通信チャネルの安全性と堅牢性を確保する基本コンポーネントが必要不可欠です。
サービスメッシュ(Service Mesh)とは、これらのアプリケーションを構成するマイクロサービスのネットワークと、それらの間の相互作用を説明するために使用される用語です。個々のサービス呼び出しは Sidecar として表現されます。多数のサービスが存在する場合、メッシュとして表現されます。下図の緑色の四角はアプリケーションのマイクロサービス、青色の四角は Sidecar、線はサービス間の呼び出し関係を示し、Sidecar 間の接続がネットワークを形成します。

Istio の概要¶
Istio はオープンソースのサービスメッシュであり、既存の分散アプリケーションに透過的にレイヤーされます。サービスメッシュ全体の動作に対する洞察と操作制御の機能、およびマイクロサービスアプリケーションのさまざまなニーズを満たす完全なソリューションを提供します。
Istio のコアコンポーネント¶
Istio サービスメッシュは、データプレーンとコントロールプレーンで構成されます。
- データプレーンは、一連のスマートプロキシ(Envoy)で構成されます。Envoy は Sidecar としてデプロイされ、マイクロサービス間の Sidecar 間通信は、ポリシー制御とテレメトリー収集(Mixer)によって実現されます。
- コントロールプレーンは、プロキシを管理および構成してトラフィックをルーティングする役割を担います。Citadel は、組み込みの ID と資格情報管理により、強力なサービス間およびエンドユーザー認証を提供します。Pilot は、Envoy Sidecar にサービスディスカバリ、スマートルーティング(A/B テスト、カナリアデプロイなど)、トラフィック管理、エラーハンドリング(タイムアウト、リトライ、サーキットブレーカー)の機能を提供します。Galley は、Istio 設定の検証、取得、処理、配布を行うコンポーネントです。
Istio の分散型トレーシング¶
Envoy は Jaeger をネイティブサポートしており、トレーシングに必要な x-b3 で始まる Header(x-b3-traceid、x-b3-spanid、x-b3-parentspanid、x-b3-sampled、x-b3-flags)と x-request-id が、ビジネスロジックによって異なるサービス間で受け渡され、Envoy から Jaeger に報告され、最終的に Jaeger が完全なトレーシング情報を生成します。
Istio における Envoy と Jaeger の関係は以下の通りです。
図中の Front Envoy は、最初にリクエストを受信する Envoy Sidecar を指し、ルートスパンを作成してリクエスト Header に追加する役割を担います。リクエストが異なるサービスに到達すると、Envoy Sidecar がトレーシング情報を報告します。
Envoy の分散型トレーシングは Jaeger をネイティブサポートしており、Envoy は外部トレーシングサービスの統合をサポートし、zipkin および zipkin 互換のバックエンド(jaeger)をサポートします。Istio の分散型トレーシングはグローバル設定 zipkinAddress を提供し、Envoy の報告アドレスは proxy_init の --zipkinAddress パラメータで渡されます。
Istio の可観測性¶
Istio の堅牢なトレーシング、モニタリング、ログ機能により、サービスメッシュのデプロイメントを深く理解することができます。Istio のモニタリング機能を通じて、サービスのパフォーマンスがアップストリームとダウンストリームにどのように影響するかを真に把握できます。また、カスタムダッシュボードは、すべてのサービスのパフォーマンスを可視化し、他のプロセスにどのように影響するかを確認する機能を提供します。これらの機能はすべて、サービスの SLO をより効果的に設定、監視、強化することを可能にします。
BookInfo の概要¶
このサンプルは、複数の Istio 機能をデモンストレーションするためのアプリケーションをデプロイします。このアプリケーションは、4 つの個別のマイクロサービスで構成されています。このアプリケーションは、オンライン書店のカテゴリを模擬し、書籍の情報を表示します。ページには、書籍の説明、書籍の詳細(ISBN、ページ数など)、およびその書籍に関するいくつかのレビューが表示されます。
Bookinfo アプリケーションは、4 つの個別のマイクロサービスに分かれています。
- productpage:productpage(Python)マイクロサービスは、details および reviews マイクロサービスを呼び出してページを構成します。
- details:details(Ruby)マイクロサービスは、書籍の詳細情報を含みます。
- reviews:reviews(Java)マイクロサービスは、書籍のレビューを含み、ratings マイクロサービスも呼び出します。
- ratings:ratings(Node.js)マイクロサービスは、書籍のランキング情報を含みます。
reviews マイクロサービスは 3 つのバージョンを提供します。
- バージョン v1 は ratings サービスを呼び出しません。
- バージョン v2 は ratings サービスを呼び出し、各評価を 1 から 5 の黒い星で表示します。
- バージョン v3 は ratings サービスを呼び出し、各評価を 1 から 5 の赤い星で表示します。
Bookinfo のトレースデータは、istio の configmap 内の zipkin.address を DataKit アドレスに変更するだけで、DataKit で zipkin コレクターを有効にする必要があり、これによりトレースデータを DataKit にプッシュできます。
環境デプロイメント¶
前提条件¶
Kubernetes¶
このサンプルは、CentOS 7.9 上で minikube を使用して作成されたバージョン 1.21.2 の Kubernetes クラスターで動作します。
DataKit のデプロイ¶
<Daemonset による DataKit のデプロイ> を参照してください。
コレクターの有効化¶
Daemonset による DataKit のデプロイ の datakit.yaml ファイルを使用し、Kubernetes クラスターの master ノード /usr/local/df-demo/datakit.yaml にアップロードします。datakit.yaml ファイルを修正し、ConfigMap を追加してファイルをマウントすることで、Zipkin および Prom コレクターを有効にします。最終結果として、DataKit がデプロイされた状態になります。
- ファイル
/usr/local/datakit/conf.d/zipkin/zipkin.confを追加:Zipkin のメトリクスコレクターを有効にします。 - ファイル
/usr/local/datakit/conf.d/prom/prom_istiod.confを追加:Istiod Pod のメトリクスコレクターを有効にします。 - ファイル
/usr/local/datakit/conf.d/prom/prom-ingressgateway.confを追加:Ingressgateway のメトリクスコレクターを有効にします。 - ファイル
/usr/local/datakit/conf.d/prom/prom-egressgateway.confを追加:Egressgateway のメトリクスコレクターを有効にします。
ingressgateway と egressgateway を収集するには、Service を使用してポート 15020 にアクセスする必要があるため、ingressgateway と egressgateway の Service を新規作成する必要があります。
istio-ingressgateway-service-ext.yaml
istio-egressgateway-service-ext.yaml
Service の作成
kubectl apply -f istio-ingressgateway-service-ext.yaml
kubectl apply -f istio-egressgateway-service-ext.yaml
以下は datakit.yaml ファイルの修正部分です。
ConfigMap の追加
apiVersion: v1
kind: ConfigMap
metadata:
name: datakit-conf
namespace: datakit
data:
zipkin.conf: |-
[[inputs.zipkin]]
pathV1 = "/api/v1/spans"
pathV2 = "/api/v2/spans"
prom_istiod.conf: |-
[[inputs.prom]]
url = "http://istiod.istio-system.svc.cluster.local:15014/metrics"
source = "prom-istiod"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name ="cpu"
[inputs.prom.tags]
app_id="istiod"
prom-ingressgateway.conf: |-
[[inputs.prom]]
url = "http://istio-ingressgateway-ext.istio-system.svc.cluster.local:15020/stats/prometheus"
source = "prom-ingressgateway"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name ="cpu"
prom-egressgateway.conf: |-
[[inputs.prom]]
url = "http://istio-egressgateway-ext.istio-system.svc.cluster.local:15020/stats/prometheus"
source = "prom-egressgateway"
metric_types = ["counter", "gauge"]
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
interval = "60s"
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name ="cpu"
zipkin.conf と prom_istiod.conf のマウント
apiVersion: apps/v1
kind: DaemonSet
...
spec:
template
spec:
containers:
- env:
volumeMounts: # 以下は追加部分
- mountPath: /usr/local/datakit/conf.d/zipkin/zipkin.conf
name: datakit-conf
subPath: zipkin.conf
- mountPath: /usr/local/datakit/conf.d/prom/prom_istiod.conf
name: datakit-conf
subPath: prom_istiod.conf
- mountPath: /usr/local/datakit/conf.d/prom/prom-ingressgateway.conf
name: datakit-conf
subPath: prom-ingressgateway.conf
- mountPath: /usr/local/datakit/conf.d/prom/prom-egressgateway.conf
name: datakit-conf
subPath: prom-egressgateway.conf
トークンの置き換え¶
Guance にログインし、「統合」 -> 「DataKit」からトークンをコピーし、datakit.yaml 内の <your-token> を置き換えます。
DataKit の再デプロイ¶
Istio のデプロイ¶
Istio のダウンロード¶
ダウンロード から Source Code と istio-1.11.2-linux-amd64.tar.gz をダウンロードします。
Istio のインストール¶
istio-1.11.2-linux-amd64.tar.gz を /usr/local/df-demo/ ディレクトリにアップロードします。Kubernetes が存在するサーバーのプライベートネットワークアドレスは 172.16.0.15 です。172.16.0.15 をご自身の IP に置き換えてください。
su minikube
cd /usr/local/df-demo/
tar zxvf istio-1.11.2-linux-amd64.tar.gz
cd /usr/local/df-demo/istio-1.11.2
export PATH=$PWD/bin:$PATH$
cp -ar /usr/local/df-demo/istio-1.11.2/bin/istioctl /usr/bin/
istioctl install --set profile=demo
インストールの確認¶
デプロイが成功すると、ingressgateway、egressgateway、istiod が Running 状態になります。
BookInfo のデプロイ¶
ファイルのコピー¶
ソースコードを解凍し、/usr/local/df-demo/istio-1.11.2/samples/bookinfo/src/productpage ディレクトリを /usr/local/df-demo/bookinfo ディレクトリにコピーします。BookInfo のデプロイに必要な yaml をコピーします。
cp /usr/local/df-demo/istio-1.11.2/samples/bookinfo/networking/bookinfo-gateway.yaml /usr/local/df-demo/bookinfo/bookinfo-gateway.yaml
cp /usr/local/df-demo/istio-1.11.2/samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml /usr/local/df-demo/bookinfo/virtual-service-ratings-test-delay.yaml
cp /usr/local/df-demo/istio-1.11.2/samples/bookinfo/platform/kube/bookinfo.yaml /usr/local/df-demo/bookinfo/bookinfo.yaml
自動インジェクションの有効化¶
prod 名前空間を作成し、この名前空間で Pod 作成時に Sidecar が自動的にインジェクトされるようにラベルを付け、Pod の入出力トラフィックがすべて Sidecar によって処理されるようにします。
RUM の有効化¶
- 1 Guance にログインし、「ユーザーアクセスモニタリング」 -> 「アプリケーションを作成」をクリックし、bookinfo と入力します。
js を/usr/local/df-demo/bookinfo/productpage/templates/productpage.htmlにコピーし、を http://<your-外网 ip>:9529に変更します。
- 2
/usr/local/df-demo/bookinfo/productpage/Dockerfileを修正します。
- 3 イメージの作成
cd /usr/local/df-demo/bookinfo/productpage
eval $(minikube docker-env)
docker build -t product-page:v1 .
- 4 イメージの置き換え
/usr/local/df-demo/bookinfo/bookinfo.yaml 内の image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2 を image: product-page:v1 に置き換えます。
APM と DataKit の連携¶
上の図では、トレースデータがデフォルトで zipkin.istio-system:9411 にプッシュされていることがわかります。DataKit サービスは datakit 名前空間にあり、ポートは 9529 であるため、ここで変換を行う必要があります。
詳細については、<Kubernetes クラスターでの ExternalName を使用した DataKit サービスのマッピング> を参照してください。
namespace の追加¶
bookinfo の yaml を修正し、すべてのリソースの metadata に namespace: prod を追加します。
vi /usr/local/df-demo/bookinfo/bookinfo.yaml
vi /usr/local/df-demo/bookinfo/bookinfo-gateway.yaml
vi /usr/local/df-demo/bookinfo/virtual-service-ratings-test-delay.yaml
Pod カスタム収集の有効化¶
bookinfo.yaml を修正します。
すべての Deployment コントローラーの Pod テンプレートに annotations を追加します。
パラメータ説明
- url:Exporter アドレス
- source:コレクター名
- metric_types:メトリクスタイプフィルター
- measurement_name:収集後のメジャーメント名
- interval:メトリクス収集頻度、s 秒
- $IP:Pod のプライベートネットワーク IP のワイルドカード
- $NAMESPACE:Pod が存在する名前空間
- tags_ignore:無視するタグ。
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-product"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
pod_name = "$PODNAME"
- 完全な
bookinfo.yamlは以下の通りです。
bookinfo.yaml
apiVersion: v1
kind: Service
metadata:
name: details
namespace: prod
labels:
app: details
service: details
spec:
ports:
- port: 9080
name: http
selector:
app: details
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-details
namespace: prod
labels:
account: details
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: details-v1
namespace: prod
labels:
app: details
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: details
version: v1
template:
metadata:
labels:
app: details
version: v1
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-details"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
spec:
serviceAccountName: bookinfo-details
containers:
- name: details
image: docker.io/istio/examples-bookinfo-details-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Ratings service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: ratings
namespace: prod
labels:
app: ratings
service: ratings
spec:
ports:
- port: 9080
name: http
selector:
app: ratings
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-ratings
namespace: prod
labels:
account: ratings
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: ratings-v1
namespace: prod
labels:
app: ratings
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: ratings
version: v1
template:
metadata:
labels:
app: ratings
version: v1
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-ratings"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
spec:
serviceAccountName: bookinfo-ratings
containers:
- name: ratings
image: docker.io/istio/examples-bookinfo-ratings-v1:1.16.2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
securityContext:
runAsUser: 1000
---
##################################################################################################
# Reviews service
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: reviews
namespace: prod
labels:
app: reviews
service: reviews
spec:
ports:
- port: 9080
name: http
selector:
app: reviews
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-reviews
namespace: prod
labels:
account: reviews
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v1
namespace: prod
labels:
app: reviews
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v1
template:
metadata:
labels:
app: reviews
version: v1
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-review1"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
#measurement_prefix = ""
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v1:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v2
namespace: prod
labels:
app: reviews
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v2
template:
metadata:
labels:
app: reviews
version: v2
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-review2"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
#measurement_prefix = ""
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v2:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: reviews-v3
namespace: prod
labels:
app: reviews
version: v3
spec:
replicas: 1
selector:
matchLabels:
app: reviews
version: v3
template:
metadata:
labels:
app: reviews
version: v3
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-review3"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
spec:
serviceAccountName: bookinfo-reviews
containers:
- name: reviews
image: docker.io/istio/examples-bookinfo-reviews-v3:1.16.2
imagePullPolicy: IfNotPresent
env:
- name: LOG_DIR
value: "/tmp/logs"
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
- name: wlp-output
mountPath: /opt/ibm/wlp/output
securityContext:
runAsUser: 1000
volumes:
- name: wlp-output
emptyDir: {}
- name: tmp
emptyDir: {}
---
##################################################################################################
# Productpage services
##################################################################################################
apiVersion: v1
kind: Service
metadata:
name: productpage
namespace: prod
labels:
app: productpage
service: productpage
spec:
ports:
- port: 9080
name: http
selector:
app: productpage
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: bookinfo-productpage
namespace: prod
labels:
account: productpage
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: productpage-v1
namespace: prod
labels:
app: productpage
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: productpage
version: v1
template:
metadata:
labels:
app: productpage
version: v1
annotations:
datakit/prom.instances: |
[[inputs.prom]]
url = "http://$IP:15020/stats/prometheus"
source = "minik8s-istio-product"
metric_types = ["counter", "gauge"]
interval = "60s"
tags_ignore = ["cache","cluster_type","component","destination_app","destination_canonical_revision","destination_canonical_service","destination_cluster","destination_principal","group","grpc_code","grpc_method","grpc_service","grpc_type","reason","request_protocol","request_type","resource","responce_code_class","response_flags","source_app","source_canonical_revision","source_canonical-service","source_cluster","source_principal","source_version","wasm_filter"]
metric_name_filter = ["istio_requests_total","pilot_k8s_cfg_events","istio_build","process_virtual_memory_bytes","process_resident_memory_bytes","process_cpu_seconds_total","envoy_cluster_assignment_stale","go_goroutines","pilot_xds_pushes","pilot_proxy_convergence_time_bucket","citadel_server_root_cert_expiry_timestamp","pilot_conflict_inbound_listener","pilot_conflict_outbound_listener_http_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_tcp","pilot_conflict_outbound_listener_tcp_over_current_http","pilot_virt_services","galley_validation_failed","pilot_services","envoy_cluster_upstream_cx_total","envoy_cluster_upstream_cx_connect_fail","envoy_cluster_upstream_cx_active","envoy_cluster_upstream_cx_rx_bytes_total","envoy_cluster_upstream_cx_tx_bytes_total","istio_request_duration_milliseconds_bucket","istio_request_duration_seconds_bucket","istio_request_bytes_bucket","istio_response_bytes_bucket"]
#measurement_prefix = ""
measurement_name = "istio_prom"
#[[inputs.prom.measurements]]
# prefix = "cpu_"
# name = "cpu"
[inputs.prom.tags]
namespace = "$NAMESPACE"
spec:
serviceAccountName: bookinfo-productpage
containers:
- name: productpage
#image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
image: image: product-page:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 9080
volumeMounts:
- name: tmp
mountPath: /tmp
securityContext:
runAsUser: 1000
volumes:
- name: tmp
emptyDir: {}
---
- 完全な
bookinfo-gateway.yaml
bookinfo-gateway.yaml
kind: Gateway
metadata:
name: bookinfo-gateway
namespace: prod
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
namespace: prod
spec:
hosts:
- "*"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
host: productpage
port:
number: 9080
サービスのデプロイ¶
cd /usr/local/df-demo/bookinfo
kubectl apply -f bookinfo.yaml
kubectl apply -f bookinfo-gateway.yaml
nginx による productpage サービスへのプロキシ¶
このサンプルでは minikube を使用しているため、nginx を介してクラスター内のサービスにプロキシする必要があります。そのため、nginx の設定が必要です。
- minikube http2 の URL を確認します。
- root アカウントでサーバーにログインし、
proxy_passを http2 サービスのアドレスに変更します。
- nginx を再起動します。
productpage へのアクセス¶
http://121.43.225.226/productpage
可観測性の演習¶
メトリクス (Metrics)¶
BookInfo のデプロイ時に、Pod カスタム収集を有効にし、measurement_name = "istio_prom" を設定しました。
「Guance」 -> 「メトリクス」にログインし、istio_prom メジャーメントを確認します。
トレース (Traces)¶
RUM¶
ユーザーアクセスモニタリングモジュールを使用して、UV、PV、セッション数、アクセスされたページなどの情報を確認します。
APM¶
アプリケーションパフォーマンスモニタリング(APM)を使用して、トレースデータを確認します。
ログ (logs)¶
stdout¶
DataKit はデフォルトで /dev/stdout に出力されるログを収集します。より高度な機能を使用する必要がある場合は、<コンテナログ収集> を参照してください。
ログファイル¶
このサンプルではログファイルの収集には対応していません。必要な場合は、<Kubernetes アプリケーションの RUM-APM-LOG 連携分析> を参照してください。
トレースタイムアウト分析¶
virtual-service-ratings-test-delay.yamlを実行します。
- jason でログインし、パスワードは空欄のまま、productpage 画面にアクセスします。
- タイムアウトしたトレースをクリックし、フレームグラフを観察して、タイムアウト呼び出しを特定します。



























