关于 model-serving-kubernetes
面向在 Kubernetes 上部署机器学习模型的工程师,提供基于 KServe 和 Triton 的模型服务操作指南,涵盖流量切分、自动扩缩和 GPU 调度。
主要功能
- 01部署 KServe InferenceService
- 02配置模型金丝雀发布与流量切分
- 03按请求或 GPU 指标自动扩缩
- 04使用 Triton 管理模型版本
- 05配置动态批处理与 GPU 调度
适用场景
- 01在 Kubernetes 上部署机器学习模型
- 02逐步验证新模型版本并调整流量
- 03扩缩 LLM 推理服务
- 04管理 Triton 模型加载与卸载
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ bagelhole/ devops-security-agent-skills --skill model-serving-kubernetes安装后在 Claude Code 中输入/model-serving-kubernetes确认已加载。
详细介绍
Kubernetes 上的模型服务
使用 KServe 和 Triton 提供生产级机器学习模型服务 — 金丝雀部署、自动扩缩容和 GPU 感知调度。
何时使用此技能
在以下情况下使用此技能:
- 大规模提供 scikit-learn、PyTorch、TensorFlow 或 ONNX 模型服务
- 为机器学习模型实现金丝雀部署和 A/B 测试
- 根据请求速率或 GPU 指标对推理 Pod 进行自动扩缩容
- 在 Kubernetes 上使用 Triton 或 KServe 部署 LLM
- 通过流量拆分管理多个模型版本
前提条件
- 配备 GPU 节点的 Kubernetes 1.28+
- 已安装 KServe(或独立部署的 Triton)
- 已配置
kubectl和helm - 集群上已安装 NVIDIA GPU Operator
安装 KServe
# Install KServe with Helm
helm repo add kserve https://kserve.github.io/helm-charts
helm repo update
helm install kserve kserve/kserve \
--namespace kserve \
--create-namespace \
--set kserve.controller.gateway.ingressGateway.className=nginx
# Verify
kubectl get pods -n kserve
kubectl get crd | grep kserve
基本的 InferenceService(KServe)
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: sklearn-iris
namespace: models
spec:
predictor:
sklearn:
storageUri: gs://kfserving-examples/models/sklearn/1.0/model
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 4Gi
kubectl apply -f inference-service.yaml
# Get inference service URL
kubectl get inferenceservice sklearn-iris -n models
# NAME URL READY ...
# sklearn-iris http://sklearn-iris.models.example.com True
# Test prediction
curl -X POST http://sklearn-iris.models.example.com/v1/models/sklearn-iris:predict \
-H "Content-Type: application/json" \
-d '{"instances": [[6.8, 2.8, 4.8, 1.4]]}'
启用 GPU 的 LLM InferenceService
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: llama-3-8b
namespace: models
annotations:
serving.kserve.io/enable-prometheus-scraping: "true"
spec:
predictor:
containers:
- name: vllm-container
image: vllm/vllm-openai:latest
args:
- "--model"
- "meta-llama/Llama-3.1-8B-Instruct"
- "--tensor-parallel-size"
- "1"
- "--gpu-memory-utilization"
- "0.90"
ports:
- containerPort: 8080
protocol: TCP
resources:
requests:
nvidia.com/gpu: "1"
memory: "20Gi"
cpu: "4"
limits:
nvidia.com/gpu: "1"
memory: "24Gi"
cpu: "8"
readinessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
env:
- name: HUGGING_FACE_HUB_TOKEN
valueFrom:
secretKeyRef:
name: hf-token
key: token
nodeSelector:
nvidia.com/gpu.present: "true"
transformer:
containers:
- name: kserve-container
image: kserve/kserve-transformer:latest
金丝雀部署(流量拆分)
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
name: llama-3-8b
namespace: models
spec:
predictor:
canaryTrafficPercent: 20 # 20% to new version, 80% to stable
containers:
- name: vllm-container
image: vllm/vllm-openai:latest
args:
- "--model"
- "meta-llama/Llama-3.1-8B-Instruct-v2" # new model version
resources:
limits:
nvidia.com/gpu: "1"
# Gradually increase canary traffic
kubectl patch inferenceservice llama-3-8b -n models \
--type='json' \
-p='[{"op":"replace","path":"/spec/predictor/canaryTrafficPercent","value":50}]'
# Promote canary to stable
kubectl patch inferenceservice llama-3-8b -n models \
--type='json' \
-p='[{"op":"remove","path":"/spec/predictor/canaryTrafficPercent"}]'
使用 KEDA 自动扩缩容
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: llama-scaler
namespace: models
spec:
scaleTargetRef:
apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
name: llama-3-8b
minReplicaCount: 1
maxReplicaCount: 5
triggers:
- type: prometheus
metadata:
serverAddress: http://prometheus-server.monitoring:9090
metricName: kserve_request_count
threshold: "10"
query: |
sum(rate(kserve_request_count_total{namespace="models",
service="llama-3-8b"}[1m]))
NVIDIA Triton 推理服务器
apiVersion: apps/v1
kind: Deployment
metadata:
name: triton-server
namespace: models
spec:
replicas: 2
selector:
matchLabels:
app: triton
template:
metadata:
labels:
app: triton
spec:
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:24.05-py3
args:
- "tritonserver"
- "--model-store=s3://my-model-store/models"
- "--model-control-mode=poll" # auto-load new model versions
- "--repository-poll-secs=30"
- "--metrics-port=8002"
ports:
- containerPort: 8000 # HTTP
- containerPort: 8001 # gRPC
- containerPort: 8002 # Metrics
resources:
limits:
nvidia.com/gpu: "1"
readinessProbe:
httpGet:
path: /v2/health/ready
port: 8000
initialDelaySeconds: 30
Triton 模型仓库结构
s3://my-model-store/models/
├── text-classifier/
│ ├── config.pbtxt
│ ├── 1/
│ │ └── model.onnx
│ └── 2/
│ └── model.onnx # new version; auto-loaded
├── embedding-model/
│ ├── config.pbtxt
│ └── 1/
│ └── model.onnx
# config.pbtxt for ONNX model
name: "text-classifier"
backend: "onnxruntime"
max_batch_size: 64
dynamic_batching {
preferred_batch_size: [16, 32]
max_queue_delay_microseconds: 1000
}
input [
{ name: "input_ids" data_type: TYPE_INT64 dims: [-1] }
{ name: "attention_mask" data_type: TYPE_INT64 dims: [-1] }
]
output [
{ name: "logits" data_type: TYPE_FP32 dims: [-1] }
]
instance_group [
{ kind: KIND_GPU count: 2 } # 2 model instances on GPU
]
模型管理命令
# List loaded models (Triton)
curl http://triton:8000/v2/models
# Load a new model version
curl -X POST http://triton:8000/v2/repository/models/text-classifier/load
# Unload a model
curl -X POST http://triton:8000/v2/repository/models/text-classifier/unload
# KServe — watch rollout status
kubectl rollout status deployment/llama-3-8b-predictor -n models
kubectl get inferenceservice llama-3-8b -n models -w
常见问题
| 问题 | 原因 | 解决方法 |
|---|---|---|
InferenceService not ready | 模型加载或内存不足(OOM) | 检查预测器 Pod 日志;提高内存限制 |
| 金丝雀版本停留在 0% | KNative 路由问题 | 检查 kubectl get ksvc -n models |
| Triton 找不到模型 | S3 权限或路径问题 | 验证 IAM 角色;检查 --model-store 路径 |
| GPU 利用率低 | 未启用动态批处理 | 在 Triton 配置中启用 dynamic_batching |
| 自动扩缩容未触发 | Prometheus 查询错误 | 在 Prometheus UI 中测试查询 |
最佳实践
- 对所有模型更新使用金丝雀部署 — 如果指标恶化,可在数秒内回滚。
- 启用 Triton 动态批处理 — 对于小型模型,它可将 GPU 吞吐量提高 5–10 倍。
- 将模型存储在 S3/GCS 中,并使用带版本号的路径(
s3://bucket/model/v1/、v2/)。 - 固定 GPU 节点选择器,防止模型 Pod 被调度到仅配备 CPU 的节点上。
- 在金丝雀发布期间,按模型版本监控 p99 延迟和错误率。
相关技能
- vllm-server - 用于 LLM 服务的 vLLM
- llm-inference-scaling - KEDA 自动扩缩容
- kubernetes-ops - Kubernetes 核心运维
- gpu-server-management - GPU 节点
评论
支持 Markdown