You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ingress Nginx连接上游超时但仍返回正常结果问题求助

Ingress Nginx 间歇性连接上游超时问题排查

问题描述

遇到Ingress Nginx间歇性报错:Intermittent ingress nginx upstream timed out (110: Operation timed out) while connecting to upstream,具体情况如下:

  1. 此错误并非while reading response header from upstream,且上游服务器响应无延迟。
  2. 执行curl https://knotfree.net/api1/getGiantPassword会出现5秒延迟,而curl http://knotfree.io/api1/getGiantPassword无延迟,符合预期。
  3. 重启Ingress Nginx Pod后,首次请求可正常完成;后续执行上述HTTPS请求时,Nginx会等待5秒后记录超时错误日志:
2024/07/06 18:35:06 [error] 26#26: *556202 upstream timed out (110: Operation timed out) while connecting to upstream, client: 10.3.96.7, server: knotfree.net, request: "GET /api1/getGiantPassword HTTP/2.0", upstream: "http://[fd10:1ba:6d2c:1000:3a5b:26d5:2b5f:56b6]:8085/api1/getGiantPassword", host: "knotfree.net"
  1. 超时后Nginx会将请求发送至上游,上游服务器记录请求并在毫秒级响应,随后Nginx记录200响应日志:
10.3.96.7 - - [06/Jul/2024:18:45:10 +0000] "GET /api1/getGiantPassword HTTP/2.0" 200 79 "-" "curl/8.6.0" 46 5.002 [knotspace-knotfreeaide-80] [] [fd10:1ba:6d2c:1000:3a5b:26d5:2b5f:56b6]:8085, 10.244.183.182:8085 0, 79 5.000, 0.002 504, 200 6e1e1ab19b8964722f112dc49e642238

最终curl可获取正确输出(随机数)。

疑问

  • 为何Nginx既记录连接上游超时错误,又能返回正确的200响应?
  • 为何请求有时能完全正常执行?
  • “无法连接上游”意味着什么?是否需要配置健康检查?

环境与配置

  • 运行环境:Vultr Kubernetes
  • Ingress负责HTTPS终止,非安全端点curl http://knotfree.io/api1/getGiantPassword始终正常
  • Ingress配置:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    kubernetes.io/ingress.class: nginx
    external-dns.alpha.kubernetes.io/hostname: "knotfree.net"  
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    certmanager.k8s.io/issuer: "letsencrypt-prod"
    certmanager.k8s.io/acme-challenge-type: dns01
    certmanager.k8s.io/acme-dns01-provider: vultr
    
  name: nginx-ingress
spec:
  rules:
  - host: "knotfree.net" 
    http:
      paths:
      - backend:
          service:
            name: knotfreeaide
            port:
              number: 80
        path: /
        pathType: Prefix
  - host: "*.knotfree.net" 
    http:
      paths:
      - backend:
          service:
            name: knotfreeaide
            port:
              number: 80
        path: /
        pathType: Prefix
  tls:
  - hosts:
    - "knotfree.net"
    - "*.knotfree.net"
    secretName: wildcard-tls

问题解答

1. 为何Nginx既记录连接上游超时错误,又能返回正确的200响应?

从日志可以明确看到,Nginx首先尝试连接IPv6地址[fd10:1ba:6d2c:1000:3a5b:26d5:2b5f:56b6]:8085时触发了5秒连接超时,因此记录了错误日志。随后Nginx会尝试Service对应的其他后端端点(此处为IPv4地址10.244.183.182:8085),该连接成功且上游毫秒级响应,最终Nginx将200结果返回给客户端。错误日志仅记录首次连接失败事件,后续重试/切换端点成功的流程不会覆盖该错误记录。

2. 为何请求有时能完全正常执行?

重启Ingress Pod后首次请求正常,是因为此时Nginx的上游端点缓存、连接池为空,可能优先选择了可用的IPv4端点,或该时段IPv6端点临时连通。后续请求出现超时,是因为Nginx尝试复用之前的IPv6连接,或通过轮询策略选中了存在连通性问题的IPv6端点,直到切换到IPv4端点才完成请求。

另外,Kubernetes Service的端点列表可能同时包含IPv4和IPv6地址,Nginx默认轮询策略会轮流选择这些端点:选中IPv4时请求正常,选中IPv6时触发连接超时,直到重试或切换端点。

3. “无法连接上游”意味着什么?是否需要配置健康检查?

“无法连接上游”表示Nginx在指定超时时间内,无法与目标上游端点建立TCP连接(并非上游响应缓慢)。结合日志中的IPv6地址,大概率是集群内IPv6网络存在连通性问题,比如Pod IPv6地址不可达、网络策略限制、CNI插件IPv6配置异常等。

需要配置健康检查:默认情况下,Ingress Nginx仅依赖Kubernetes Service的端点状态(仅检查Pod是否Running),无法识别端点的实际连通性。建议通过Ingress Annotation配置Nginx主动健康检查,自动剔除不可达的上游端点:

nginx.ingress.kubernetes.io/upstream-healthcheck-path: "/api1/health"
nginx.ingress.kubernetes.io/upstream-healthcheck-port: "8085"
nginx.ingress.kubernetes.io/healthcheck-interval: "10s"
nginx.ingress.kubernetes.io/healthcheck-timeout: "5s"

此外,也可排查集群IPv6配置是否正常,或通过Service配置强制使用IPv4(若无需IPv6):在Service的spec中设置ipFamilyPolicy: SingleStack和ipFamilies: ["IPv4"]。


内容的提问来源于stack exchange,提问作者Alan Wootton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 10:45:04