Traefik代理K8s集群API超时问题:30秒后返回502错误
我在K8s集群中部署了用于测试Traefik配置的API(地址:https://apps.peregimenez.com/corstest),该API接收请求后会延迟指定时间再返回响应。
测试命令如下:
curl -X 'POST' 'https://apps.peregimenez.com/corstest' -H 'accept: application/json' -H 'Content-Type: application/json' -H "Origin: https://peregimenez.com" -d '{ "query": "hello there", "sleep":30 }' -i --max-time 60
当延迟时间小于30秒时请求正常,超过30秒则返回502 Server Error,Traefik日志显示:
time="2023-11-30T11:42:54Z" level=debug msg="'499 Client Closed Request' caused by: context canceled"
我已尝试在Helm Chart中设置更高的超时时间甚至禁用超时,但均无效,请问问题出在哪里?我的Chart配置如下:
ingressClass: enabled: true isDefaultClass: false additionalArguments: - "--log.level=DEBUG" - "--providers.kubernetesingress.ingressclass=traefik" - "--ping" - "--entryPoints.websecure.transport.respondingTimeouts.readTimeout=300s" - "--entryPoints.websecure.transport.respondingTimeouts.writeTimeout=300s" - "--entryPoints.websecure.transport.respondingTimeouts.idleTimeout=300s" - "--entryPoints.websecure.transport.lifeCycle.graceTimeOut=300s" - "--entryPoints.web.transport.respondingTimeouts.readTimeout=300s" - "--entryPoints.web.transport.respondingTimeouts.writeTimeout=300s" - "--entryPoints.web.transport.respondingTimeouts.idleTimeout=300s" - "--entryPoints.web.transport.lifeCycle.graceTimeOut=300s" - "--serversTransport.forwardingTimeouts.responseHeaderTimeout=300s" - "--serversTransport.forwardingTimeouts.idleConnTimeout=300s" dashboard: enabled: true rbac: enabled: true providers: kubernetesCRD: enabled: true ports: web: port: 8000 expose: true exposedPort: 80 protocol: TCP nodePort: 32080 websecure: port: 8443 expose: true exposedPort: 443 protocol: TCP nodePort: 32443 service: enabled: true type: NodePort requests: cpu: "100m" memory: "100Mi" limits: cpu: "100m" memory: "100Mi"
从日志里的499 Client Closed Request和context canceled来看,核心问题并非Traefik的入口点超时配置,而是缺少后端服务的全局超时控制,同时还要排查几个潜在的覆盖性配置:
1. 补充Traefik后端转发的总超时参数
你当前只配置了Traefik与客户端的交互超时(entryPoints.*.transport.respondingTimeouts),以及等待后端响应头的超时(responseHeaderTimeout),但没有设置Traefik等待后端完整响应的总超时时间。需要在additionalArguments中添加对应版本的参数:
- 若使用Traefik v2.x:
- "--serversTransport.forwardingTimeouts.dialTimeout=300s" - "--serversTransport.forwardingTimeouts.timeout=300s" - 若使用Traefik v3.x:
- "--serversTransport.forwardingTimeouts.timeout=300s"
2. 检查Ingress资源的注解覆盖
如果你的Ingress对象中配置了traefik.ingress.kubernetes.io/proxy-read-timeout或traefik.ingress.kubernetes.io/proxy-send-timeout这类注解,会直接覆盖Helm的全局配置。需要检查并调整:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: # 若存在这些注解,要么删除,要么将值设为300(单位秒) traefik.ingress.kubernetes.io/proxy-read-timeout: "300" traefik.ingress.kubernetes.io/proxy-send-timeout: "300"
3. 排查后端Pod的探针超时
如果后端API的存活/就绪探针超时时间过短(比如小于30秒),Kubernetes会在请求处理期间重启Pod,导致Traefik收到连接中断错误。需要调整后端Deployment的探针配置:
livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 60 # 确保该值大于测试的延迟时间 failureThreshold: 3
调整完成后,重新部署Traefik和后端服务,再测试延迟超过30秒的请求即可。
内容的提问来源于stack exchange,提问作者Pedro G.

