通过 Istioctl Describe 理解您的网格
在 Istio 1.3 中,我们新增了 istioctl experimental describe
命令。
一些配置可以影响 pod,要理解这些配置,您可以利用这个命令行工具得到一些必要的信息。
这份指南向您展示如何使用这个实验性质的命令来查看一个 pod 是否在网格中并验证它的配置。
该命令的基本用法如下:
$ istioctl experimental describe <pod-name>[.<namespace>]
向 pod 名字后面加上一个命名空间与使用 istioctl
的 -n
参数来指定一个非默认的命名空间效果一样。
该指南假定您已经在您的网格中部署了 Bookinfo 示例。 如果您还没部署,先参考启动应用服务和确定 ingress 的 IP 和端口。
验证 pod 是否在网格中
如果 pod 里没有 Envoy 代理或者代理没启动,istioctl describe
命令会返回一个警告。
另外,如果 pods 的 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 "http://localhost: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
。
验证 destination rule 配置
您可以使用 istioctl describe
查看哪些 destination rule 规则被用来将请求路由到 pod。例如,应用 Bookinfo 双向 TLS destination rule 规则:
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@
现在再来 describe
一次 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
服务的请求的 destination rule。 - 匹配该 pod 的
ratings
destination rule 的子集,本例中为v1
。 - 该 destination rule 所定义的其它子集。
- 该 pod 同时接受 HTTP 和 双向 TLS 请求,客户端使用 双向 TLS。
验证 virtual service 规则
当 virtual services 配置路由到一个 pod 时,istioctl describe
也会在它的输出中包含这些路由。
例如,应用 Bookinfo virtual services 这个将所有请求都路由到 v1
pods 的规则:
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-all-v1.yaml@
然后,describe 一个实现了 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 类似的信息,同时还有 virtual service 的到该 pod 的路由。
istioctl describe
命令不仅仅展示影响该 pod 的 virtual service。
如果一条 virtual service 配置了 pod 的服务主机但却没有流量到达它,该命令将会输出一个警告。
这种情况可能会发生在 virtual service 实际上已经不再将流量路由到该 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,因为 virtual service 中的路由将所有流量都路由到 v1
子集。
如果您选择删除掉 Bookinfo destination rules:
$ 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!
该输出说明您删除了 destination rule,但是依赖它的 virtual service 还在。
Virtual service 想将流量路由到 v1
子集,但是没有 destination rule 来定义 v1
子集。
因此,要去 v1
的流量就无法流向该 pod。
如果您现在刷新浏览器来向 Bookinfo 发送一个新的请求,您将会看到这条消息:Error fetching product reviews
。
要修复这个问题,请重新应用 destination rule:
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@
重新刷新浏览器,可以看到应用恢复工作了,运行 istioctl experimental describe pod $REVIEWS_V1_POD
也不再报出警告了。
验证流量路由
istioctl describe
命令还可以展示流量的分隔权重。
例如,运行如下命令将 90% 的流量路由到 revis
服务的 v1
子集,将 10% 路由到 v2
子集:
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-90-10.yaml@
现在来 describe reviews v1
pod:
$ istioctl x describe pod $REVIEWS_V1_POD
...
VirtualService: reviews
Weight 90%
该输出显示了 reviews
virtual service 在 v1
子集上有 90% 的权重。
该功能对于别的类型的路由也很有用。例如,您可以部署指定请求头的路由:
$ kubectl apply -f @samples/bookinfo/networking/virtual-service-reviews-jason-v2-v3.yaml@
然后,再次 describe 该 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)
该输出显示了一个警告,因为该 pod 在 v1
子集。
但是,如果请求头包含 end-user=jason
,该 virtual service 配置将会把流量路由到 v2
子集,其余情况下都路由到 v3
子集。
验证严格双向 TLS
按照双向 TLS 迁移的说明,您可以为 ratings
服务启用严格双向 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
运行下列命令来 describe ratings
的 pod:
$ istioctl x describe pod $RATINGS_POD
Pilot reports that pod enforces mTLS and clients speak mTLS
该输出说明到 ratings
pod 的请求已被锁定并且是安全的。
尽管如此,一个部署在切换双向 TLS 到 STRICT
模式时有时还是会中断。
这可能是因为 destination rule 与新配置不匹配。
例如,如果您配置 Bookinfo 的客户端不用双向 TLS 而是用普通 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 和认证策略之间的冲突。
您可以通过应用一个使用双向 TLS 的 destination rule 来修复问题:
$ kubectl apply -f @samples/bookinfo/networking/destination-rule-all-mtls.yaml@
结论和清理
我们对于 istioctl x describe
命令的目标是帮助您理解您的 Istio 网格中的流量和安全配置。
我们也希望能听到您的改善意见! 请在 https://discuss.istio.io 参与讨论。
运行以下命令以删除 Bookinfo 的 pods 和本指南中用到的配置:
$ 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@