使用 Istioctl Describe 了解您的网格

在 Istio 1.3 中,我们包含了 istioctl experimental describe 命令。此 CLI 命令为您提供了解影响 Pod 的配置所需的信息。本指南将向您展示如何使用此实验性子命令查看 Pod 是否在网格中并验证其配置。

该命令的基本用法如下

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

将命名空间附加到 Pod 名称的效果与使用 `istioctl` 的 `-n` 选项指定非默认命名空间相同。

本指南假设您已在网格中部署了 Bookinfo 示例。如果您还没有,请 启动应用程序的服务 并在继续之前 确定入口的 IP 和端口

验证 Pod 是否在网格中

如果 Envoy 代理不存在于 Pod 中或代理尚未启动,则 `istioctl describe` 命令将返回警告。此外,如果 Pod 的 Istio 要求 未满足,该命令也会发出警告。

例如,以下命令会发出警告,表明 `kube-dns` Pod 不属于服务网格,因为它没有边车。

$ 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://127.0.0.1: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 中服务使用的协议,在本例中,`HTTP` 协议通过 `9080` 端口使用。

验证目标规则配置

您可以使用 `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` 也会在输出中包含路由。例如,应用 Bookinfo 虚拟服务,将所有请求路由到 `v1` Pod

压缩
$ 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 发送新的请求,您将看到以下消息:`无法获取产品评论`。要解决此问题,请重新应用目标规则

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

重新加载浏览器显示应用程序再次运行,并且运行 `istioctl experimental describe pod $REVIEWS_V1_POD` 不再产生警告。

验证流量路由

`istioctl describe` 命令也显示拆分流量权重。例如,运行以下命令,将 90% 的流量路由到 `reviews` 服务的 `v1` 子集,并将 10% 的流量路由到 `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` 子集(在所有其他情况下)。

验证严格双向 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,您将看到 `评级服务当前不可用`。要了解原因,请运行以下命令

$ 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@
这些信息对您有用吗?
您对改进有任何建议吗?

感谢您的反馈!