2. Istio 架构解析:控制面与数据面、Envoy、Pilot、Mixer、Citadel
刚开始接触 Istio 的时候,我其实挺困惑的——边车、控制面、数据面,这些词听着都很唬人。直到我亲手在测试环境里部署了一套 Istio,盯着 Pod 里的两个容器看了一会,才恍然大悟。说白了,Istio 就是把网络通信和安全控制从应用代码里抽出来,放到一个基础设施层里。这一章咱们就把它拆开,看看内部到底是怎么转的。
2.1 控制面与数据面——Istio 的心脏和血管
Istio 的架构分两层:数据面 和 控制面。数据面是所有的 Envoy 代理,它们跟业务容器一起跑在 Pod 里,负责拦截和转发进出 Pod 的所有流量。控制面则是整个大脑,下发规则、签发证书、收集指标。这两层通过 xDS 协议通信,数据面只管执行,控制面只管决策。
我记得有一次排查一个延迟问题,发现控制面下发的路由规则没及时生效,数据面和控制面之间的连接断开了几秒。从那以后我就特别重视控制面的高可用配置。
这张图里,你可以看到控制面的三个核心组件:Pilot、Mixer、Citadel,以及数据面里每一个 Pod 里的 Envoy 边车。箭头表示控制面下发配置到每个 Envoy。所有进出 Pod 的流量都必须经过 Envoy,它根据 Pilot 下发的规则转发。
2.2 Envoy 代理——数据面的基石
Envoy 是 Istio 数据面的“执行者”。它是一个高性能的 L4/L7 代理,最初由 Lyft 开发,后来成了 CNCF 的项目。在 Istio 里,Envoy 以 sidecar 模式部署在应用 Pod 中,拦截所有进出的网络流量。
Envoy 能做什么?它支持 HTTP/1.1、HTTP/2、gRPC、TCP 等多种协议。它可以根据 Pilot 下发的路由规则做负载均衡、故障注入、熔断、重试等。它还通过 Mixer 做策略检查和遥测报告。
--concurrency 2 写进启动参数。
Envoy 作为 sidecar 意味着它对业务代码完全无侵入。你的应用不需要知道 Envoy 的存在,只需要监听 localhost。Envoy 会监听 15001(入站)和 15006(出站)端口做透明代理。
2.3 Pilot——服务发现与流量管理的指挥官
Pilot 是控制面的核心,它负责两件事:
- 服务发现: 从 Kubernetes(或其他平台)获取服务列表、端点信息,转换成 Envoy 能理解的 xDS(发现服务)协议数据。
- 流量规则下发: 把 VirtualService、DestinationRule 等 CRD 翻译成 Envoy 的路由配置,通过 xDS 推送给数据面。
Envoy 与 Pilot 之间维持长连接。一旦有规则变化,Pilot 会立即推送增量更新。这种机制保证了路由变更的秒级生效。
我个人习惯在测试环境里先改一个 VirtualService 做流量切分,然后观察 Envoy 的日志,确认配置确实到达了。有一次我改了路由比例,但忘了检查端点是否匹配,结果导致部分流量被丢到了空 Pod——嗯,后来我就养成了打完配置立刻 curl 一下的习惯。
2.4 Mixer——策略与遥测的历史与现在
提到 Mixer,我得先说明一点:在 Istio 1.5 版本之后,Mixer 的功能已经被重构到了 Envoy 的扩展机制中,不再作为独立组件部署。但在早期的 Istio 架构里,Mixer 是控制面的重要一员,所以理解它的概念对掌握 Istio 的设计思路有帮助。
Mixer 原来负责两个接口:
| 接口 | 功能 | 性能瓶颈 |
|---|---|---|
| Check | 每个请求到达前,Envoy 向 Mixer 询问“这个请求是否允许通过”?比如白名单、配额检查。 | 高并发时延迟增加 |
| Report | 请求结束后,Envoy 向 Mixer 上报指标和日志。 | 大量上报导致控制面负载 |
2.5 Citadel——安全基石
Citadel 是 Istio 的证书颁发机构(CA)。它为每个工作负载签发 SPIFFE 格式的身份证书,并且管理这些证书的轮换。有了 Citadel,Envoy 之间可以轻松实现双向 TLS(mTLS)通信,即两端的 Envoy 都验证对方的身份,保证通信的机密性和完整性。
Citadel 的工作原理很简单:它监听 Kubernetes 的 ServiceAccount 创建,自动为每个 ServiceAccount 生成密钥和证书,并通过 Secret 下发到对应的 Pod。Envoy 启动时会从 Secret 中读取证书,然后用它来加密和解密流量。
你说这麻烦吗?其实不。因为一切都是自动的。你只需要在安装 Istio 时开启全局 mTLS 就行。有一次我排查一个服务间连不上的问题,发现是因为某个命名空间没打上 istio-injection=enabled 标签,导致那边没有 Envoy 边车,也就没有证书。折腾了半小时才找到原因——所以我建议你先检查命名空间和 Pod 的注解。
2.6 避坑指南:新手最容易卡住的两个地方
- 端口冲突: Envoy 默认使用 15000 作为管理端口,15001/15006 作为透明代理端口。如果你在宿主机上也监听这些端口,会起不来。我建议你在部署前先用
netstat -tlnp检查一下。 - Sidecar 注入不生效: 很多人忘了给 namespace 打
istio-injection=enabled标签,或者没有重启 Pod 使注入生效。执行kubectl get pod -n your-ns -o yaml看看有没有initContainers: istio-init和containers: istio-proxy。
以上就是 Istio 主要组件的拆解。记住:数据面是 Envoy,控制面负责下发规则(Pilot)、安全性(Citadel)以及曾经的策略/遥测(Mixer)。你理解了这个分层,后续学流量管理、安全策略就会顺畅很多。