AWS ALB+EKS+NGINX环境下Express GET请求Connection:close问题求助
核心现象:外部通过AWS ALB访问时,GET请求响应返回Connection: close,POST请求保持Connection: keep-alive;但集群内部直接请求NGINX Ingress时,所有请求都返回Connection: keep-alive,强制设置响应头无效。
排查方向与解决步骤
检查NGINX Ingress Controller的全局配置
先确认Ingress Controller的ConfigMap没有针对GET请求的特殊连接配置,重点看以下参数:proxy_http_version:必须设置为1.1(HTTP/1.0默认不支持keep-alive)proxy_set_header Connection:建议配置为"$connection_upgrade",保持动态适配keepalive_timeout和keepalive_requests:设置合理的连接存活时间和单连接可处理请求数
示例ConfigMap配置:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-ingress-controller data: proxy_http_version: "1.1" proxy_set_header: "Connection \"$connection_upgrade\"" keepalive_timeout: "75s" keepalive_requests: "100"同时检查目标Ingress资源的annotations,确认是否有
nginx.ingress.kubernetes.io/configuration-snippet这类自定义片段,是否针对GET请求设置了Connection: close。强制在Ingress中为GET请求注入Connection头
如果全局配置无异常,尝试在目标Ingress资源中添加annotation,强制为GET请求注入Connection: keep-alive头,注意加上always确保所有响应都生效:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: annotations: nginx.ingress.kubernetes.io/configuration-snippet: | if ($request_method = GET) { add_header Connection keep-alive always; } # 其他元数据配置 spec: # 路由规则配置排查AWS ALB目标组与监听配置
- 确认目标组的HTTP版本为
HTTP/1.1,若为HTTP/1.0会导致ALB默认关闭连接 - 检查目标组的
Idle timeout设置,建议和NGINX的keepalive_timeout保持一致(比如75秒),避免ALB提前关闭空闲连接 - 若ALB启用了HTTP/2监听,尝试临时禁用HTTP/2,仅保留HTTP/1.1,排查是否是HTTP/2兼容导致的请求方法差异
- 确认目标组的HTTP版本为
抓包验证流量链路
在NGINX Ingress Pod上执行抓包,确认NGINX返回给ALB的响应头是否正确:# 进入Ingress Pod kubectl exec -it <nginx-ingress-pod-name> -- /bin/bash # 抓包过滤Connection头 tcpdump -i any port 80 -A | grep -i "Connection:"用外部curl发送GET请求,观察NGINX输出的响应头:如果NGINX返回
keep-alive但ALB转发给客户端的是close,问题出在ALB侧;如果NGINX本身返回close,则回到Ingress配置继续排查。
内容的提问来源于stack exchange,提问作者nadav steiner

