Istio 심화 — 왜 그렇게 흐르는가 · 네 리소스의 역할 · 讲解
무엇이 무엇을 담당하나
一句话总结
VirtualService 决定“发往哪里”,DestinationRule 决定“发送后如何处理”。这就是 Canary 部署同时需要二者的原因。
为什么需要这些知识
初次使用 Istio 时,大多数人都会犯这个错误。
# VirtualService 만 쓴 카나리 — 동작하지 않는다http: - route: - destination: { host: shop, subset: v1 } weight: 90 - destination: { host: shop, subset: v2 } weight: 10没有任何地方知道 subset: v1 指向什么。subset 要在 DestinationRule 中定义。
# DestinationRule — 서브셋의 정의spec: host: shop subsets: - name: v1 labels: { version: v1 } - name: v2 labels: { version: v2 }这样,v1 才表示带有 version: v1 label 的 Pod。换成前一课程介绍的 Envoy 术语:DestinationRule 的 subset 创建 cluster(outbound|8080|v1|shop...),VirtualService 的 weight 则成为 route 的权重。
四种资源
| 资源 | 作用 | 对应 Envoy 对象 |
|---|---|---|
| Gateway | 接收从 Mesh 外部进入的流量,定义 port、host、TLS | Listener |
| VirtualService | 决定哪些请求发往哪里,包括匹配、权重、重试、timeout | Route |
| DestinationRule | 决定如何处理目标,包括 subset、LB、连接池、异常值、TLS | Cluster |
| ServiceEntry | 把 Mesh 不认识的外部服务登记到清单中 | Cluster + Endpoint |
Gateway 只负责开放入口。仅有 Gateway 并不会产生流量路由——必须存在通过 gateways: 引用该 Gateway 的 VirtualService,路由才会建立。这也是常见陷阱。
mTLS 何时生效
PeerAuthentication 决定 mode。
| mode | 含义 |
|---|---|
| PERMISSIVE | 同时接受明文和 mTLS(默认值,用于迁移) |
| STRICT | 仅接受 mTLS |
| DISABLE | 不使用 mTLS |
默认使用 PERMISSIVE,是因为环境中可能仍有未注入 sidecar 的 Pod。因此,“安装 Istio 后流量就会加密”是错误说法。 切换到 STRICT 之前,明文流量仍可直接通过。
切换到 STRICT 时经常被破坏的对象包括:没有 sidecar 的 Pod,例如 Job;发送健康检查的 kubelet;以及 Mesh 外部的监控系统。kubelet 的 probe 会由 Istio 绕过原路径处理,但自行编写的检查脚本会失效。
确认配置是否真正到达 proxy
Istio 中最常见的情况是:YAML 已经 apply,行为却没有变化。 Control Plane 接受的配置与 sidecar 实际持有的配置可能不同,因此要在 proxy 侧确认。
istioctl proxy-status # 각 프록시가 최신 설정과 동기인지istioctl analyze -n prod # 설정끼리의 모순을 정적으로 찾는다istioctl proxy-config routes deploy/frontend -n prodistioctl proxy-config cluster deploy/frontend -n prod --fqdn api.prod.svc.cluster.localproxy-status 显示 STALE 时,说明该 proxy 仍在使用旧配置。如果已经 SYNCED,行为却仍然不同,说明配置本身与意图不符,应直接读取 routes 和 cluster。
VirtualService 必须有明确的附着位置。 常见问题是 hosts 中的名称与实际服务不同,或者未填写 gateways,导致配置只在 Mesh 内部生效。要应用于通过 Gateway 进入的流量,必须明确写出该 Gateway 的名称;如果 Gateway 位于其他 namespace,就要使用 네임스페이스/이름。
DestinationRule 的 subset 是 label,不是 deployment。 subset: v2 只指向具有相应名称 label 的 Pod。创建新 deployment 时如果遗漏 label,subset 就会成为空目标,请求将返回 503。通过 proxy-config endpoint 查看实际地址数量,是最快的确认方法。
istioctl proxy-config endpoint deploy/frontend -n prod | grep api存在应用顺序。 同一 host 下有多个 VirtualService 时,规则不会合并,而是最先创建的对象获胜。各团队分别创建一个资源后,其他团队的规则可能被悄然忽略。应坚持一个 host 对应一个资源;如果需要按 path 拆分,也要在同一个资源内部完成。
收紧 mTLS 之前,先确认哪些流量仍是明文。 把 PeerAuthentication 改为 STRICT 的瞬间,没有 sidecar 的 workload 和部分 Kubernetes 状态检查就会中断。应先保持 PERMISSIVE,在 telemetry 中确认明文比例降至 0,然后再收紧。
常见误解
“加入 Istio 就会获得可观测性。” sidecar 提供的是 L7 请求指标,例如请求数、延迟和状态码。应用程序内部发生了什么,仍然无从得知。Trace 也是如此:sidecar 会创建 span,但如果应用程序不继续传递 header,链路就会中断。 并非完全无需修改代码。
生产环境中真正重要的事
配置是否按预期生效,应直接询问 proxy。
istioctl analyze # 정적 검사 — 서브셋 미정의 같은 것을 잡는다istioctl proxy-status # 각 사이드카가 최신 설정을 받았나(SYNCED)istioctl proxy-config route <pod> # 실제로 받은 라우트istioctl proxy-config cluster <pod> --fqdn shop.default.svc.cluster.local如果 proxy-status 显示 STALE,说明配置尚未送达。此时无论如何反复查看 YAML,都没有意义。