AI Token流量爆发下的Kubernetes容器弹性伸缩配置指南

AI服务流量的特殊性:为什么传统HPA不够用

大模型推理服务的流量模式与传统Web应用截然不同。Token流式传输导致单请求持续时间长达10-60秒,并发连接数与QPS之间的换算关系完全不同。一个100 QPS的聊天补全接口,在平均响应时间30秒的情况下,同时活跃连接数约3000。传统HPA基于CPU利用率的伸缩策略在这里失效,因为推理进程在等待GPU计算时CPU使用率很低,但GPU显存已经接近满载。

Kubernetes容器编排需要针对AI推理服务的特征,从指标采集、伸缩策略、Pod调度三个层面进行适配。

自定义指标体系设计

Prometheus Adapter是连接Prometheus指标与Kubernetes API的桥梁。需要为AI推理服务定义业务级别的伸缩指标:

# prometheus-adapter配置 (adapter-config.yaml)
rules:
  - seriesQuery: 'vllm_num_requests_running{namespace!="",pod!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
        pod: {resource: "pod"}
    name:
      matches: "vllm_num_requests_running"
      as: "active_requests"
    metricsQuery: 'sum(vllm_num_requests_running{namespace="<<.Namespace>>"}) by (pod)'

  - seriesQuery: 'vllm_gpu_cache_usage_perc{namespace!="",pod!=""}'
    resources:
      overrides:
        namespace: {resource: "namespace"}
        pod: {resource: "pod"}
    name:
      matches: "vllm_gpu_cache_usage_perc"
      as: "gpu_cache_utilization"
    metricsQuery: 'avg(vllm_gpu_cache_usage_perc{namespace="<<.Namespace>>"}) by (pod)'

部署Prometheus Adapter后,验证自定义指标是否可被Kubernetes API识别:

# 查询自定义指标
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1 \
  | jq '.resources[] | select(.name | contains("active_requests"))'

# 获取当前指标值
kubectl get --raw /apis/custom.metrics.k8s.io/v1beta1/namespaces/llm-prod/pods/*/active_requests

HPA策略:基于活跃请求数的弹性伸缩

AI推理服务的HPA策略应以活跃请求数(active_requests)为主指标,CPU利用率为辅助指标:

# hpa-vllm.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: vllm-inference-hpa
  namespace: llm-prod
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: vllm-inference
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Pods
      pods:
        metric:
          name: active_requests
        target:
          type: AverageValue
          averageValue: "50"   # 每Pod平均50个活跃请求时扩容
    - type: Resource
      resource:
        name: nvidia.com/gpu
        target:
          type: Utilization
          averageUtilization: 80
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Percent
          value: 100
          periodSeconds: 60
    scaleDown:
      stabilizationWindowSeconds: 300   # 缩容等待5分钟
      policies:
        - type: Percent
          value: 25    # 每次最多缩容25%
          periodSeconds: 120

关键参数说明:scaleUp的stabilizationWindowSeconds设为30秒,AI服务流量尖峰来得快,需要快速扩容。scaleDown等待300秒,避免流量波动导致反复缩容扩容。

Pod优雅上下线与请求排空

AI推理Pod缩容时,正在进行的Token流式传输必须被排空,否则用户体验中断。需要配置preStop钩子实现请求排空:

# deployment-vllm.yaml (关键片段)
spec:
  template:
    spec:
      terminationGracePeriodSeconds: 120
      containers:
        - name: vllm
          lifecycle:
            preStop:
              exec:
                command:
                  - /bin/sh
                  - -c
                  - |
                    # 标记Pod为不可调度
                    curl -X POST http://localhost:8000/health | grep -q ok || true
                    # 等待活跃请求处理完成
                    while [ "$(curl -s http://localhost:8000/metrics | grep vllm_num_requests_running | awk '{print $2}')" -gt 0 ]; do
                      sleep 5
                    done
          readinessProbe:
            httpGet:
              path: /health
              port: 8000
            initialDelaySeconds: 60
            periodSeconds: 10

配合Service的publishNotReadyAddresses: false设置,Pod进入Terminating状态后自动从Service Endpoints摘除,新请求不会路由到即将下线的Pod,但已建立的SSE连接保持不变直到Token流式传输完成。

KEDA事件驱动伸缩:应对突发流量

对于流量波动大的AI服务场景,KEDA提供更细粒度的伸缩控制。基于请求队列深度触发扩容,比HPA的周期性轮询响应更快:

# keda-scaledobject.yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: vllm-scaler
  namespace: llm-prod
spec:
  scaleTargetRef:
    name: vllm-inference
  minReplicaCount: 2
  maxReplicaCount: 20
  cooldownPeriod: 300
  triggers:
    - type: prometheus
      metadata:
        serverAddress: http://prometheus:9090
        metricName: vllm_num_requests_waiting
        threshold: "10"
        query: "sum(vllm_num_requests_waiting{namespace='llm-prod'})"

KEDA的优势在于支持多种触发器类型。当请求队列积压超过10个时立即扩容,无需等待HPA的轮询周期。同时KEDA可以将副本数缩容到0(minReplicaCount=0),在夜间低峰期节省GPU资源成本。

GPU感知调度与拓扑感知

多GPU节点的Kubernetes集群,调度器需要感知GPU拓扑。NVIDIA GPU Operator自动安装nvidia-device-plugin,但默认调度策略不考虑GPU间NVLink拓扑:

# 启用Topology Manager
# kubelet配置
featureGates:
  TopologyManager: true
  TopologyManagerPolicyAlpha: true

# 节点级拓扑策略
topologyManagerPolicy: "best-effort"

# Pod调度约束
resources:
  limits:
    nvidia.com/gpu: 4
  # 通过resourceClass指定拓扑约束

对于需要4卡NVLink全互联的训练任务,使用Node Affinity将任务调度到HGX架构节点,避免被调度到多卡但无NVLink的L40S节点上。

监控与告警体系搭建

完整的AI服务容器监控需要覆盖三层:基础设施层(GPU/网络/存储)、Kubernetes层(Pod/Deployment/HPA)、业务层(请求延迟/队列深度/Token吞吐):

# Prometheus告警规则
- alert: AIServiceHighLatency
  expr: histogram_quantile(0.99, rate(vllm_request_duration_seconds_bucket[5m])) > 30
  for: 2m
  labels:
    severity: warning
  annotations:
    summary: "AI推理P99延迟超过30秒"

- alert: AIPodPendingScaleUp
  expr: kube_hpa_status_desired_replicas > kube_hpa_status_current_replicas
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "HPA扩容未满足,可能GPU资源不足"

当HPA触发扩容但集群中没有可用GPU节点时,需要配合Cluster Autoscaler自动扩容底层GPU节点。确保Cluster Autoscaler的节点组配置了GPU机型,扩容超时设置为10分钟以内。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/aitoken-liu-liang-bao-fa-xia-de-kubernetes-rong-qi-tan-xing/

(0)
小编小编
上一篇 2小时前
下一篇 2小时前

相关推荐