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/