LabHub
学习 学习路径 课程

Istio 심화 — 왜 그렇게 흐르는가 · 네 리소스의 역할 · 讲解

무엇이 무엇을 담당하나

在 LabHub 中继续学习

一句话总结

VirtualService 决定“发往哪里”DestinationRule 决定“发送后如何处理”。这就是 Canary 部署同时需要二者的原因。

概念图: VirtualService 决定“发往哪里” · DestinationRule 决定“发送后如何处理” · DestinationRule 中定义 · cluster

为什么需要这些知识

初次使用 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 创建 clusteroutbound|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.local

proxy-status 显示 STALE 时,说明该 proxy 仍在使用旧配置。如果已经 SYNCED,行为却仍然不同,说明配置本身与意图不符,应直接读取 routescluster

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,都没有意义。