EnvoyとIstiodのデバッグ

Istioは、トラフィック管理の設定問題を診断するのに非常に役立つ2つのコマンド、proxy-statusproxy-config コマンドを提供します。proxy-status コマンドを使用すると、メッシュの概要を把握し、問題の原因となっているプロキシを特定できます。次に、proxy-config を使用してEnvoyの設定を調べ、問題を診断できます。

以下で説明するコマンドを試したい場合は、次のいずれかを選択できます。

または

  • Kubernetesクラスタで実行されている独自のアプリケーションに対して同様のコマンドを使用する。

メッシュの概要を把握する

proxy-status コマンドを使用すると、メッシュの概要を把握できます。サイドカーのいずれかが設定を受信していない、または同期していない疑いがある場合は、proxy-status でそれを知ることができます。

$ istioctl proxy-status
NAME CDS LDS EDS RDS ISTIOD VERSION details-v1-558b8b4b76-qzqsg.default SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0 istio-ingressgateway-66c994c45c-cmb7x.istio-system SYNCED SYNCED SYNCED NOT SENT istiod-6cf8d4f9cb-wm7x6 1.7.0 productpage-v1-6987489c74-nc7tj.default SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0 prometheus-7bdc59c94d-hcp59.istio-system SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0 ratings-v1-7dc98c7588-5m6xj.default SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0 reviews-v1-7f99cc4496-rtsqn.default SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0 reviews-v2-7d79d5bd5d-tj6kf.default SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0 reviews-v3-7dbcdcbc56-t8wrx.default SYNCED SYNCED SYNCED SYNCED istiod-6cf8d4f9cb-wm7x6 1.7.0

このリストにプロキシがない場合は、現在 Istiod インスタンスに接続されていないため、設定を受信していないことを意味します。

  • SYNCED は、Envoyが最後に Istiod が送信した構成を認識したことを意味します。
  • NOT SENT は、Istiod が Envoy に何も送信していないことを意味します。これは通常、Istiod に送信するものがないためです。
  • STALE は、Istiod が Envoy に更新を送信したが、確認応答を受信していないことを意味します。これは通常、Envoy と Istiod 間のネットワークの問題、または Istio 自体のバグを示します。

EnvoyとIstiodの差分を取得する

proxy-status コマンドは、プロキシ ID を指定することで、Envoy がロードした構成と Istiod が送信する構成の差分を取得するためにも使用できます。これにより、同期していないものが正確にどこにあるか、問題がどこにあるかを特定するのに役立ちます。

$ istioctl proxy-status details-v1-6dcc6fbb9d-wsjz4.default
--- Istiod Clusters +++ Envoy Clusters @@ -374,36 +374,14 @@ "edsClusterConfig": { "edsConfig": { "ads": { } }, "serviceName": "outbound|443||public-cr0bdc785ce3f14722918080a97e1f26be-alb1.kube-system.svc.cluster.local" - }, - "connectTimeout": "1.000s", - "circuitBreakers": { - "thresholds": [ - { - - } - ] - } - } - }, - { - "cluster": { - "name": "outbound|53||kube-dns.kube-system.svc.cluster.local", - "type": "EDS", - "edsClusterConfig": { - "edsConfig": { - "ads": { - - } - }, - "serviceName": "outbound|53||kube-dns.kube-system.svc.cluster.local" }, "connectTimeout": "1.000s", "circuitBreakers": { "thresholds": [ { } Listeners Match Routes Match (RDS last loaded at Tue, 04 Aug 2020 11:52:54 IST)

ここでは、リスナーとルートは一致していますが、クラスターは同期していないことがわかります。

Envoy構成の詳細な調査

proxy-config コマンドは、特定の Envoy インスタンスがどのように構成されているかを確認するために使用できます。これは、Istio の構成とカスタムリソースだけでは検出できない問題を特定するために使用できます。特定の Pod のクラスター、リスナー、またはルートの基本的な概要を取得するには、次のコマンドを使用します(必要に応じて、リスナーまたはルートをクラスターに変更します)。

$ istioctl proxy-config cluster -n istio-system istio-ingressgateway-7d6874b48f-qxhn5
SERVICE FQDN PORT SUBSET DIRECTION TYPE DESTINATION RULE BlackHoleCluster - - - STATIC agent - - - STATIC details.default.svc.cluster.local 9080 - outbound EDS details.default istio-ingressgateway.istio-system.svc.cluster.local 80 - outbound EDS istio-ingressgateway.istio-system.svc.cluster.local 443 - outbound EDS istio-ingressgateway.istio-system.svc.cluster.local 15021 - outbound EDS istio-ingressgateway.istio-system.svc.cluster.local 15443 - outbound EDS istiod.istio-system.svc.cluster.local 443 - outbound EDS istiod.istio-system.svc.cluster.local 853 - outbound EDS istiod.istio-system.svc.cluster.local 15010 - outbound EDS istiod.istio-system.svc.cluster.local 15012 - outbound EDS istiod.istio-system.svc.cluster.local 15014 - outbound EDS kube-dns.kube-system.svc.cluster.local 53 - outbound EDS kube-dns.kube-system.svc.cluster.local 9153 - outbound EDS kubernetes.default.svc.cluster.local 443 - outbound EDS ... productpage.default.svc.cluster.local 9080 - outbound EDS prometheus_stats - - - STATIC ratings.default.svc.cluster.local 9080 - outbound EDS reviews.default.svc.cluster.local 9080 - outbound EDS sds-grpc - - - STATIC xds-grpc - - - STRICT_DNS zipkin - - - STRICT_DNS

Envoy をデバッグするには、Envoy のクラスター/リスナー/ルート/エンドポイントと、それらがどのように相互作用するかを理解する必要があります。proxy-config コマンドを -o json およびフィルタリングフラグと一緒に使用して、productpage Pod から reviews Pod の reviews:9080 にリクエストを送信する際の Envoy の動きを追跡します。

  1. Pod のリスナーの概要を照会すると、Istio が次のリスナーを生成していることがわかります。

    • Pod へのすべてのインバウンドトラフィックを受信する 0.0.0.0:15006 のリスナーと、Pod へのすべてのアウトバウンドトラフィックを受信し、リクエストを仮想リスナーに引き渡す 0.0.0.0:15001 のリスナーです。
    • アウトバウンド TCP/HTTPS トラフィック用の、サービスIPごと、およびHTTP以外ごとの仮想リスナー。
    • インバウンドトラフィック用に公開されたポートごとに、Pod IP上の仮想リスナー。
    • アウトバウンドHTTPトラフィック用に、HTTPポートごとに0.0.0.0の仮想リスナー。
    $ istioctl proxy-config listeners productpage-v1-6c886ff494-7vxhs
    ADDRESS PORT MATCH DESTINATION 10.96.0.10 53 ALL Cluster: outbound|53||kube-dns.kube-system.svc.cluster.local 0.0.0.0 80 App: HTTP Route: 80 0.0.0.0 80 ALL PassthroughCluster 10.100.93.102 443 ALL Cluster: outbound|443||istiod.istio-system.svc.cluster.local 10.111.121.13 443 ALL Cluster: outbound|443||istio-ingressgateway.istio-system.svc.cluster.local 10.96.0.1 443 ALL Cluster: outbound|443||kubernetes.default.svc.cluster.local 10.100.93.102 853 App: HTTP Route: istiod.istio-system.svc.cluster.local:853 10.100.93.102 853 ALL Cluster: outbound|853||istiod.istio-system.svc.cluster.local 0.0.0.0 9080 App: HTTP Route: 9080 0.0.0.0 9080 ALL PassthroughCluster 0.0.0.0 9090 App: HTTP Route: 9090 0.0.0.0 9090 ALL PassthroughCluster 10.96.0.10 9153 App: HTTP Route: kube-dns.kube-system.svc.cluster.local:9153 10.96.0.10 9153 ALL Cluster: outbound|9153||kube-dns.kube-system.svc.cluster.local 0.0.0.0 15001 ALL PassthroughCluster 0.0.0.0 15006 Addr: 10.244.0.22/32:15021 inbound|15021|mgmt-15021|mgmtCluster 0.0.0.0 15006 Addr: 10.244.0.22/32:9080 Inline Route: /* 0.0.0.0 15006 Trans: tls; App: HTTP TLS; Addr: 0.0.0.0/0 Inline Route: /* 0.0.0.0 15006 App: HTTP; Addr: 0.0.0.0/0 Inline Route: /* 0.0.0.0 15006 App: Istio HTTP Plain; Addr: 10.244.0.22/32:9080 Inline Route: /* 0.0.0.0 15006 Addr: 0.0.0.0/0 InboundPassthroughClusterIpv4 0.0.0.0 15006 Trans: tls; App: TCP TLS; Addr: 0.0.0.0/0 InboundPassthroughClusterIpv4 0.0.0.0 15010 App: HTTP Route: 15010 0.0.0.0 15010 ALL PassthroughCluster 10.100.93.102 15012 ALL Cluster: outbound|15012||istiod.istio-system.svc.cluster.local 0.0.0.0 15014 App: HTTP Route: 15014 0.0.0.0 15014 ALL PassthroughCluster 0.0.0.0 15021 ALL Inline Route: /healthz/ready* 10.111.121.13 15021 App: HTTP Route: istio-ingressgateway.istio-system.svc.cluster.local:15021 10.111.121.13 15021 ALL Cluster: outbound|15021||istio-ingressgateway.istio-system.svc.cluster.local 0.0.0.0 15090 ALL Inline Route: /stats/prometheus* 10.111.121.13 15443 ALL Cluster: outbound|15443||istio-ingressgateway.istio-system.svc.cluster.local
  2. 上記の概要から、すべてのサイドカーが 0.0.0.0:15006 にバインドされたリスナー(IPテーブルがすべてのインバウンドPodトラフィックをルーティングする場所)と、0.0.0.0:15001 にバインドされたリスナー(IPテーブルがすべてのアウトバウンドPodトラフィックをルーティングする場所)を持っていることがわかります。0.0.0.0:15001リスナーは、リクエストの元の宛先に最も一致する仮想リスナーにリクエストを引き渡します(一致するものが見つかった場合)。そうでない場合は、宛先に直接接続する PassthroughCluster にリクエストを送信します。

    $ istioctl proxy-config listeners productpage-v1-6c886ff494-7vxhs --port 15001 -o json
    [ { "name": "virtualOutbound", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 15001 } }, "filterChains": [ { "filters": [ { "name": "istio.stats", "typedConfig": { "@type": "type.googleapis.com/udpa.type.v1.TypedStruct", "typeUrl": "type.googleapis.com/envoy.extensions.filters.network.wasm.v3.Wasm", "value": { "config": { "configuration": "{\n \"debug\": \"false\",\n \"stat_prefix\": \"istio\"\n}\n", "root_id": "stats_outbound", "vm_config": { "code": { "local": { "inline_string": "envoy.wasm.stats" } }, "runtime": "envoy.wasm.runtime.null", "vm_id": "tcp_stats_outbound" } } } } }, { "name": "envoy.tcp_proxy", "typedConfig": { "@type": "type.googleapis.com/envoy.config.filter.network.tcp_proxy.v2.TcpProxy", "statPrefix": "PassthroughCluster", "cluster": "PassthroughCluster" } } ], "name": "virtualOutbound-catchall-tcp" } ], "trafficDirection": "OUTBOUND", "hiddenEnvoyDeprecatedUseOriginalDst": true } ]
  3. リクエストはポート 9080 へのアウトバウンドHTTPリクエストであるため、0.0.0.0:9080 仮想リスナーに引き渡されます。このリスナーは、構成されたRDSでルート構成を検索します。この場合、Istiod (ADS経由) によって構成されたRDSでルート 9080 を検索します。

    $ istioctl proxy-config listeners productpage-v1-6c886ff494-7vxhs -o json --address 0.0.0.0 --port 9080
    ... "rds": { "configSource": { "ads": {}, "resourceApiVersion": "V3" }, "routeConfigName": "9080" } ...
  4. 9080 ルート構成には、各サービスの仮想ホストのみがあります。リクエストは reviews サービスに向かっているため、Envoyはリクエストがドメインに一致する仮想ホストを選択します。ドメインで一致すると、Envoyはリクエストに一致する最初のルートを探します。この場合、高度なルーティングはないため、すべてに一致するルートが1つだけです。このルートは、Envoyに outbound|9080||reviews.default.svc.cluster.local クラスタにリクエストを送信するように指示します。

    $ istioctl proxy-config routes productpage-v1-6c886ff494-7vxhs --name 9080 -o json
    [ { "name": "9080", "virtualHosts": [ { "name": "reviews.default.svc.cluster.local:9080", "domains": [ "reviews.default.svc.cluster.local", "reviews", "reviews.default.svc", "reviews.default", "10.98.88.0", ], "routes": [ { "name": "default", "match": { "prefix": "/" }, "route": { "cluster": "outbound|9080||reviews.default.svc.cluster.local", "timeout": "0s", } } ] ...
  5. このクラスタは、Istiod (ADS経由) から関連するエンドポイントを取得するように構成されています。したがって、Envoyは serviceName フィールドをキーとして使用してエンドポイントのリストを検索し、それらのいずれかにリクエストをプロキシします。

    $ istioctl proxy-config cluster productpage-v1-6c886ff494-7vxhs --fqdn reviews.default.svc.cluster.local -o json
    [ { "name": "outbound|9080||reviews.default.svc.cluster.local", "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {}, "resourceApiVersion": "V3" }, "serviceName": "outbound|9080||reviews.default.svc.cluster.local" }, "connectTimeout": "10s", "circuitBreakers": { "thresholds": [ { "maxConnections": 4294967295, "maxPendingRequests": 4294967295, "maxRequests": 4294967295, "maxRetries": 4294967295 } ] }, } ]
  6. このクラスタで現在利用可能なエンドポイントを確認するには、proxy-config エンドポイントコマンドを使用します。

    $ istioctl proxy-config endpoints productpage-v1-6c886ff494-7vxhs --cluster "outbound|9080||reviews.default.svc.cluster.local"
    ENDPOINT STATUS OUTLIER CHECK CLUSTER 172.17.0.7:9080 HEALTHY OK outbound|9080||reviews.default.svc.cluster.local 172.17.0.8:9080 HEALTHY OK outbound|9080||reviews.default.svc.cluster.local 172.17.0.9:9080 HEALTHY OK outbound|9080||reviews.default.svc.cluster.local

ブートストラップ構成の検査

これまで、主にIstiodから取得した構成を見てきましたが、Envoyには、Istiodの場所などの情報を含むいくつかのブートストラップ構成が必要です。これを確認するには、次のコマンドを使用します。

$ istioctl proxy-config bootstrap -n istio-system istio-ingressgateway-7d6874b48f-qxhn5
{ "bootstrap": { "node": { "id": "router~172.30.86.14~istio-ingressgateway-7d6874b48f-qxhn5.istio-system~istio-system.svc.cluster.local", "cluster": "istio-ingressgateway", "metadata": { "CLUSTER_ID": "Kubernetes", "EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,MESH_ID,SERVICE_ACCOUNT,CLUSTER_ID", "INSTANCE_IPS": "10.244.0.7", "ISTIO_PROXY_SHA": "istio-proxy:f98b7e538920abc408fbc91c22a3b32bc854d9dc", "ISTIO_VERSION": "1.7.0", "LABELS": { "app": "istio-ingressgateway", "chart": "gateways", "heritage": "Tiller", "istio": "ingressgateway", "pod-template-hash": "68bf7d7f94", "release": "istio", "service.istio.io/canonical-name": "istio-ingressgateway", "service.istio.io/canonical-revision": "latest" }, "MESH_ID": "cluster.local", "NAME": "istio-ingressgateway-68bf7d7f94-sp226", "NAMESPACE": "istio-system", "OWNER": "kubernetes://apis/apps/v1/namespaces/istio-system/deployments/istio-ingressgateway", "ROUTER_MODE": "sni-dnat", "SDS": "true", "SERVICE_ACCOUNT": "istio-ingressgateway-service-account", "WORKLOAD_NAME": "istio-ingressgateway" }, "userAgentBuildVersion": { "version": { "majorNumber": 1, "minorNumber": 15 }, "metadata": { "build.type": "RELEASE", "revision.sha": "f98b7e538920abc408fbc91c22a3b32bc854d9dc", "revision.status": "Clean", "ssl.version": "BoringSSL" } }, }, ...

Istiodへの接続の検証

Istiodへの接続を確認することは、トラブルシューティングに役立つステップです。サービスメッシュ内のすべてのプロキシコンテナは、Istiodと通信できる必要があります。これは、いくつかの簡単なステップで実現できます。

  1. curl Podを作成します。

    $ kubectl create namespace foo $ kubectl apply -f <(istioctl kube-inject -f samples/curl/curl.yaml) -n foo
  2. curl を使用して Istiod への接続をテストします。次の例では、デフォルトの Istiod 構成パラメーターと相互 TLS が有効になっている状態で、v1 登録 API を呼び出します。

    $ kubectl exec $(kubectl get pod -l app=curl -n foo -o jsonpath={.items..metadata.name}) -c curl -n foo -- curl -sS istiod.istio-system:15014/version

Istiodのバージョンを一覧表示するレスポンスを受け取るはずです。

Istioが使用しているEnvoyのバージョンは?

デプロイメントで使用されているEnvoyのバージョンを確認するには、コンテナに exec し、server_info エンドポイントをクエリします。

$ kubectl exec -it productpage-v1-6b746f74dc-9stvs -c istio-proxy -n default -- pilot-agent request GET server_info --log_as_json | jq {version}
{ "version": "2d4ec97f3ac7b3256d060e1bb8aa6c415f5cef63/1.17.0/Clean/RELEASE/BoringSSL" }
この情報は役に立ちましたか?
改善のための提案はありますか?

フィードバックありがとうございます!