使用 Istioctl Describe 理解您的網格

在 Istio 1.3 中,我們加入了 istioctl experimental describe 命令。此 CLI 命令為您提供了解影響Pod的組態所需資訊。本指南向您說明如何使用此實驗性子命令來查看 Pod 是否在網格中,並驗證其組態。

該命令的基本用法如下

$ istioctl experimental describe pod <pod-name>[.<namespace>]

在 Pod 名稱後附加命名空間與使用 istioctl-n 選項來指定非預設命名空間具有相同的效果。

本指南假設您已在網格中部署了 Bookinfo 範例。如果您尚未執行此操作,請先啟動應用程式的服務確定 Ingress 的 IP 和埠,然後再繼續。

驗證 Pod 是否在網格中

如果 Envoy 代理不存在於 Pod 中,或代理尚未啟動,則 istioctl describe 命令會傳回警告。此外,如果某些 Pod 的 Istio 要求未滿足,該命令也會發出警告。

例如,以下命令會產生警告,指出 kube-dns Pod 不是服務網格的一部分,因為它沒有 Sidecar。

$ export KUBE_POD=$(kubectl -n kube-system get pod -l k8s-app=kube-dns -o jsonpath='{.items[0].metadata.name}')
$ istioctl x describe pod -n kube-system $KUBE_POD
Pod: coredns-f9fd979d6-2zsxk
   Pod Ports: 53/UDP (coredns), 53 (coredns), 9153 (coredns)
WARNING: coredns-f9fd979d6-2zsxk is not part of mesh; no Istio sidecar
--------------------
2021-01-22T16:10:14.080091Z     error   klog    an error occurred forwarding 42785 -> 15000: error forwarding port 15000 to pod 692362a4fe313005439a873a1019a62f52ecd02c3de9a0957cd0af8f947866e5, uid : failed to execute portforward in network namespace "/var/run/netns/cni-3c000d0a-fb1c-d9df-8af8-1403e6803c22": failed to dial 15000: dial tcp4 127.0.0.1:15000: connect: connection refused[]
Error: failed to execute command on sidecar: failure running port forward process: Get "https://#:42785/config_dump": EOF

對於屬於網格一部分的 Pod(例如 Bookinfo 的 ratings 服務),該命令不會產生此類警告,而是會輸出應用於 Pod 的 Istio 組態。

$ export RATINGS_POD=$(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}')
$ istioctl experimental describe pod $RATINGS_POD
Pod: ratings-v1-7dc98c7588-8jsbw
   Pod Ports: 9080 (ratings), 15090 (istio-proxy)
--------------------
Service: ratings
   Port: http 9080/HTTP targets pod port 9080

輸出會顯示以下資訊:

  • Pod 中服務容器的埠,在此範例中,ratings 容器的埠為 9080
  • Pod 中 istio-proxy 容器的埠,在此範例中為 15090
  • Pod 中服務使用的協定,在此範例中,埠 9080 上使用 HTTP

驗證目標規則組態

您可以使用 istioctl describe 來查看哪些目標規則適用於對 Pod 的請求。例如,套用 Bookinfo 的 相互 TLS 目標規則

壓縮
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

現在再次描述 ratings Pod。

$ istioctl x describe pod $RATINGS_POD
Pod: ratings-v1-f745cf57b-qrxl2
   Pod Ports: 9080 (ratings), 15090 (istio-proxy)
--------------------
Service: ratings
   Port: http 9080/HTTP
DestinationRule: ratings for "ratings"
   Matching subsets: v1
      (Non-matching subsets v2,v2-mysql,v2-mysql-vm)
   Traffic Policy TLS Mode: ISTIO_MUTUAL

現在,該命令會顯示額外輸出。

  • ratings 目標規則適用於對 ratings 服務的請求。
  • 符合 Pod 的 ratings 目標規則的子集,在此範例中為 v1
  • 目標規則定義的其他子集。
  • Pod 接受 HTTP 或相互 TLS 請求,但用戶端使用相互 TLS。

驗證虛擬服務組態

虛擬服務設定到 Pod 的路由時,istioctl describe 也會在輸出中包含這些路由。例如,套用將所有請求路由到 v1 Pod 的 Bookinfo 虛擬服務

壓縮
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@

然後,描述一個實作 reviews 服務 v1 版本的 Pod。

$ 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
...
VirtualService: reviews
   1 HTTP route(s)

輸出包含與先前顯示的 ratings Pod 相似的資訊,但也包含虛擬服務到 Pod 的路由。

istioctl describe 命令不僅會顯示影響 Pod 的虛擬服務。如果虛擬服務設定了 Pod 的服務主機,但沒有流量會到達它,則該命令的輸出會包含警告。如果虛擬服務實際上透過永遠不將流量路由到 Pod 的子集來封鎖流量,則可能會發生這種情況。例如:

$ 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
...
VirtualService: reviews
   WARNING: No destinations match pod subsets (checked 1 HTTP routes)
      Route to non-matching subset v1 for (everything)

警告包含問題的原因、檢查了多少路由,甚至會提供有關其他路由的資訊。在此範例中,沒有流量到達 v2 Pod,因為虛擬服務中的路由將所有流量導向 v1 子集。

如果您現在刪除 Bookinfo 目標規則:

壓縮
$ kubectl delete -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

您可以查看 istioctl describe 的另一個實用功能。

$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
   WARNING: No destinations match pod subsets (checked 1 HTTP routes)
      Warning: Route to subset v1 but NO DESTINATION RULE defining subsets!

輸出顯示您已刪除目標規則,但未刪除依賴它的虛擬服務。虛擬服務將流量路由到 v1 子集,但沒有定義 v1 子集的目標規則。因此,目標為 v1 版本的流量無法流向 Pod。

如果您在此時重新整理瀏覽器以傳送新的請求給 Bookinfo,您會看到以下訊息:Error fetching product reviews。若要修正此問題,請重新套用目標規則。

壓縮
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

重新載入瀏覽器會顯示應用程式再次運作,並且執行 istioctl experimental describe pod $REVIEWS_V1_POD 不再產生警告。

驗證流量路由

istioctl describe 命令也會顯示流量分割權重。例如,執行以下命令將 90% 的流量路由到 v1 子集,並將 10% 的流量路由到 reviews 服務的 v2 子集:

壓縮
$ 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%

輸出顯示 reviews 虛擬服務的 v1 子集權重為 90%。

此功能對於其他類型的路由也很有幫助。例如,您可以部署特定標頭的路由。

壓縮
$ 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 子集中的 Pod。但是,您套用的虛擬服務組態會將流量路由到 v2 子集(如果標頭包含 end-user=jason),並在所有其他情況下路由到 v3 子集。

驗證嚴格 mutual TLS

按照相互 TLS 移轉指示,您可以為 ratings 服務啟用嚴格的相互 TLS。

$ kubectl apply -f - <<EOF
apiVersion: security.istio.io/v1
kind: PeerAuthentication
metadata:
  name: ratings-strict
spec:
  selector:
    matchLabels:
      app: ratings
  mtls:
    mode: STRICT
EOF

執行以下命令來描述 ratings Pod。

$ istioctl x describe pod $RATINGS_POD
Pilot reports that pod enforces mTLS and clients speak mTLS

輸出報告現在已鎖定並保護對 ratings Pod 的請求。

但是,有時在將相互 TLS 切換為 STRICT 時,部署會中斷。可能的原因是目標規則與新組態不符。例如,如果您使用 純 HTTP 目標規則設定 Bookinfo 用戶端不使用相互 TLS:

壓縮
$ 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

輸出包含一個警告,描述目標規則與驗證原則之間的衝突。

您可以透過套用使用相互 TLS 的目標規則來還原正確的行為:

壓縮
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@

結論和清理

我們使用 istioctl x describe 命令的目標是協助您了解 Istio 網格中的流量和安全性組態。

我們很樂意聽取您關於改進的想法!請加入我們的 https://discuss.istio.io

若要移除本指南中使用的 Bookinfo Pod 和組態,請執行以下命令:

壓縮壓縮壓縮壓縮
$ 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@
此資訊對您有幫助嗎?
您有任何改進建議嗎?

感謝您的意見!