使用 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@