原文:https://dev.to/googlecloud/native-cors-support-on-gke-gateway-offloading-cross-origin-policy-management-to-infrastructure-3c0m(作者 @olivi-eh)
浏览器默认会强制执行同源策略,防止恶意脚本读取不同源的数据。但现代应用架构几乎离不开跨域通信:单页应用、移动客户端和嵌入式 Web 组件,经常需要跨不同域名、子域名和端口获取数据、流式接收 AI 模型推理结果。
为了安全地支持这些交互,应用必须实现跨域资源共享(Cross-Origin Resource Sharing,CORS)。多年来,在 Ingress-Nginx 上运行 Kubernetes 工作负载的团队,通常会使用 nginx.ingress.kubernetes.io/enable-cors 等 annotation 处理 CORS。当迁移到 Kubernetes Gateway API 和 GKE Gateway 后,缺少原生 CORS 支持一直是常见的运维痛点,也使其成为呼声最高的缺失能力之一。
GKE 团队在 GKE Gateway 和 Inference Gateway 原生 CORS 支持 的 Preview 版本中补齐了这块短板。本文将拆解新的 CORS filter 如何工作、为什么要把跨域策略管理移到负载均衡层,以及实际使用中需要考虑的运维细节。
为什么要在入口层管理 CORS?
如果在各个后端应用内部实现 CORS,会在三个主要方面带来架构阻力:
- 冗余应用逻辑:每个后端服务或框架(Node.js、FastAPI、Spring,或 vLLM 等推理引擎)都必须引入中间件,用于评估请求头并生成预检响应。
- 预检请求消耗资源:复杂 Web 请求会触发
OPTIONS预检调用。把这些预检请求路由到后端容器,会把应用内存、CPU 周期和网络带宽浪费在纯协议协商上。 - 配置扩散与漂移:当几十个微服务各自管理 CORS 策略时,允许头、暴露头或源校验上的细微差异,都会造成安全漏洞和客户端集成失败。
把 CORS 处理转移到 GKE Gateway 后,Google Cloud Load Balancing 可以在网络边缘直接终结 OPTIONS 预检请求,并注入所需的响应头(Access-Control-Allow-Origin、Access-Control-Allow-Methods 和 Access-Control-Allow-Headers)。后端应用只会收到已通过校验的业务请求,既省去样板代码,也降低计算开销。
在 HTTPRoute 中配置 CORS filter
GKE Gateway 通过开源 Gateway API 规范直接提供 CORS 支持。你可以在 HTTPRoute 清单的 rules 部分,通过 CORS filter 以声明式方式定义策略。
下面是在 API 路由上配置 CORS 策略的示例:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api-cors-route
namespace: production
spec:
parentRefs:
- name: external-gateway
rules:
- matches:
- path:
type: PathPrefix
value: /api
backendRefs:
- name: api-service
port: 8080
filters:
- type: CORS
cors:
allowOrigins:
- "https://app.example.com"
- "https://*.partner-domain.com"
allowMethods:
- GET
- POST
- PUT
- DELETE
allowHeaders:
- Authorization
- Content-Type
- X-Requested-With
exposeHeaders:
- X-Request-ID
allowCredentials: true
maxAge: 3600
cors 配置块可以精细控制协商参数:
- `allowOrigins`:指定允许的来源,可以是明确 URL(
https://app.example.com)、通配符模式(https://*.partner-domain.com),或全通配符(*)。 - `allowMethods`:列出允许的 HTTP 方法。也可以指定
*允许所有方法。 - `allowHeaders`:定义客户端请求中可以携带的 HTTP 请求头。
- `exposeHeaders`:列出浏览器可以暴露给客户端脚本的响应头,范围超出简单响应头。
- `allowCredentials`:将
Access-Control-Allow-Credentials设置为true或false,决定浏览器是否允许携带 Cookie 或认证头的请求获取响应。 - `maxAge`:定义浏览器缓存预检响应的秒数(默认 5 秒),可显著减少后续
OPTIONS流量。
凭据与通配符的安全注意事项
在 GKE Gateway 上设计 CORS 策略时,需要特别注意 allowOrigins 与 allowCredentials 的交互。
按照标准浏览器安全规则,如果 Access-Control-Allow-Origin 被设置为字面通配符(*),浏览器会阻止携带凭据请求的响应。然而,当你在 GKE Gateway 的 allowOrigins 中配置通配符模式或通配符时,控制器会动态匹配并回显传入请求的 Origin,而不是返回字面上的星号。
由于浏览器看到的是与 allowCredentials: true 一起返回的明确 Origin,因此会允许该响应。如果你将 allowOrigins: ["*"] 与 allowCredentials: true 一起配置,任意网站都可能读取已认证用户的响应。对于需要认证的 API,应始终定义明确的域名列表,而不是使用全放行通配符。
支持的 GatewayClass 与架构约束
本次预览版支持单集群 GKE Gateway 部署,涵盖三种主要 GatewayClass:
- `gke-l7-rilb`:区域内部 Application Load Balancer。
- `gke-l7-regional-external-managed`:区域外部 Application Load Balancer。
- `gke-l7-global-external-managed`:全局外部 Application Load Balancer。
它还支持通过 Inference Gateway 暴露的 AI 推理工作负载,允许前端聊天界面或客户端 SDK 跨源直接查询提供服务的模型。
在生产环境落地前,需要注意以下技术限制:
- 仅支持单集群:多集群 Gateway(
gke-l7-gmc-*)目前不支持 CORS 过滤器。 - 过滤器冲突:不能在同一条路由规则中同时组合
CORS过滤器和RequestRedirect过滤器。 - URL map 正则表达式限制:GKE Gateway 控制器会将通配符 Origin 模式转换为底层 Cloud Load Balancing URL map 上的正则表达式。对于
gke-l7-global-external-managed,每个 Gateway 监听器限制一个正则表达式,并且不支持将通配符 Origin 与PathPrefix匹配组合使用。对于区域外部和区域内部 GatewayClass,每个主机名最多可以使用五个正则表达式。需要注意的是,精确 Origin 和全放行*条目不会计入这些正则表达式配额。
后续步骤
GKE Gateway 原生 CORS 支持消除了组织将工作负载从传统 Ingress 控制器迁移到 Kubernetes Gateway API 时最大的功能缺口之一。通过在路由层以声明式方式管理跨源策略,平台团队可以简化应用代码,并集中管理所有服务的安全策略。
如需了解更多内容并在集群中开始测试 CORS,可以查阅官方 GKE Gateway CORS 文档 和上游 Gateway API CORS 用户指南。
原文:https://dev.to/googlecloud/native-cors-support-on-gke-gateway-offloading-cross-origin-policy-management-to-infrastructure-3c0m(作者 @olivi-eh)



