AKS搭配Ingress控制器60秒后断开Redis连接求助
问题
环境配置:
- 使用Django Channels部署应用,依赖Azure Cache for Redis缓存服务
- 网络架构:标准负载均衡器后接nginx-ingress控制器,流量路由至后端Pod
问题现象:无论如何配置负载均衡器或Ingress,Redis连接总会在60秒后被断开。
已排除的情况:
- AKS外部署相同环境无超时问题,后端连接集群内Redis实例时无此问题,因此确定问题出在AKS或Ingress控制器上
- 负载均衡器规则已配置允许至少30分钟的空闲连接
- 无防火墙限制
- 排除应用内超时(本地运行无超时)
- 排除Ingress超时(设置小于60秒才会触发超时)
当前Ingress配置:
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: {{ include "HELPERS.name" . }} labels: app: {{ include "HELPERS.name" . }} chart: {{ template "HELPERS.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} annotations: nginx.ingress.kubernetes.io/proxy-body-size: 5m nginx.ingress.kubernetes.io/proxy-send-timeout: "3600" nginx.ingress.kubernetes.io/proxy-read-timeout: "3600" nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600" nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "3600" nginx.ingress.kubernetes.io/auth-keepalive-timeout: "3600" nginx.ingress.kubernetes.io/limit-rps: '500' cert-manager.io/cluster-issuer: {{ .Values.cert_issuer_prefix }}-cert-issuer acme.cert-manager.io/http01-edit-in-place: "true" nginx.org/client-max-body-size: "30m"
Ingress控制器的ConfigMap配置:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-ingress-test-ocean-ingress-nginx-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx helm.sh/chart: ingress-nginx-3.35.0 app.kubernetes.io/instance: nginx-ingress-test-ocean app.kubernetes.io/managed-by: Helm data: proxy-connect-timeout: "420" proxy-read-timeout: "420" proxy-send-timeout: "420" keepalive-timeout : "420" keep-alive: "420" upstream-keepalive-timeout: "420"
请问可能是哪一方导致该问题?如何修改负载均衡器/AKS/Ingress控制器或其他服务配置来阻止连接超时?
分析与解决方案
可能的问题根源
- AKS节点SNAT超时限制:AKS节点的出站SNAT连接默认超时为60秒,Pod通过节点公共IP连接Azure Cache for Redis时,空闲连接会被SNAT规则强制断开。
- Nginx Ingress缺少WebSocket专属配置:Django Channels依赖WebSocket,当前配置未覆盖WebSocket特有的握手与超时参数,导致Nginx主动切断空闲连接。
- ConfigMap参数错误:当前ConfigMap中存在无效参数,部分超时配置未生效。
针对性修复步骤
1. 调整AKS出站SNAT超时
在后端应用的Service资源中添加注解,延长SNAT空闲超时至30分钟(1800秒):
metadata: annotations: service.beta.kubernetes.io/azure-load-balancer-tcp-idle-timeout: "1800"
该注解仅对通过AKS负载均衡器出站的连接生效,需确保应用Pod通过集群出站LB访问Azure Cache for Redis。
2. 补充Nginx Ingress的WebSocket配置
在Ingress的annotations中添加WebSocket相关参数:
nginx.ingress.kubernetes.io/websocket-services: "{{ include "HELPERS.name" . }}" nginx.ingress.kubernetes.io/proxy-set-header: "Upgrade $http_upgrade" nginx.ingress.kubernetes.io/proxy-set-header: "Connection \"upgrade\"" nginx.ingress.kubernetes.io/proxy-read-timeout: "1800" nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
websocket-services指定处理WebSocket流量的后端服务名称Upgrade和Connection头确保Nginx正确转发WebSocket握手请求- 延长读写超时至1800秒,覆盖默认60秒限制
3. 修正Nginx ConfigMap参数
删除无效的keep-alive参数,统一延长所有超时配置至1800秒:
apiVersion: v1 kind: ConfigMap metadata: name: nginx-ingress-test-ocean-ingress-nginx-controller namespace: ingress-nginx labels: app.kubernetes.io/name: ingress-nginx helm.sh/chart: ingress-nginx-3.35.0 app.kubernetes.io/instance: nginx-ingress-test-ocean app.kubernetes.io/managed-by: Helm data: proxy-connect-timeout: "1800" proxy-read-timeout: "1800" proxy-send-timeout: "1800" keepalive-timeout: "1800" upstream-keepalive-timeout: "1800"
4. 验证Azure Cache for Redis配置
在Azure门户中检查Redis实例的idle-timeout设置,确保其值大于1800秒,避免Redis端主动断开空闲连接。
内容的提问来源于stack exchange,提问作者Mateusz Pydych
相关产品推荐
相关产品推荐

