Istio的運維-診斷工具
在參考官方文件的時候發現環境偶爾會出現問題,因此插入一章與除錯有關的內容,便於簡單問題的定位。涵蓋官方文件的診斷工具章節
使用istioctl命令列工具
首先可以通過日誌或Introspection檢查各個元件,如果不足以支援問題定位,可以參考如下操作:
istioctl是一個可以用於除錯和診斷istio服務網格的工具。Istio專案為Bash和ZSH執行下的istioctl
提供了自動補全功能。
建議安裝對應istio版本的
istioctl
。
istioctl自動補全
-
將如下內容新增到
~/.bash_profile
檔案中[[ -r "/usr/local/etc/profile.d/bash_completion.sh" ]] && . "/usr/local/etc/profile.d/bash_completion.sh"
-
使用bash時,將在
tools
命令中的istioctl.bash
檔案拷貝到$HOME
目錄下,然後執行如下操作即可$ source ~/istioctl.bash
檢視網格的狀態
可以使用istioctl proxy-status
或istioctl ps
命令檢視網格的狀態。如果輸出結果中缺少某個代理,說明該代理當前沒有連線到Pilot例項,因而無法接收到任何配置。如果狀態為stale
,表示當前存在網路故障,或Pilot需要擴容。
獲取代理配置
可以使用istioctl proxy-config
或istioctl pc
檢索代理配置資訊。
例如,使用如下方式可以檢索特定pod中的Envoy例項的叢集配置資訊。
$ istioctl proxy-config cluster <pod-name> [flags]
使用如下方式可以檢索特定pod中的Envoy例項的bootstrap配置資訊。
$ istioctl proxy-config bootstrap <pod-name> [flags]
使用如下方式可以檢索特定pod中的Envoy例項的listener(監聽器)配置資訊。
$ istioctl proxy-config listener <pod-name> [flags]
使用如下方式可以檢索特定pod中的Envoy例項的route(路由)配置資訊。
$ istioctl proxy-config route <pod-name> [flags]
使用如下方式可以檢索特定pod中的Envoy例項的endpoint (後端)配置資訊。
$ istioctl proxy-config endpoints <pod-name> [flags]
更多參見下一節除錯Envoy和istiod
除錯Envoy和istiod
istio提供了兩個非常有用的命令來診斷流量管理配置問題:proxy-status 和proxy-config。proxy-status
可以獲取網格的概述並確定導致問題的代理。proxy-config
可以檢查Envoy配置並診斷該問題。
如果要嘗試如下命令,可以:
- 安裝Bookinfo
- 使用kubernetes叢集中部署類似應用
獲取網格概況
通過proxy-status
命令可以檢視網格的概況,瞭解是否有sidecar無法接收配置或無法保持同步。
如果某個代理沒有出現在輸出列表中,則說明該代理沒有連線到istiod例項,因此也無法接收任何配置資訊。狀態資訊如下:
SYNCED
:表示Envoy確認了istiod發過來的配置NOT SENT
:表示istiod還沒有傳送配置到Envoy。通常時因為istiod當前沒有需要傳送的配置資訊STALE
:表示istiod傳送了一個更新到Envoy,但沒有接收到確認。通常表示Envoy和istiod之間的網路出現了問題,或istio本身出現了bug。
$ istioctl ps
NAME CDS LDS EDS RDS PILOT VERSION
details-v1-78d78fbddf-psnmk.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
istio-ingressgateway-569669bb67-dsd5h.istio-system SYNCED SYNCED SYNCED NOT SENT istiod-788cf6c878-4pq5g 1.6.0
productpage-v1-85b9bf9cd7-d8hm8.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
prometheus-79878ff5fd-tjdxx.istio-system SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
ratings-v1-6c9dbf6b45-xlf2q.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
reviews-v1-564b97f875-q5l9r.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
reviews-v2-568c7c9d8f-vcd94.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
reviews-v3-67b4988599-psllq.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
sleep-78484c89dd-fmxbc.default SYNCED SYNCED SYNCED SYNCED istiod-788cf6c878-4pq5g 1.6.0
檢索Envoy和istiod的差異
proxy-status
加上proxy ID可以檢索Envoy載入的配置和istiod傳送的配置之間的差異,通過這種方式可以確定哪部分內容沒有被同步,並確定可能存在的問題。
下面的例子可以看到ingressgateway的listeners和routers配置都與istiod發過來的配置匹配,但clusters不匹配。
$ 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
深入探究Envoy配置
proxy-config
命令可以檢視一個Envoy例項的配置,用於定位無法通過檢視istio配置和使用者資源發現的問題。例如,使用如下命令可以獲取特定pod的clusters,listeners或routes概要。注:首先通過istioctl ps檢視出不匹配的代理,然後使用istioctl pc檢視具體的不匹配的資訊。
$ istioctl proxy-config cluster -n istio-system istio-ingressgateway-7d6874b48f-qxhn5
SERVICE FQDN PORT SUBSET DIRECTION TYPE
BlackHoleCluster - - - STATIC
agent - - - STATIC
details.default.svc.cluster.local 9080 - outbound EDS
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.istio-system.svc.cluster.local 9090 - 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的clusters/listeners/routes/endpoints,以及它們之間是如何互動的。下面將使用帶有-o json
和篩選標誌的proxy config
命令來跟蹤Envoy,因為它決定在哪裡將請求從productpage
pod傳送到reviews
pod的 reviews:9080
-
如果請求了一個pod的listener概要,可以看到istio生成了如下listeners:
- 一個
0.0.0.0:15006
的listener,用於接收到pod的入站流量;以及一個0.0.0.0:15001
的listener,用於接收所有到pod的出站流量,然後將請求交給一個 virtual listener。 - 每個kubernetes service IP都對應一個virtual listener,非HTTP的listener用於出站的TCP/HTTPS流量
- pod IP中的virtual listener暴露了接收入站流量的埠
- 0.0.0.0的HTTP型別的virtual listener,用於出站的HTTP流量
Istio使用的埠資訊如下:
Port Protocol Used by Description 15000 TCP Envoy Envoy admin port (commands/diagnostics) 15001 TCP Envoy √ Envoy Outbound 15006 TCP Envoy √ Envoy Inbound 15020 HTTP Envoy Istio agent Prometheus telemetry 15021 HTTP Envoy Health checks 15090 HTTP Envoy Envoy Prometheus telemetry 15010 GRPC Istiod XDS and CA services (plaintext) 15012 GRPC Istiod XDS and CA services (TLS) 8080 HTTP Istiod Debug interface 443 HTTPS Istiod Webhooks 15014 HTTP Mixer, Istiod Control plane monitoring 15443 TLS Ingress and Egress Gateways SNI 9090 HTTP Prometheus Prometheus 42422 TCP Mixer Telemetry - Prometheus 15004 HTTP Mixer, Pilot Policy/Telemetry - mTLS
9091 HTTP Mixer Policy/Telemetry 可以看到
TYPE
欄位是沒有HTTPS
的,HTTPS
作為TCP
型別。下面是productpage
的listeners,刪減了部分資訊。10.84
開頭的是各個kubernetes service的CLUSTER-IP
,以172.20
開頭的是kubernetes的node IP,以nodePort方式暴露服務。$ istioctl proxy-config listeners productpage-v1-85b9bf9cd7-d8hm8.default ADDRESS PORT TYPE 0.0.0.0 443 TCP <--+ 10.84.71.37 443 TCP | 10.84.223.189 443 TCP | 10.84.100.226 15443 TCP | 10.84.121.154 443 TCP | 10.84.142.44 443 TCP | #從0.0.0.0_15001相關IP:PORT上接收出站的non-HTTP流量 10.84.155.219 443 TCP | 172.20.127.212 9100 TCP | 10.84.205.103 443 TCP | 10.84.167.116 443 TCP | 172.20.127.211 9100 TCP <--+ 10.84.113.197 9979 HTTP+TCP<--+ 0.0.0.0 9091 HTTP+TCP | 10.84.30.227 9092 HTTP+TCP | 10.84.108.37 8080 HTTP+TCP | 10.84.158.64 8443 HTTP+TCP | 10.84.202.185 8080 HTTP+TCP | 10.84.21.252 8443 HTTP+TCP | 10.84.215.56 8443 HTTP+TCP | 0.0.0.0 60000 HTTP+TCP | # 從0.0.0.0_15001的相關埠上接收出站的HTTP+TCP流量 10.84.126.74 8778 HTTP+TCP | 10.84.126.74 8080 HTTP+TCP | 10.84.123.207 8080 HTTP+TCP | 10.84.30.227 9091 HTTP+TCP | 10.84.229.5 8080 HTTP+TCP<--+ 0.0.0.0 9080 HTTP+TCP # 從 0.0.0.0_15006 上接收所有到9080的入站流量 0.0.0.0 15001 TCP # 從IP tables接收pod的所有出站流量,並移交給虛擬偵聽器 0.0.0.0 15006 HTTP+TCP # Envoy 入站 0.0.0.0 15090 HTTP # Envoy Prometheus 遙測 0.0.0.0 15021 HTTP # 健康檢查
下面是
productpage
Pod中實際監聽的埠資訊,與上述對應。$ ss -ntpl State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 128 0.0.0.0:15090 0.0.0.0:* LISTEN 0 128 127.0.0.1:15000 0.0.0.0:* LISTEN 0 128 0.0.0.0:9080 0.0.0.0:* LISTEN 0 128 0.0.0.0:15001 0.0.0.0:* LISTEN 0 128 0.0.0.0:15006 0.0.0.0:* LISTEN 0 128 0.0.0.0:15021 0.0.0.0:* LISTEN 0 128 *:15020 *:*
- 一個
-
從上述輸出概要中可以看到每個sidecar都有一個繫結到
0.0.0.0:15006
的listener,IP tables會將所有入站的Pod流量匯入該listener;以及一個繫結到0.0.0.0:15001
的listener,IP tables會將所有出站流量匯入該listener,該listener有一個欄位useOrigi
nalDst設定為true,表示會使用最佳匹配原始目的地的方式將請求分發到virtual listener,如果沒有找到任何virtual listener,將會直接傳送到連線目的地的PassthroughCluster
。$ istioctl pc listener productpage-v1-85b9bf9cd7-d8hm8.default --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", "accessLog": [ { "name": "envoy.file_access_log", "typedConfig": { "@type": "type.googleapis.com/envoy.config.accesslog.v2.FileAccessLog", "path": "/dev/stdout", "format": "[%START_TIME%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %RESPONSE_FLAGS% \"%DYNAMIC_METADATA(istio.mixer:status)%\" \"%UPSTREAM_TRANSPORT_FAILURE_REASON%\" %BYTES_RECEIVED% %BYTES_SENT% %DURATION% %RESP(X-ENVOY-UPSTREAM-SERVICE-TIME)% \"%REQ(X-FORWARDED-FOR)%\" \"%REQ(USER-AGENT)%\" \"%REQ(X-REQUEST-ID)%\" \"%REQ(:AUTHORITY)%\" \"%UPSTREAM_HOST%\" %UPSTREAM_CLUSTER% %UPSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_LOCAL_ADDRESS% %DOWNSTREAM_REMOTE_ADDRESS% %REQUESTED_SERVER_NAME% %ROUTE_NAME%\n" } } ] } } ], "name": "virtualOutbound-catchall-tcp" } ], "useOriginalDst": true, "trafficDirection": "OUTBOUND" } ]
-
應用的請求為一個出站HTTP請求,會到達
9080
埠,這意味著請求將傳遞給0.0.0.0:9080
virtual listener。該listener會檢視其RDS中配置的路由。這種情況下會查詢istiod配置的RDS的9080
路由$ istioctl pc listener productpage-v1-85b9bf9cd7-d8hm8.default -o json --address 0.0.0.0 --port 9080 [ { "name": "0.0.0.0_9080", "address": { "socketAddress": { "address": "0.0.0.0", "portValue": 9080 } }, "filterChains": [ { "filterChainMatch": { "applicationProtocols": [ "http/1.0", "http/1.1", "h2c" ] }, "filters": [ { "name": "envoy.http_connection_manager", "typedConfig": { "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager", "statPrefix": "outbound_0.0.0.0_9080", "rds": { "configSource": { "ads": {} }, "routeConfigName": "9080" }, ... ]
-
9080的路由配置中每個服務只有一個virtual host。由於應用的請求會傳遞到reviews服務,因此Envoy會選擇請求與域相匹配的virtual host。一旦匹配到域,Envoy會檢視匹配請求的第一個路由。下面場景中,由於沒有配置任何高階路由,因此只有一條可以匹配的路由,該路由告訴Envoy將請求傳送到
outbound|9080||reviews.default.svc.cluster.local
叢集。$ istioctl proxy-config routes productpage-v1-85b9bf9cd7-d8hm8.default --name 9080 -o json [ { "name": "9080", "virtualHosts": [ ... { "name": "reviews.default.svc.cluster.local:9080", "domains": [ "reviews.default.svc.cluster.local", "reviews.default.svc.cluster.local:9080", "reviews", "reviews:9080", "reviews.default.svc.cluster", "reviews.default.svc.cluster:9080", "reviews.default.svc", "reviews.default.svc:9080", "reviews.default", "reviews.default:9080", "10.84.110.152", "10.84.110.152:9080" ], "routes": [ { "name": "default", "match": { "prefix": "/" }, "route": { "cluster": "outbound|9080||reviews.default.svc.cluster.local", "timeout": "0s", "retryPolicy": { "retryOn": "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes", "numRetries": 2, "retryHostPredicate": [ { "name": "envoy.retry_host_predicates.previous_hosts" } ], "hostSelectionRetryMaxAttempts": "5", "retriableStatusCodes": [ 503 ] }, "maxGrpcTimeout": "0s" }, "decorator": { "operation": "reviews.default.svc.cluster.local:9080/*" } } ], "includeRequestAttemptCount": true } ], "validateClusters": false } ]
-
cluster的配置用於從istiod中檢索後端。Envoy會使用
serviceName
作為key在Endpoints列表中進行查詢,並將請求傳遞到這些後端。$ istioctl pc cluster productpage-v1-85b9bf9cd7-d8hm8.default --fqdn reviews.default.svc.cluster.local -o json [ { ... "name": "outbound|9080||reviews.default.svc.cluster.local", "type": "EDS", "edsClusterConfig": { "edsConfig": { "ads": {} }, "serviceName": "outbound|9080||reviews.default.svc.cluster.local" }, "connectTimeout": "10s", "circuitBreakers": { "thresholds": [ { "maxConnections": 4294967295, "maxPendingRequests": 4294967295, "maxRequests": 4294967295, "maxRetries": 4294967295 } ] }, "filters": [ { "name": "istio.metadata_exchange", "typedConfig": { "@type": "type.googleapis.com/udpa.type.v1.TypedStruct", "typeUrl": "type.googleapis.com/envoy.tcp.metadataexchange.config.MetadataExchange", "value": { "protocol": "istio-peer-exchange" } } } ] } ]
-
使用
proxy-config endpoint
命令檢視本叢集中當前可用的後端$ istioctl pc endpoint productpage-v1-85b9bf9cd7-d8hm8.default --cluster "outbound|9080||reviews.default.svc.cluster.local" ENDPOINT STATUS OUTLIER CHECK CLUSTER 10.80.3.55:9080 HEALTHY OK outbound|9080||reviews.default.svc.cluster.local 10.80.3.56:9080 HEALTHY OK outbound|9080||reviews.default.svc.cluster.local 10.80.3.58:9080 HEALTHY OK outbound|9080||reviews.default.svc.cluster.local
流量方向為:listener(應用出站port)->route(routeConfigName
)->cluster(domain)->endpoint(serviceName)
檢查bootstrap配置
到目前為止已經檢視了istiod的大部分配置,然而,Envoy需要一些如哪裡可以發現istiod的bootstrap配置,使用如下方式檢視:
$ istioctl proxy-config bootstrap -n istio-system istio-ingressgateway-569669bb67-dsd5h.istio-system
{
"bootstrap": {
"node": {
"id": "router~10.83.0.14~istio-ingressgateway-569669bb67-dsd5h.istio-system~istio-system.svc.cluster.local",
"cluster": "istio-ingressgateway",
"metadata": {
"CLUSTER_ID": "Kubernetes",
"CONFIG_NAMESPACE": "istio-system",
"EXCHANGE_KEYS": "NAME,NAMESPACE,INSTANCE_IPS,LABELS,OWNER,PLATFORM_METADATA,WORKLOAD_NAME,MESH_ID,SERVICE_ACCOUNT,CLUSTER_ID",
"INSTANCE_IPS": "10.83.0.14,fe80::6871:95ff:fe5b:9e3e",
"ISTIO_PROXY_SHA": "istio-proxy:12cfbda324320f99e0e39d7c393109fcd824591f",
"ISTIO_VERSION": "1.6.0",
"LABELS": {
"app": "istio-ingressgateway",
"chart": "gateways",
"heritage": "Tiller",
"istio": "ingressgateway",
"pod-template-hash": "569669bb67",
"release": "istio",
"service.istio.io/canonical-name": "istio-ingressgateway",
"service.istio.io/canonical-revision": "latest"
},
"MESH_ID": "cluster.local",
"NAME": "istio-ingressgateway-569669bb67-dsd5h",
"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",
"TRUSTJWT": "true",
"WORKLOAD_NAME": "istio-ingressgateway"
},
...
}
校驗到istiod的連通性
服務網格中的所有Envoy代理容器都應該連線到istiod,使用如下步驟測試:
-
建立一個
sleep
pod$ kubectl create namespace foo $ kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) -n foo
-
使用curl測試到istiod的連通性。下面呼叫v1註冊API,使用預設的istiod配置引數,並啟用雙向TLS認證
$ kubectl exec $(kubectl get pod -l app=sleep -n foo -o jsonpath={.items..metadata.name}) -c sleep -n foo -- curl -sS istiod.istio-system:15014/debug/endpointz
通過istioctl的輸出理解網格
如下內容是一個實驗特性,僅用於評估
istio 1.3中包含一個istioctl experimental describe命令。該CLI命令提供瞭解影響pod的配置所需的資訊。本節展示如何使用該experimental 子命令檢視一個pod是否在網格中,以及檢查該pod的配置。該命令的基本使用方式為:
$ istioctl experimental describe pod <pod-name>[.<namespace>] #或
$ istioctl experimental describe pod <pod-name> -n <namespace>
校驗pod是否在網格中
如果一個pod不在網格中,istioctl describe
會顯示一個告警資訊,此外,如果pod缺少istio需要的配置時也會給出告警資訊。
$ istioctl experimental describe pod mutatepodimages-7575797d95-qn7p5
Pod: mutatepodimages-7575797d95-qn7p5
Pod does not expose ports
WARNING: mutatepodimages-7575797d95-qn7p5 is not part of mesh; no Istio sidecar
--------------------
Error: failed to execute command on sidecar: error 'execing into mutatepodimages-7575797d95-qn7p5/default istio-proxy container: container istio-proxy is not valid for pod mutatepodimages-7575797d95-qn7p5
如果一個pod在網格中,則不會產生告警。
$ istioctl x describe pod ratings-v1-6c9dbf6b45-xlf2q
Pod: ratings-v1-6c9dbf6b45-xlf2q
Pod Ports: 9080 (details), 15090 (istio-proxy)
--------------------
Service: details
Port: http 9080/HTTP targets pod port 9080
Pilot reports that pod enforces HTTP/mTLS and clients speak HTTP
輸出為:
- pod的服務容器埠,上述為
ratings
的9080埠 - pod中的istio-proxy埠,15090
- pod服務使用的協議,9080埠的http協議
- pod設定的mutual TLS
校驗destination rule配置
可以使用istioctl describe
檢查應用到一個pod的destination rule。例如執行如下命令部署destination rule
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml
檢視ratings
pod
$ export RATINGS_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')
$ istioctl x describe pod $RATINGS_POD
Pod: ratings-v1-6c9dbf6b45-xlf2q
Pod Ports: 9080 (ratings), 15090 (istio-proxy)
--------------------
Service: ratings
Port: http 9080/HTTP targets pod port 9080
DestinationRule: ratings for "ratings"
Matching subsets: v1
(Non-matching subsets v2,v2-mysql,v2-mysql-vm)
Traffic Policy TLS Mode: ISTIO_MUTUAL
Pilot reports that pod enforces HTTP/mTLS and clients speak mTLS
輸出為:
- 應用到
ratings
服務的ratings
destination rule - 匹配pod的
ratings
destination rule,上述為v1
- destination rule定義的其他subset
- pod接收HTTP或mutual TLS,但客戶端使用mutual TLS
校驗virtual service配置
部署如下virtual service
$ kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml
檢視v1
版本的reviews
服務:
$ export REVIEWS_V1_POD=$(kubectl get pod -l app=reviews,version=v1 -o jsonpath='{.items[0].metadata.name}')
istioctl x describe pod $REVIEWS_V1_POD
$ istioctl x describe pod $REVIEWS_V1_POD
Pod: reviews-v1-564b97f875-q5l9r
Pod Ports: 9080 (reviews), 15090 (istio-proxy)
--------------------
Service: reviews
Port: http 9080/HTTP targets pod port 9080
DestinationRule: reviews for "reviews"
Matching subsets: v1
(Non-matching subsets v2,v3)
Traffic Policy TLS Mode: ISTIO_MUTUAL
VirtualService: reviews
1 HTTP route(s)
輸出結果與前面的ratings
pod型別,但多了到pod的virtual service路由。
istioctl describe
命令不僅僅顯示了影響pod的virtual service。如果一個virtual service配置的host為一個pod,但流量不可達,會輸出告警資訊,這種請求可能發生在當一個virtual service如果沒有可達的pod subset時。例如:
$ export REVIEWS_V2_POD=$(kubectl get pod -l app=reviews,version=v2 -o jsonpath='{.items[0].metadata.name}')
istioctl x describe pod $REVIEWS_V2_POD
[root@bastion istio-1.6.0]# istioctl x describe pod $REVIEWS_V2_POD
Pod: reviews-v2-568c7c9d8f-vcd94
...
VirtualService: reviews
WARNING: No destinations match pod subsets (checked 1 HTTP routes)
Route to non-matching subset v1 for (everything)
告警資訊給出導致問題的原因,檢查的路由數目,以及其他路由資訊。例如,由於virtual service將所有的流量到匯入了v1
subset,因此v2
pod無法接收到任何流量。
如果刪除如下destination rule:
$ kubectl delete -f samples/bookinfo/networking/destination-rule-all-mtls.yaml
可以看到如下資訊:
$ istioctl x describe pod $REVIEWS_V1_POD
Pod: reviews-v1-564b97f875-q5l9r
Pod Ports: 9080 (reviews), 15090 (istio-proxy)
--------------------
Service: reviews
Port: http 9080/HTTP targets pod port 9080
VirtualService: reviews
WARNING: No destinations match pod subsets (checked 1 HTTP routes)
Warning: Route to subset v1 but NO DESTINATION RULE defining subsets!
輸出展示了已刪除destination rule,但沒有刪除依賴它的virtual service。該virtual service將流量路由到v1
subset,但沒有定義v1
subset的destination rule。因此流量無法分發到v1
版本的pod。
恢復環境:
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml
校驗流量路由
istioctl describe
也可以展示流量權重。如理如下命令會將90%的流量匯入reviews
服務的v1
subset,將10%的流量匯入reviews
服務的v2
subset。
$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-90-10.yaml
檢視reviews v1` pod:
$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
Weight 90%
輸出顯示90%的reviews
服務的流量匯入到了v1
subset中。
部署其他型別的路由,如部署指定HTTP首部的路由:
$ kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml
再次檢視pod:
$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
WARNING: No destinations match pod subsets (checked 2 HTTP routes)
Route to non-matching subset v2 for (when headers are end-user=jason)
Route to non-matching subset v3 for (everything)
由於檢視了位於v1
subset的pod,而virtual service將包含 end-user=jason
的流量分發給v2
subset,其他流量分發給v3
subset,v1
subset沒有任何流量匯入,此時會輸出告警資訊。
檢查strict mutual TLS(官方文件待更新)
根據mutual TLS遷移指南,可以給ratings服務啟用strict mutual TLS。
$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
name: ratings-strict
spec:
selector:
matchLabels:
app: ratings
mtls:
mode: STRICT
EOF
執行如下命令檢視ratings
pod,輸出顯示ratings
pod已經使用mutual TLS防護。
$ istioctl x describe pod $RATINGS_POD
Pilot reports that pod enforces mTLS and clients speak mTLS
有時,將mutual TLS切換位STRICT
模式時會對部署的元件造成影響,通常是因為destination rule不匹配新配置造成的。例如,如果配置Bookinfo客戶端不使用mutualTLS,而使用明文的HTTP destination rules:
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all.yaml
如果在瀏覽器傻瓜開啟Bookinfo,會顯示Ratings service is currently unavailable
,使用如下命令檢視原因:
$ istioctl x describe pod $RATINGS_POD
...
WARNING Pilot predicts TLS Conflict on ratings-v1-f745cf57b-qrxl2 port 9080 (pod enforces mTLS, clients speak HTTP)
Check DestinationRule ratings/default and AuthenticationPolicy ratings-strict/default
輸出中有一個描述destination rule和authentication policy衝突的告警資訊。
使用如下方式恢復:
$ kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml
解除安裝
$ kubectl delete -f samples/bookinfo/platform/kube/bookinfo.yaml
$ kubectl delete -f samples/bookinfo/networking/bookinfo-gateway.yaml
$ kubectl delete -f samples/bookinfo/networking/destination-rule-all-mtls.yaml
$ kubectl delete -f samples/bookinfo/networking/virtual-service-all-v1.yaml
使用istioctl analyse診斷配置
istioctl analyze
是一個可以探測istio配置中潛在錯誤的診斷工具,它可以診斷現有的叢集或一組本地配置檔案,會同時診斷這兩者。
可以使用如下方式診斷當前的kubernetes:
$ istioctl analyze --all-namespaces
例如,如果某些名稱空間沒有啟用istiod注入,會列印如下告警資訊:
Warn [IST0102] (Namespace openshift) The namespace is not enabled for Istio injection. Run 'kubectl label namespace openshift istio-injection=enabled' to enable it, or 'kubectl label namespace openshift istio-injection=disabled' to explicitly mark it as not needing injection
分析現有的叢集/本地檔案或二者
上述的例子用於分析一個存在的叢集,但該工具也可以支援分析本地kubernetes yaml的配置檔案集,或同時分析本地檔案和叢集。當分析一個本地檔案集時,這些檔案集應該是完全自包含的。通常用於分析需要部署到叢集的一個完整的配置檔案集。
分析特定的本地kubernetes yaml檔案集:
$ istioctl analyze --use-kube=false a.yaml b.yaml
分析當前目錄中的所有yaml檔案:
$ istioctl analyze --use-kube=false *.yaml
模擬將當前目錄中的files部署到當前叢集中:
$ istioctl analyze *.yaml
使用istioctl analyze --help
命令檢視完整的選項。更多analyse的使用參見Q&A.
元件內省
Istio元件是用一個靈活的內省框架構建的,它使檢查和操作執行元件的內部狀態變得簡單。元件會開放一個埠,用於通過web瀏覽器的互動式檢視獲取元件的狀態,或使用外部工具通過REST訪問。
Mixer
, Pilot
和Galley
都實現了ControlZ 功能(1.6版本可以檢視istiod)。當啟用這些元件時將記錄一條訊息,指示要連線的IP地址和埠,以便與ControlZ互動。
2018-07-26T23:28:48.889370Z info ControlZ available at 100.76.122.230:9876
可以使用如下命令進行埠轉發,類似kubectl的port-forward
,用於遠端訪問。
$ istioctl dashboard controlz <podname> -n <namespaces>
元件日誌
日誌作用域
元件的日誌按照作用域進行分類。取決於元件提供的功能,不同的元件有不同的作用域。所有的元件都有一個default
的作用域,用於未分類的日誌訊息。
各個元件的日誌作用域參見:reference documentation。
每個作用域對應一個唯一的日誌級別:
- none
- error
- warning
- info
- debug
其中none表示沒有劃分作用域的輸出,debug
會最大化輸出。預設的作用域為info
,用於在一般情況下為istio提供何時的日誌輸出。
可以使用 --log_output_level
控制輸出級別:
控制輸出
日誌資訊通常會傳送到元件的標準輸出流中。 --log_target
選項可以將輸出重定向到任意(數量的)位置,可以通過逗號分割的列表給出檔案系統的路徑。stdout
和stderr
分別表示標準輸出和標準錯誤輸出流。
日誌滾動
istio元件能夠自動管理日誌滾動,將大的日誌切分為小的日誌檔案。--log_rotate
選項允許指定用於滾動的基本檔名。派生的名稱將用於單個日誌檔案。
--log_rotate_max_age
選項指定檔案發生滾動前的最大時間(天為單位),--log_rotate_max_size
選項用於指定檔案滾動發生前的最大檔案大小(MB為單位), --log_rotate_max_backups
選項控制儲存的滾動檔案的最大數量,超過該值的老檔案會被自動刪除。
元件除錯
--log_caller
和--log_stacktrace_level
選項可以控制日誌資訊是否包含程式設計師級別的資訊。在跟蹤元件bug時很有用,但日常用不到。