在部署之前先把错找出来
目标
Istio 配置即使语法正确,大多数时候也可能无法工作。由于其结构由名称相互引用, 只要一侧的名称发生变化,连接就会悄无声息地中断。
本实验将在没有集群的情况下,部署之前找出这类问题。
两种工具的区别
| 检查内容 | 能发现的问题 | |
|---|---|---|
istioctl validate |
单个文件的语法 | 拼写错误、未知字段 |
istioctl analyze |
资源之间的引用 | 不存在的 subset、网关以及主机冲突 |
Kubernetes 无法发现这两类问题。 CRD schema 会悄悄丢弃未知字段,
所以 kubectl apply 会成功,只有流量无法通过。
使用方法
istioctl validate -f vs.yaml
istioctl analyze --use-kube=false vs.yaml dr.yaml
echo $? # 0 이면 깨끗, 79 면 문제 있음
--use-kube=false 表示不查看集群,只检查文件。
步骤
- 拼写错误 →
01-validate.txt - 引用断裂 →
02-analyze.txt - 修复并通过 →
vs.yaml、dr.yaml - 主机冲突 →
04-conflict.txt - 不存在的网关 →
05-gateway.txt - Sidecar 注入 →
06-inject.txt - analyze 无法发现的问题 →
07-blind.txt - 总结 →
08-notes.md
参考
第 7 步中,不出现任何问题才是正确结果。本步骤的目的就是亲自观察静态分析的局限。
发现拼写错误
创建字段名错误的 VirtualService,用 istioctl validate 发现问题,并记录到 01-validate.txt。
尝试把 http: 下的 route: 写成 rout:。istioctl validate -f x.yaml 会报告 unknown field "rout"。Kubernetes 无法发现这个问题:CRD schema 会悄悄丢弃未知字段,因此 apply 会成功,只有流量无法通过。
Schema 正确但行为错误
只创建一个将流量发送到 subset: v1 的 VirtualService(不创建 DestinationRule),让 istioctl analyze 发现问题,并记录到 02-analyze.txt。
运行 istioctl analyze --use-kube=false vs.yaml。它会输出 IST0101 Referenced host+subset in destinationrule not found。validate 可以通过,但 analyze 能发现问题:前者检查语法,后者检查引用关系。这是 Istio 中“配置已经应用却出现 503”的首要原因。
修复并使其通过
添加定义 subset 的 DestinationRule,使 istioctl analyze 以退出码 0结束。文件名使用 vs.yaml 和 dr.yaml。
DestinationRule 的 host 必须与 VirtualService 的 destination.host 相同,subsets[].name 必须与 destination.subset 相同。确认命令:istioctl analyze --use-kube=false vs.yaml dr.yaml; echo $?,结果必须为 0(有问题时为 79)。
两个资源占用同一个主机时
再创建一个指向相同主机的 VirtualService 来引发冲突,并记录到 04-conflict.txt。
会出现 IST0109,内容为“define the same host ... which can lead to undefined behavior”。未定义哪一个会生效。 当团队分成两组、各自创建 VirtualService 时,就会发生这种情况。解决方法是合并为一个。
引用不存在的网关时
创建引用不存在网关的 VirtualService,并记录到 05-gateway.txt。必须出现两种诊断。
设置 gateways: [nope-gw]。会同时出现 IST0101 Referenced gateway not found 和 IST0132(主机不在网关中)。请将两者都保留下来。
Sidecar 实际会变成什么样
向一个 Deployment 注入 Sidecar,并将注入后的容器列表记录到 06-inject.txt。
本 Pod 中没有真正的 istiod,因此要通过文件传入配置。三个参数必须全部提供,只给两个时,istioctl 会尝试从集群中查找剩下的一个。
istioctl kube-inject -f dep.yaml \
--injectConfigFile /opt/istio/inject-config.yaml \
--meshConfigFile /opt/istio/mesh-config.yaml \
--valuesFile /opt/istio/values-config.yaml
系统会附加 istio-proxy 容器和 istio-init 初始化容器。istio-init 会修改 iptables,使所有流量都经过代理。
analyze 无法发现的问题
将 PeerAuthentication 设为 STRICT,将同一服务的 DestinationRule 设为 tls.mode: DISABLE,运行 istioctl analyze,并把没有出现任何问题的结果记录到 07-blind.txt。再写一行说明为何危险。
analyze 会认为配置没有问题,但实际情况是:服务器要求 mTLS,而客户端使用明文连接,导致全部请求失败。 这说明静态分析并非万能。有些问题仅查看文件无法得知,必须结合集群状态分析。因此在实际工作中,会让 istioctl analyze 连接集群运行(--use-kube 默认值)。
总结三个要点
在 08-notes.md 中至少写三行:validate 与 analyze 的区别、相同主机冲突为何危险,以及静态分析无法发现的一种问题。
正文中必须包含 참조、충돌、mTLS。