EnvoyとIstiodのデバッグ
Istioは、トラフィック管理の設定問題を診断するのに非常に役立つ2つのコマンド、proxy-status と proxy-config コマンドを提供します。proxy-status コマンドを使用すると、メッシュの概要を把握し、問題の原因となっているプロキシを特定できます。次に、proxy-config を使用してEnvoyの設定を調べ、問題を診断できます。
以下で説明するコマンドを試したい場合は、次のいずれかを選択できます。
- インストール手順とBookinfoのインストール手順に記載されているように、IstioとBookinfoがインストールされたKubernetesクラスタを用意する。
または
- 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 の動きを追跡します。
- 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
- Pod へのすべてのインバウンドトラフィックを受信する 
- 上記の概要から、すべてのサイドカーが - 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 } ]
- リクエストはポート - 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" } ...
- 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", } } ] ...
- このクラスタは、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 } ] }, } ]
- このクラスタで現在利用可能なエンドポイントを確認するには、 - 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と通信できる必要があります。これは、いくつかの簡単なステップで実現できます。
- curlPodを作成します。- $ kubectl create namespace foo $ kubectl apply -f <(istioctl kube-inject -f samples/curl/curl.yaml) -n foo
- 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"
}