當前位置: 妍妍網 > 碼農

Istio 的運維診斷工具詳解

2024-07-15碼農

戳下方名片 ,關註並 星標

回復「 1024 」獲取 2TB 學習資源!

👉 體系化學習:

特色專欄

/ /

/ /

/ /

/ /

/ /

大家好,我是民工哥!

今天來聊一聊關於 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]

istio的listener,route,cluster和endpoint與Envoy中的概念類似。

Cluster :在Envoy中,Cluster是一個服務集群,Cluster中包含一個到多個endpoint,每個endpoint都可以提供服務,Envoy根據負載均衡演算法將請求發送到這些endpoint中。cluster分為inbound和outbound兩種,前者對應Envoy所在節點上的服務;後者占了絕大多數,對應Envoy所在節點的外部服務。可以使用如下方式分別檢視inbound和outbound的cluster:

# istioctl pc cluster productpage-v1-64794f5db4-4h8c8.default --direction inbound -ojson
# istioctl pc cluster productpage-v1-64794f5db4-4h8c8.default --direction outbound -ojson

Listeners :Envoy采用listener來接收並處理downstream發過來的請求。更多監聽埠參見下文

Routes :配置Envoy的路由規則。Istio下發的缺省路由規則中對每個埠(服務)設定了一個路由規則,根據host來對請求進行路由分發,routes的目的為其他服務的cluster

Endpoint :cludter對應的後端服務,可以透過istio pc endpoint檢視inbound和outbound對應的endpoint資訊

偵錯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使用的埠資訊如下:

    可以看到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有一個欄位useOriginalDst設定為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命令檢視本集群中當前可用的後端,也可以直接指定埠檢視--port

    $ 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的作用域,用於未分類的日誌訊息。

    各個元件的日誌作用域參見:https://istio.io/docs/reference/commands/。

    每個作用域對應一個唯一的日誌級別:

  • • 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時很有用,但日常用不到。

    作者:charlieroro 連結:

    cnblogs.com/charlieroro/p/13080267.html

    👍 如果你喜歡這篇文章,請點贊並分享給你的朋友!

    公眾號讀者專屬技術群

    構建高品質的技術交流社群,歡迎從事後端開發、運維技術進群( 備註崗位,已在技術交流群的請勿重復添加微信好友 )。主要以技術交流、內推、行業探討為主,請文明發言。 廣告人士勿入,切勿輕信私聊,防止被騙。

    掃碼加我好友,拉你進群

    PS:因為公眾號平台更改了推播規則,如果不想錯過內容,記得讀完點一下 在看 ,加個 星標 ,這樣每次新文章推播才會第一時間出現在你的訂閱列表裏。 在看 支持我們吧!