如何为WebSocket场景扩容AWS EKS Kubernetes集群?
问题描述
我在为承载大量WebSocket连接的Kubernetes集群扩容时遇到问题。此前使用AWS EC2 t2.medium实例运行服务器,流量增长后升级为t2.large,但预计4-6周后将无法满足需求,因此转向AWS EKS实现水平扩容。
已部署好EKS集群、工作节点、Pod,配置了Prometheus+Grafana监控、Cluster Autoscaler和HPA。但压测时发现,即便Pod的CPU(500m)和内存(500Mi)阈值未被触发,发送消息时WebSocket连接立即断开。此前在t2.large上遇到过类似问题,最终解决方式是提升Ubuntu的文件描述符限制,但在EKS中无法SSH到自动扩容的EC2实例,也不知如何在Pod层面配置系统级参数。当前6个Pod的内存使用率仅4/16Gi、CPU使用率略超2%,资源未充分利用却无法处理连接。
咨询两个问题:
- 如何在AWS EKS集群中提升文件描述符限制?
- 除文件描述符外,还有哪些可能导致该问题的原因?
附相关配置
Deployment配置
apiVersion: apps/v1 kind: Deployment metadata: name: web-app-deployment spec: replicas: 6 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: web-app image: web-app-image:latest imagePullPolicy: Always ports: - containerPort: 8000 env: - name: REDIS_HOST value: "redis-stack-0.redis" - name: REDIS_PORT value: "6379" - name: CELERY_BROKER_URL value: "redis://redis-stack-0.redis:6379/0" resources: requests: cpu: "500m" memory: "500Mi"
Service配置
apiVersion: v1 kind: Service metadata: name: web-app-service spec: type: LoadBalancer selector: app: web-app ports: - protocol: TCP port: 80 targetPort: 8000
HPA配置
apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: web-app-hpa namespace: default spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: web-app-deployment minReplicas: 6 maxReplicas: 12 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 - type: Resource resource: name: memory target: type: Utilization averageUtilization: 50
解决方案
1. 在AWS EKS中提升文件描述符限制
Pod层面配置
直接在Deployment的容器定义中添加安全上下文,设置进程级别的文件描述符限制,同时可通过启动命令覆盖软/硬限制:
containers: - name: web-app # 保留原有配置 securityContext: sysctls: - name: fs.file-max value: "1048576" - name: net.core.somaxconn value: "65535" # 启动命令中设置进程级限制 command: ["sh", "-c", "ulimit -n 1048576 && exec your-application-start-command"]
如果是自定义镜像,也可以在Dockerfile中预先配置:
RUN echo "* soft nofile 1048576" >> /etc/security/limits.conf && \ echo "* hard nofile 1048576" >> /etc/security/limits.conf CMD ["your-application-start-command"]
节点层面配置(自动扩容EC2节点)
通过EKS节点组的启动模板(User Data)批量配置系统级限制,新扩容的节点会自动生效:
- 编辑节点组关联的EC2启动模板,添加以下User Data脚本:
#!/bin/bash echo "* soft nofile 1048576" >> /etc/security/limits.conf echo "* hard nofile 1048576" >> /etc/security/limits.conf echo "fs.file-max=1048576" >> /etc/sysctl.conf echo "net.core.somaxconn=65535" >> /etc/sysctl.conf sysctl -p
- 更新EKS节点组使用修改后的启动模板,后续自动扩容的节点会自动应用配置。
2. 其他可能导致WebSocket连接断开的原因
- 负载均衡器超时设置:AWS ALB/NLB默认空闲超时为60秒,若WebSocket心跳间隔超过该值,会被LB主动断开,需将超时调整为300秒或更长。
- 应用层逻辑问题:检查应用是否存在连接泄漏、消息处理阻塞、未捕获异常,比如Redis连接池耗尽、Celery任务阻塞导致主线程无法响应WebSocket消息。
- 网络策略限制:是否有Kubernetes网络策略限制了Pod间或Pod与外部的长连接,导致连接被强制中断。
- 内核参数异常:除文件描述符外,
net.ipv4.tcp_tw_reuse、net.ipv4.tcp_fin_timeout配置不当会导致TIME_WAIT连接堆积,占用端口资源。 - TCP队列溢出:新连接请求过多时,TCP监听队列(backlog)溢出会导致连接被拒绝,需调整
net.core.somaxconn及应用自身的listen backlog参数。 - HPA指标异常:检查HPA是否正确采集CPU/内存指标,是否因指标延迟导致Pod未及时扩容,或资源请求/限制设置不合理导致Pod被节流。
内容的提问来源于stack exchange,提问作者Precious112
相关产品推荐
相关产品推荐

