API 网关专栏 · 第 64 章

API 网关与 Istio:划清南北向和东西向流量边界

2026年09月14日
API 网关与 Istio:划清南北向和东西向流量边界

API 网关和 Istio 可以互补,但前提是每项策略都有唯一且清晰的负责人。一种常见设计是让 API 网关负责公开 API 契约,包括消费者认证、配额、版本路由和请求转换;Istio 则保护并观测网格内的工作负载间流量。这只是起点,并非硬性规则:如果公网入口所需能力都在 Istio 入口网关的支持范围内,就未必需要额外部署 API 网关。

真正危险的是无意中堆叠出两层网关:它们验证不同 Token、追加不同客户端地址、对同一请求重复重试,并输出互不兼容的路由名称。本文将说明如何选择拓扑、定义身份交接,并在生产切流前验证完整链路。

本文中的 Istio 行为按 Istio 1.31.1 审阅。实际部署必须固定补丁版本和 Gateway API CRD 版本,因为浮动文档页面不能充当生产版本契约。

核心要点

  • 先分配职责,再选择产品:公开 API 策略、网格身份、应用授权和网络暴露都要有明确负责人。
  • 公网只保留一条允许路径。如果 Istio 入口端点或工作负载服务仍能被直接访问,边缘策略就可能被绕过。
  • Istio RequestAuthentication 会验证已经携带的凭据;如果凭据必须存在,还要配套授权策略。
  • 网格双向 TLS 验证的是工作负载,不是最终用户,也不能替代授权。
  • 把重试、超时和流量切分交给最了解上下文的那一层,再测试组合后的总截止时间与重放行为。

划分职责平面

决策常见负责人必须保留的边界
公网主机名、API 产品、消费者凭据与配额API 网关路由级身份不等于应用对象权限
互联网暴露与第一个可信代理跳点边缘负载均衡器或 API 网关仅信任来自已配置对等端的转发头
工作负载身份与服务间加密Istio有效工作负载证书只证明身份,不代表拥有权限
东西向服务授权Istio 与服务负责人网格策略无法推断全部领域状态规则
对象与工作流授权应用在受保护数据和业务状态附近完成检查
灰度路由与重试指定的一层流量组件重复重试与切分会产生乘法效应

这套分工是有条件的。如果 Istio 入口负责公开 API 策略,它就在该边界承担网关角色;如果独立 API 网关承担这一角色,Istio 就不应悄悄重建一份冲突的公开契约。

从三种拓扑中选择

1. API 网关位于 Istio 入口之前

1flowchart LR
2    C[外部客户端] --> G[API 网关]
3    G -->|已认证的源站连接| I[Istio 入口网关]
4    I --> M[网格工作负载]
5    M --> S[下游网格服务]

当边缘需要 API 消费者管理、复杂转换、面向开发者的凭据,或有意放在网格之外的治理能力时,可以使用该拓扑。应限制 Istio 入口端点,使流量只能从 API 网关路径进入。网关到入口的连接需要独立完成服务端认证,并在需要时进行客户端认证;仅转发身份请求头并不能证明发送它的是哪个代理。

额外一跳会产生成本。需要测量连接复用、TLS 握手、请求体缓冲、流式传输和故障行为。不要仅仅因为两个产品都已安装,就让两层长期共存。

2. 只使用 Istio 入口作为公网网关

Istio 可以通过入口网关暴露服务,也可以使用自身网络 API 或 Kubernetes Gateway API。如果所选 Istio 版本及运维模型已经覆盖公开路由与安全需求,这通常是最精简的设计。

移除独立 API 网关前,要盘点硬性要求:消费者生命周期、密钥签发、共享配额、请求或响应转换、Schema 治理、分析、变现以及非 Kubernetes 后端。入口监听器并不天然等于完整的 API 管理生命周期。

3. 公网网关加专用多集群东西向网关

东西向网关和公网 API 网关承担不同任务。Istio 文档中的多网络模式,会在不同集群网络中的工作负载无法直连时使用专用网关。这些网关在网络之间传输经过认证的网格流量,并依赖可信 mTLS 工作负载身份;它们不会自动成为公开 API 入口。

Istio 1.31 多主集群、多网络指南还提醒:示例中的东西向网关可能默认暴露到公网,生产环境需要增加访问限制。南北向和东西向网关应分别管理公网 DNS、防火墙策略、监听端口和证书信任。

定义身份交接

把每一种身份画成不同的值:

  1. 连接到公网边缘的网络对等端;
  2. 依据可信代理规则解析出的客户端地址;
  3. 从凭据中验证出的 API 消费者或最终用户身份;
  4. 网关访问网格时使用的工作负载身份;
  5. 应用进行对象授权时使用的主体。

不要把它们压缩成一个 X-User 或 X-Forwarded-For 请求头。在第一个可信边界删除调用方提交的敏感身份头,再由负责的网关为下一跳创建范围受限的上下文。接收方只能在来自获准网关工作负载的已认证连接上接受这些上下文。

如果应用需要原始 Bearer Token,应明确选择原样转发、交换 Token,还是只转发已验证声明。转发所有声明会扩大耦合和信息暴露。网关生成的请求 ID 可用于关联,但不是用户身份。

让认证与授权配套

Istio 1.31 RequestAuthentication API明确区分了两种情况:规则覆盖的无效凭据会被拒绝,但完全没有凭据的请求会以“无已认证身份”状态被接受。如果必须要求有效主体,还要配套授权策略。

下面的 Istio 1.31.1 配置摘录用于说明二者关系;实际部署必须按身份契约替换 selector、issuer、audience 和 JWKS URI:

1apiVersion: security.istio.io/v1
2kind: RequestAuthentication
3metadata:
4  name: public-api-jwt
5  namespace: istio-system
6spec:
7  selector:
8    matchLabels:
9      istio: ingressgateway
10  jwtRules:
11    - issuer: "https://identity.example.com/"
12      audiences: ["api://orders"]
13      jwksUri: "https://identity.example.com/.well-known/jwks.json"
14---
15apiVersion: security.istio.io/v1
16kind: AuthorizationPolicy
17metadata:
18  name: require-public-api-principal
19  namespace: istio-system
20spec:
21  selector:
22    matchLabels:
23      istio: ingressgateway
24  rules:
25    - from:
26        - source:
27            requestPrincipals: ["*"]

这只是配置摘录,并非完整部署。需要确认入口工作负载标签、策略挂载模型、issuer 行为、JWKS 可用性、健康检查或 Token 签发例外路径,以及准确 Istio 版本。audiences 必须与 IdP 和 API 契约匹配;列表为空时,Istio 文档中的回退行为是接受与服务名称匹配的 audience。独立边缘网关可能已经验证过 Token;如果 Istio 再次验证,要说明原因、密钥轮换如何同步,以及应用最终信任哪一个结果。

把网格 mTLS 当作工作负载认证

Istio 1.31 安全最佳实践指出,为了支持渐进采用,代理默认使用宽容的双向 TLS 模式,在可行时同时接受双向 TLS 和明文流量。切换到严格模式后会拒绝明文网格连接。这两条路径的信任属性不同,在宣布迁移完成前必须分别测试。

即使使用严格双向 TLS,也只能证明工作负载身份,不能说明最终用户有权读取某张发票或修改某个账号。工作负载级访问由网格授权策略控制,对象级检查仍应留在应用中。Kubernetes NetworkPolicy 与云防火墙应作为纵深防御,因为流量捕获和网关暴露是不同边界。

每项流量策略只指定一个负责人

重试最容易产生意外乘法效应。如果 API 网关尝试两次,而 Istio 又对每次上游调用尝试两次,一个客户端操作就可能产生四次应用调用;写操作可能在部分完成后被重放。

每条路由都应记录:

  • 端到端客户端截止时间;
  • 各跳的连接、请求和单次尝试超时;
  • 哪些方法或操作可以重试;
  • 全链路最大总尝试次数;
  • 可重放写操作的幂等键与去重负责人;
  • 哪一层负责灰度权重、故障注入或异常实例处理。

公开 API 版本路由应由外部契约负责人控制。服务实例选择和工作负载局部弹性通常留在网格,除非某项例外具有更强上下文。随后应注入慢上游、响应头之后的连接重置和控制面故障,观察实际行为。

协调 Kubernetes 配置归属

Kubernetes Gateway API 通过 GatewayClass、Gateway 和 HTTPRoute 等资源改善角色分离,但不能阻止两个团队表达冲突意图。每个 GatewayClass 应只交给一个控制器,限制公网监听器的创建权限,并明确使用命名空间挂载规则。

主机名、证书、路由和策略挂载要有唯一事实来源。GitOps 仓库应能看出公网路由由 API 网关控制器还是 Istio 协调。发布流程必须检查状态条件:清单被 API 接受但没有控制器真正下发,并不算部署成功。

观测并验证完整链路

可以在各层传递同一个关联值,但要保留每层自己的权威字段。日志应区分边缘拒绝、Istio 认证失败、网格授权拒绝、上游重置、应用拒绝和客户端取消。

切流前验证:

  • 请求不能绕过公网网关直达 Istio 入口或服务;
  • 伪造的转发头和身份头会在信任边界被替换;
  • 缺失、无效、过期和有效凭据分别走预期路径;
  • 迁移期间已经理解宽容与严格网格 mTLS 的不同行为;
  • 总超时与重试预算没有超过客户端截止时间;
  • 流式、WebSocket、gRPC 和大请求体不会被意外缓冲;
  • 路由删除、证书轮换和策略回滚均可观测;
  • 南北向和东西向网关只暴露各自需要的监听器。

迁移顺序

  1. 盘点现有主机名、路由、身份、重试、超时和观测字段。
  2. 为每项策略指定唯一负责人,并从目标设计中删除重复默认行为。
  3. 在不接公网流量的情况下部署新路径,测试源站认证和防绕过能力。
  4. 镜像或回放脱敏流量,验证路由与遥测,避免创建写操作。
  5. 为小规模用户切流,并保留可立即执行的 DNS 或负载均衡回滚。
  6. 对比拒绝原因、延迟、错误和上游尝试次数。
  7. 只有在回滚与紧急访问都有文档后,才移除旧公网路径。

总结

API 网关与 Istio 的组合首先是职责分配问题,不是强制堆叠两个代理。当确实需要其能力时,让 API 网关负责公开 API 契约,让 Istio 负责网格身份和服务流量,把领域授权留给应用。认证每一次交接,阻断备用路径,并把组合后的重试、截止时间、身份和故障当作一个系统来测试。

常见问题

每个 Istio 部署都需要独立 API 网关吗?

不需要。如果 Istio 入口支持的路由与安全模型已经满足公开接口需求,它就可能足够。只有存在明确能力和运维职责时,才增加独立 API 网关。

Istio 东西向网关是 API 网关吗?

它负责网络之间的网格流量,并不会自动负责公开 API 产品、消费者凭据、配额或生命周期治理。

Istio mTLS 会认证最终用户吗?

不会。它认证参与通信的工作负载。最终用户认证和应用授权仍是独立决策。

后续步骤

继续比较 API 网关与服务网格的职责,设计网关 mTLS 身份与轮换,并明确细粒度授权的归属。

获取方案