除錯 Envoy 和 Istiod
Istio 提供了兩個非常有價值的命令來協助診斷流量管理設定問題,即 proxy-status
和 proxy-config
命令。proxy-status
命令可讓您取得網格的概觀,並識別導致問題的 Proxy。然後可以使用 proxy-config
來檢查 Envoy 設定並診斷問題。
如果您想嘗試以下描述的命令,您可以
- 擁有安裝了 Istio 和 Bookinfo 的 Kubernetes 叢集(如安裝步驟和Bookinfo 安裝步驟中所述)。
或
- 針對在 Kubernetes 叢集中執行的您自己的應用程式使用類似的命令。
取得您的網格概觀
proxy-status
命令可讓您取得網格的概觀。如果您懷疑其中一個 Sidecar 沒有接收到設定或不同步,則 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
如果此清單中遺失 Proxy,則表示它目前未連線到 Istiod 執行個體,因此不會接收任何設定。
SYNCED
代表 Envoy 已確認接收到 Istiod 發送給它的最後一次設定。NOT SENT
代表 Istiod 尚未向 Envoy 發送任何內容。這通常是因為 Istiod 沒有任何東西可以發送。STALE
代表 Istiod 已向 Envoy 發送更新,但尚未收到確認。這通常表示 Envoy 和 Istiod 之間存在網路問題,或者 Istio 本身存在錯誤。
擷取 Envoy 和 Istiod 之間的差異
proxy-status
命令也可以透過提供 Proxy 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)
在這裡您可以看到監聽器 (listeners) 和路由 (routes) 匹配,但叢集 (clusters) 不同步。
深入了解 Envoy 設定
proxy-config
命令可用於查看給定的 Envoy 實例是如何設定的。然後可以使用它來找出您僅透過查看 Istio 設定和自訂資源無法偵測到的任何問題。若要取得給定 Pod 的叢集、監聽器或路由的基本摘要,請使用如下命令(在需要時將 clusters 更改為 listeners 或 routes):
$ 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 叢集/監聽器/路由/端點以及它們如何相互作用。我們將使用帶有 -o json
和篩選標誌的 proxy-config
命令,來追蹤 Envoy 如何確定將來自 productpage
Pod 的請求傳送到 reviews
Pod 的 reviews:9080
。
如果您查詢 Pod 上的監聽器摘要,您會注意到 Istio 會產生以下監聽器
- 一個在
0.0.0.0:15006
上接收所有傳入 Pod 流量的監聽器,以及一個在0.0.0.0:15001
上接收所有傳出 Pod 流量的監聽器,然後將請求轉交給虛擬監聽器。 - 每個服務 IP 的一個虛擬監聽器,每個非 HTTP 適用於傳出 TCP/HTTPS 流量。
- 每個暴露端口的 Pod IP 的一個虛擬監聽器,用於傳入流量。
- 每個 HTTP 端口的
0.0.0.0
上的一個虛擬監聽器,用於傳出 HTTP 流量。
$ 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
- 一個在
從上面的摘要中,您可以看到每個 Sidecar 都有一個綁定到
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 會尋找與請求匹配的第一個路由。在這種情況下,我們沒有任何進階路由,因此只有一個與所有內容匹配的路由。此路由告訴 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
endpoints 命令。$ 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 的連線是個有用的疑難排解步驟。服務網格中的每個 Proxy 容器都應該能夠與 Istiod 通訊。這可以透過幾個簡單的步驟完成
建立一個
curl
Pod$ 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"
}