我在使用大量 Websocket 连接正确扩展我的 Kubernetes 集群时遇到问题。
所以在我搬到 kubernetes 之前,我在我的服务器上使用了 t2.medium aws ec2 实例,坚持了一段时间,直到我开始获得大量流量,准确地说是 websocket 连接,所以为了临时修复,我将实例升级为目前正在处理流量的 t2.large,但随着当前用户的增长,我知道新实例将无法在接下来的 4-6 周内阻止它,所以我决定只使用 kubernetes 进行水平自动缩放。
我已经通过 aws EKS 设置了 Kubernetes、所有需要的工作节点和 Pod、用于指标监控的 Prometheus 和 Grafana、用于扩展工作节点的集群自动缩放器以及用于扩展 Pod 副本的 HPA。
但是在负载测试时我遇到了一个问题,即使在该流量级别上没有超过 cpu 和内存利用率阈值(我将每个 pod 的 cpu 设置为 500m,将内存设置为 500Mi),所有 websocket 都会立即断开连接消息是通过连接发送的,在 t2.large 上发生了类似的事情,它最终成为 ubuntu 上的文件描述符限制,我必须为我的 Web 服务器的工作进程增加该限制,但我找不到方法要在 kubernetes 上执行此操作,首先我无法 ssh 到任何 ec2 实例,集群自动缩放器会启动,并且无法使用 pod 进行操作系统级别配置。通过 grafana,我的内存利用率恒定为 4/16 Gi,仅略高于 2% 的 CPU 利用率,这意味着即使现有的 6 个副本 Pod 也未得到充分利用,仍然无法处理连接。
在这种情况下,我可能对可能的解决方案是错误的,这就是为什么我要询问有 kubernetes 经验的人,因为我的假设是基于我使用一个 ec2 实例的经验,但我仍然很想知道是否有一种方法可以我可以增加 aws eks kubernetes 集群中的文件描述符限制。
这是我的 pod yaml 配置:
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"
---
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
type: LoadBalancer
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 8000
这是我的 HPA yaml 配置:
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
所以总而言之,我问两个问题,第一个是我是否可以增加文件描述符限制,第二个是根据您使用 kubernetes 的经验,其他可能的事情可能是错误的,因为根据我的一点经验,我的假设很可能是错了。
要增加 Kubernetes 中的文件描述符限制,您可以使用 DaemonSet 将更改应用到所有节点。这是一个例子:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: increase-fd-limits
spec:
selector:
matchLabels:
name: increase-fd-limits
template:
metadata:
labels:
name: increase-fd-limits
spec:
containers:
- name: increase-fd-limits
image: busybox
command: ["sh", "-c", "ulimit -n 65536"]
securityContext:
privileged: true
对于第二个问题,请考虑检查: