1. 网络流量与超时点概览
为了更好地理解问题,我们首先需要了解外部请求是如何通过GKE Gateway到达我们的服务Pod的,以及在这个链条中存在哪些超时点。
Actual Traffic Flow Google Cloud (Auto-Provisioned Resources) Kubernetes Cluster (Our Configuration) Controls Controls Controls Controls Client/User Service Pod External HTTPS LB (Forwarding Rule, Proxy) URL Map (Timeout #1 - Ignored) Backend Service (Timeout #2 - Ignored) Network Endpoint Group Gateway Resource HTTPRoute Resource Service (Type: ClusterIP) BackendConfig
核心问题 : 我们在Kubernetes中配置HTTPRoute和BackendConfig的尝试,都未能成功修改URL Map和Backend Service这两个关键资源中的超时值,导致它们一直停留在默认的30秒。
2. 问题背景
部署在GKE上的服务(例如py-github-agent代码审查或chat-api-svc聊天机器人)在处理耗时较长的任务时,外部API请求总是在大约30秒后被中断。
核心症状:
- 对于批处理API (如代码审查) : 请求直接失败,客户端收到
504 Gateway Timeout或stream timeout错误。 - 对于流式API (如LLM聊天) : 连接在30秒时被强行切断。这会导致前端收到的流式数据被突然截断,用户看到一半的回答后就停止了。
- 共同点: 服务Pod内的日志显示应用本身仍在正常处理,并未出错,只是客户端连接丢失了。
目标: 将负载均衡器的超时时间延长至600秒,以支持长耗时任务和完整的流式响应。
3. 第一轮排查:区分内部与外部问题
假设: 问题可能出在应用本身或集群内部网络。
步骤:
-
获取服务ClusterIP :
bashkubectl get svc clusterip-py-github-agent -o jsonpath='{.spec.clusterIP}' # 输出: 192.172.23.160 -
在集群内部发起测试 : 我们在集群内部署一个临时的
curl测试Pod,直接向该ClusterIP发起一个长超时的请求。bashkubectl run curl-test-pod --image=curlimages/curl --rm -i --restart=Never -- curl -m 600 ... http://192.172.23.160:8000/review -
结果 : 测试成功! 请求在超过1分钟后成功返回了完整的JSON响应。
结论 : 应用本身和Kubernetes集群内部的服务网络均没有问题 。问题几乎100%出在从外部流量入口到集群内部的GKE Gateway 或其管理的Google Cloud负载均衡器上。
4. 第二轮排查:尝试Kubernetes原生配置
我们尝试了两种Kubernetes声明式的方法来配置超时。
方案A: 使用HTTPRoute (标准Gateway API)
HTTPRoute是Gateway API的标准资源,它允许为特定路由规则定义超时。
步骤:
-
修改
k8s/httproute.yaml,为/py-github-agent规则添加timeouts字段。yaml... rules: - backendRefs: - name: clusterip-py-github-agent port: 8000 matches: - path: type: PathPrefix value: /py-github-agent timeouts: request: 600s # <-- 添加此配置 -
应用配置:
kubectl apply -f k8s/httproute.yaml -
结果 : 失败! 外部请求依旧在30秒后超时。
方案B: 使用BackendConfig (GKE原生)
BackendConfig是GKE提供的一种自定义资源,用于配置由GKE控制器创建的后端服务。
步骤:
-
创建
k8s/backend-config.yaml文件:yamlapiVersion: cloud.google.com/v1 kind: BackendConfig metadata: name: py-github-agent-backend-config spec: timeoutSec: 600 -
为
py-github-agent的Service添加注解,将其与BackendConfig关联。yaml# helm/templates/service.yaml ... metadata: annotations: cloud.google.com/backend-config: '{"default": "py-github-agent-backend-config"}' ... -
应用配置。
-
结果 : 失败! 外部请求依旧在30秒后超时。
5. 第三轮排查:深入GCP底层资源
既然所有Kubernetes层面的声明式配置都失败了,我们必须深入到由GKE自动创建的Google Cloud原生资源层去一探究竟。
步骤1: 检查Backend Service
Backend Service是负载均衡器的核心组件,直接定义了后端的行为,包括超时。
动作:
-
找到由GKE为我们的服务自动创建的
Backend Service的真实名称 。bashgcloud compute backend-services list | grep github-agent # 输出: gkegw1-bu0s-default-clusterip-py-github-agent-8000-iymtp0imv8al -
检查这个
Backend Service的实时timeoutSec属性。bashgcloud compute backend-services describe gkegw1-bu0s-default-clusterip-py-github-agent-8000-iymtp0imv8al --global --format="value(timeoutSec)" -
惊人发现 : 输出为
30!
结论 : 这证明了我们在Kubernetes中应用的BackendConfig完全没有生效 。GKE控制器忽略了我们的配置,并使用了30秒的默认值。这显然是GKE控制器的一个Bug。
步骤2: 第一次手动修复
假设 : 既然Backend Service是问题的关键,手动修复它应该能解决问题。
动作:
-
使用
gcloud命令强制更新Backend Service的超时。bashgcloud compute backend-services update gkegw1-bu0s-default-clusterip-py-github-agent-8000-iymtp0imv8al --global --timeout=600 -
等待1分钟后,重新测试外部
curl请求。 -
结果 : 再次失败! 依旧是
504 stream timeout。
步骤3: 检查URL Map
假设 : 问题可能在比Backend Service更高一层的URL Map上。URL Map中的路由规则也可以定义超时,并且其优先级可能更高。
动作:
-
导出
URL Map的完整YAML配置进行分析。bashgcloud compute url-maps describe gkegw1-bu0s-default-py-api-gateway-rrnx141i3brm --format=yaml -
发现 : 在匹配
/py-github-agent路径的routeAction中,完全没有timeout字段。
最终假设 : 当URL Map的routeAction中没有明确的timeout时,它不会继承Backend Service的超时,而是使用一个独立的、全局默认的30秒超时。而我们在HTTPRoute中的配置(本应在此处生效)被GKE控制器忽略了(又一个Bug)。
6. 意外的解决方案:漫长的生效延迟
在我们准备对URL Map进行更复杂的手动修复时,应您的要求,我们又进行了一次最终的外部curl测试。
结果 : 成功了!
最终结论 :
问题的根源确实是Backend Service的超时配置错误。我们使用gcloud手动将其更新为600秒的操作是正确的。
然而,这个变更在Google Cloud的全球负载均衡器基础设施上完全生效,花费了远超预期的漫长时间(超过10分钟) 。我们紧随其后的测试都因为配置尚未生效而失败,从而误导我们去排查更高层的URL Map。在我们进行讨论和检查的这段时间里,配置最终悄悄地完成了同步。
7. 总结与反思
- GKE Gateway Bug : GKE Gateway控制器目前存在Bug,无法稳定地将
HTTPRoute.timeouts和Service上的BackendConfig注解同步到底层的GCP资源。 - 手动干预是最后手段 : 当声明式配置失效时,直接使用
gcloud命令检查和修改底层的云资源是排查问题的终极手段。 - 配置生效延迟: 对于全局网络资源,变更可能需要很长的时间才能完全生效,需要有足够的耐心等待和验证。
虽然手动修改云资源会造成"配置漂移",但在这种控制器Bug的情况下,这是恢复服务的唯一有效方法。建议将此类手动变更详细记录,并考虑在未来通过Terraform等工具管理这些云资源,或向Google报告此Bug。