对 istio 用户而言,最常见的场景之一是将 istio 用作 ingress 网关,通过其暴露微服务给外部客户端访问。具体而言有两种典型的方式。一种是只运行业务服务的容器,不携带 sidecar。另一种是运行携带 sidecar 的 Pod,业务服务和 ingress 网关之间建立 mTLS 双向认证进行通信。
最近,笔者帮一位 istio 用户排查问题:为什么通过 istio ingress 网关暴露的服务不能被 istio 网格外部的 CURL 客户端访问到。下文记录了笔者排查问题时的关键步骤,希望能帮助到遇到类似问题的用户。
1. 使用 istioctl analyzer 命令
使用
istioctl analyzer 命令排查和故障服务相关的每个 istio 资源,这是我最喜欢用的 istioctl 命令。
Analyzer允许用户检查特定命名空间(namespace)或是整个 Kubernetes 集群里的每一个YAML文件。最佳实践是,在用户部署 istio 资源之前,用 analyzer 命令检查 istio 待部署资源(如 gateway,virtual service)相关的 YAML 文件。这可以帮助用户提前发现问题。
shell
$ istioctl analyze helloworld-gw-nlb.yaml -n istio-system
✔ No validation issues found when analyzing namespace: istio-system.
如果 istio 资源已经生效,用户还可以将analyzer命令作用于整个集群,以检查现有集群是否存在和用户冲突的路由(route)。执行
istioctl analyze --all-namespaces
可以检查整个集群。
2. 验证 secret 是否被正确加载
出于安全考虑,用户会以加密的方式访问服务,可能是单边TLS或双向TLS认证。用户要确保 secret 在 ingress 网关中被正确加载,以便 ingress 网关能对入站流量进行加密。
istioctl proxy-config secret
命令可以帮助用户检查 ingress 网关中加载了哪些 secret,还可以通过它验证secret 的加载的时间及其有效时长。例如,下面的命令列出了ingress 网关加载的名为
mycluster-wdc06-b-406454-85f044fc29ce613c264409c04a76c95d-0001
secret 的具体信息,它是在安装 istio 过程中默认生成在 istio-system 命名空间下的。
shell
$ istioctl proxy-config secret istio-ingressgateway-768c6bf77b-2k7hm.istio-system
RESOURCE NAME TYPE STATUS VALID CERT SERIAL NUMBER NOT AFTER NOT BEFORE
mycluster-wdc06-b-406454-85f044fc29ce613c264409c04a76c95d-0001 Cert Chain ACTIVE true 415111668488852830681974512193801089848052 2020-12-05T09:43:42Z 2020-09-06T09:43:42Z
3. 检查 istio 网络资源
接下来就轮到检查边缘服务(edge serivce)相关的 gateway、virtual service 资源,以确保它们被正确地引用。
对于 gateway 资源,需要验证以下几点:
-
a. gateway 的命名空间正确,和网关所部署的命名空间一致。 -
b. gateway 中 credentialName
要和上述步骤2中网关加载的 secret 名称一致。在 istio1.7 版本中,secret 要和 gateway 归属于同一个命名空间。 -
c. host
字段填写正确。如果 virtual service 部署在了另一个命名空间,笔者建议在 host 字段加上该命名空间作为前缀。例如,hello/.。 -
d. 如果用户使用了自定义网关,确保选择器(selector)匹配。相关 gateway 资源的选择器必须和网关 deployment 的选择器匹配。
helloworld-gw-nlb.yaml:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
namespace: istio-system # step a
spec:
selector:
istio: ingressgateway # step d
servers:
- port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: mycluster-wdc06-b-406454-85f044fc29ce613c264409c04a76c95d-0001 # step b
hosts:
- "hello/hello.mycluster-wdc06-b-406454-85f044fc29ce613c264409c04a76c95d-0001.us-east.containers.appdomain.cloud". #step c
对于 virtual service 则需要注意以下几点:
-
a. 确保 gateway
字段引用正确。如果 virtual service 引用了另一个命名空间的 gateway 对象,要在
gateway前加上该命名空间作为前缀。 -
b. host
字段要和 gateway 资源里指定的值一致。 -
c. 确保 route 配置了正确的目标地址。当涉及到多个命名空间的流量转发时,host字段要补全。
helloworld-vs.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
namespace: hello # step a
spec:
hosts:
- "hello.mycluster-wdc06-b-406454-85f044fc29ce613c264409c04a76c95d-0001.us-east.containers.appdomain.cloud" # step b
gateways:
- istio-system/helloworld-gateway # step a
http:
- match:
- uri:
exact: /hello
route:
- destination:
host: helloworld.hello.svc.cluster.local # step c
port:
number: 5000
4. 检查 ingress 网关的日志
检查ingress网关的日志,验证请求被网关正确接收,检查是否有错误日志。可以通过这篇文档
Requests are rejected by Envoy 查阅如何分析 ingress 网关日志及常见错误码释义。
有时候,为了方便查错,需要打开 ingress 网关的debug日志,可以通过如下命令实现:
istioctl proxy-config log {ingress-pod}.istio-system --level
或者通过以下命令检查Envoy配置是否正确:
istioctl dashboard envoy {ingress-pod}.istio-system
可以通过
Debugging Envoy and Istiod了解如何debug Envoy配置。
总结
通过以上技巧,笔者希望能帮助到大家快速定位排查 istio 相关的网络问题。
如果你还有问题,欢迎随时访问链接
Istio GitHub issue和
collect all required information,提出你的issue。希望你有一个愉快的istio使用体验,无论你是否在 IBM 云上的 istio。
原作者:Lin Sun
原文地址:
4 steps to debug your edge microservices in an Istio service mesh