本文档详细记录了在GKE(Google Kubernetes Engine)中使用Gateway API时,解决长连接请求超时(stream timeout 或 504 Gateway Timeout)问题的完整排查和解决方案。
1. 问题描述
当客户端通过GKE Gateway访问后端服务的一个长时间运行的API(例如,需要超过30秒才能完成的AI代码审查任务)时,客户端在大约30秒后收到一个 stream timeout 或 504 Gateway Timeout 错误,即使后端应用本身仍在正常处理请求。
核心症状:
- 超过30秒的请求稳定失败。
- 后端Pod的日志显示请求已收到并正在处理,没有出现崩溃或错误。
curl命令提前终止,并显示超时错误。
2. 排查过程
步骤一:检查应用日志
我们首先检查了后端服务(py-github-agent)的Pod日志。
bash
kubectl logs -l app=py-github-agent
日志显示应用收到了请求,并开始执行耗时的任务。在超时期间,应用并未报错或重启。这排除了应用本身是问题根源的可能性。
步骤二:增加后端服务(Backend Service)超时时间
我们怀疑是GKE为Kubernetes Service创建的后端服务(Backend Service)资源有默认的短超时。我们首先尝试通过为Service添加注解来延长超时时间。
尝试的解决方案 :
在 helm/templates/service.yaml 中添加注解:
yaml
apiVersion: v1
kind: Service
metadata:
name: clusterip-{{ .Values.service.appName }}
annotations:
{{- if .Values.backendTimeout }}
networking.gke.io/backend-timeout: {{ .Values.backendTimeout | quote }}
{{- end }}
...
并通过 gcloud 命令直接更新了对应的后端服务:
bash
gcloud compute backend-services update [BACKEND_SERVICE_NAME] --timeout=300 --global
结果 :
我们验证了GCP控制台中的后端服务超时时间确实已经更新为300秒。然而,再次测试curl命令,问题依旧存在。这证明超时发生在负载均衡器到后端服务 之前 的某个环节。
步骤三:分析GKE Gateway和HTTPRoute
既然后端超时不是问题,我们将注意力转向了更高层级的GKE Gateway (gateway.yaml) 和 HTTPRoute (httproute.yaml)。
gateway.yaml: 本身不包含任何超时配置。httproute.yaml: 定义了从Gateway到Service的路由规则。
我们意识到,Google Cloud Load Balancer (由GKE Gateway创建) 有一个独立的 前端超时 或 请求超时,它的默认值恰好是30秒。这解释了为什么即使后端服务愿意等待更长时间,连接依然会被负载均衡器切断。
3. 根本原因
GKE Gateway API创建的全局外部负载均衡器(GCLB)默认的 HTTP请求超时为30秒 。我们之前调整的 backend-timeout 仅仅是负载均衡器与后端Pod之间的连接超时,而不是客户端与负载均衡器之间的连接超时。
4. 最终解决方案
解决此问题的正确方法是使用Gateway API的标准功能,在 HTTPRoute 资源中为需要长连接的特定路由规则定义一个超时策略。
我们修改了 k8s/httproute.yaml 文件,为指向 py-github-agent 服务的规则添加了 timeouts 字段:
yaml
# k8s/httproute.yaml
- backendRefs:
- group: ""
kind: Service
name: clusterip-py-github-agent
port: 8000
weight: 1
matches:
- path:
type: PathPrefix
value: /py-github-agent
# --- 添加的解决方案 ---
timeouts:
request: 600s
# ---------------------
实施步骤
-
修改配置 : 将上述
timeouts块添加到k8s/httproute.yaml文件中对应的路由规则下。 -
应用配置 : 使用
kubectl应用更改。bashkubectl apply -f k8s/httproute.yamlGKE Gateway控制器会自动监测到
HTTPRoute的变化,并重新配置底层的Google Cloud Load Balancer,将这条特定路径的请求超时时间调整为600秒。
验证
应用更改后,我们多次运行了长时间的 curl 命令进行测试,均成功返回了完整的响应,再未出现超时错误。
bash
curl -m 700 -X POST -H "Content-Type: application/json" -d '{"pull_request_url": "..."}' https://gateway.jpgcp.cloud/py-github-agent/review
5. 总结
在GKE Gateway中处理长连接超时问题的关键在于,不能只关注后端的 Service 或 Backend Service,还必须配置 HTTPRoute 中的 timeouts.request 策略来调整负载均衡器前端的请求超时。这是更精确、更符合Gateway API规范的解决方案。