GPT-OSS-20B健康检查接口:K8s集成部署指南

1. 引言:为什么需要健康检查?

想象一下,你费了九牛二虎之力,终于把一个20B参数的大模型部署到了Kubernetes集群里。模型跑起来了,服务也能访问,一切看起来都很美好。但没过多久,你发现服务偶尔会卡住,或者响应变得特别慢,甚至直接挂掉。更头疼的是,你根本不知道它什么时候会出问题,只能等用户投诉了才发现。

这就是为什么我们需要健康检查接口。

对于像GPT-OSS-20B这样的大型模型服务,健康检查不是“锦上添花”,而是“雪中送炭”。它就像是给服务装了一个24小时不间断的“心电图监测仪”,能实时告诉你:

  • 服务还活着吗?
  • 模型加载成功了吗?
  • GPU显存够用吗?
  • 推理速度正常吗?

今天,我就带你一步步把健康检查功能集成到GPT-OSS-20B的K8s部署中,让你对自己的服务状态了如指掌。

2. 理解GPT-OSS-20B与vLLM推理服务

在开始动手之前,我们先花几分钟搞清楚我们在部署什么。

2.1 GPT-OSS-20B是什么?

GPT-OSS-20B是OpenAI最新开源的一个文本生成模型,有200亿参数。这个“20B”指的就是参数量,你可以把它理解成模型的“大脑容量”——参数越多,通常模型的理解和生成能力越强。

这个模型有几个特点:

  • 完全开源:你可以自由使用、修改、部署
  • 支持商用:没有使用限制
  • 推理友好:针对推理场景做了优化
  • WebUI界面:自带一个网页界面,方便交互测试

2.2 vLLM推理引擎

vLLM是一个专门为大模型推理设计的服务引擎,你可以把它想象成一个“超级加速器”。它的核心价值在于:

  • 显存优化:用更少的显存跑更大的模型
  • 吞吐量高:同时处理多个请求也不会太慢
  • 延迟低:单个请求的响应速度更快
  • 兼容性好:支持OpenAI的API格式

我们部署的gpt-oss-20b-WEBUI镜像,其实就是把GPT-OSS-20B模型和vLLM推理引擎打包在一起,再配上了一个网页界面。

2.3 部署的基本要求

根据官方建议,部署这个服务需要:

  • GPU要求:至少2张RTX 4090D(24GB显存/张)
  • 总显存:48GB以上(这是微调的最低要求,纯推理可以稍低)
  • 内存:建议64GB以上
  • 存储:模型文件大约40GB,加上系统空间,建议预留100GB

如果你的环境达不到这个要求,可能会遇到模型加载失败或者推理速度极慢的问题——这也是为什么健康检查如此重要。

3. 基础部署:让服务先跑起来

在添加健康检查之前,我们得先确保基础服务能正常部署和运行。我会带你走一遍完整的部署流程,这样你就能理解健康检查要监控什么。

3.1 环境准备与镜像部署

首先,确保你的K8s集群满足硬件要求。如果你用的是云服务商的GPU节点,通常已经配置好了驱动。如果是自建集群,需要先安装NVIDIA的GPU驱动和nvidia-docker。

部署镜像的步骤很简单:

# gpt-oss-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gpt-oss-20b
  namespace: ai-services
spec:
  replicas: 1  # 单副本部署,多副本需要更多GPU
  selector:
    matchLabels:
      app: gpt-oss-20b
  template:
    metadata:
      labels:
        app: gpt-oss-20b
    spec:
      containers:
      - name: gpt-oss-container
        image: your-registry/gpt-oss-20b-webui:latest
        resources:
          limits:
            nvidia.com/gpu: 2  # 申请2张GPU卡
            memory: "64Gi"
            cpu: "8"
          requests:
            nvidia.com/gpu: 2
            memory: "32Gi"
            cpu: "4"
        ports:
        - containerPort: 7860  # WebUI默认端口
        - containerPort: 8000  # vLLM API端口
        env:
        - name: MODEL_NAME
          value: "gpt-oss-20b"
        - name: GPU_MEMORY_UTILIZATION
          value: "0.9"  # GPU显存使用率上限

应用这个配置:

kubectl apply -f gpt-oss-deployment.yaml

3.2 服务暴露与访问

部署完成后,我们需要创建一个Service来暴露服务:

# gpt-oss-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: gpt-oss-service
  namespace: ai-services
spec:
  selector:
    app: gpt-oss-20b
  ports:
  - name: webui
    port: 80
    targetPort: 7860
    nodePort: 30080  # NodePort方式,方便测试
  - name: api
    port: 8000
    targetPort: 8000
  type: NodePort

应用Service配置后,你就可以通过以下方式访问:

  • WebUI界面http://<节点IP>:30080
  • API接口http://<节点IP>:8000/v1/completions

3.3 验证服务状态

部署完成后,别急着庆祝,先验证一下服务是否真的正常:

# 查看Pod状态
kubectl get pods -n ai-services -l app=gpt-oss-20b

# 查看Pod日志(重点关注模型加载部分)
kubectl logs -f <pod-name> -n ai-services

# 测试API接口
curl -X POST http://<节点IP>:8000/v1/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-oss-20b",
    "prompt": "你好,请介绍一下你自己",
    "max_tokens": 50
  }'

如果一切正常,你应该能看到模型返回的文本。但这时候,我们只能手动检查服务状态——太原始了。接下来,我们就来给它装上“自动监控”。

4. 设计健康检查接口

健康检查不是随便写个接口返回{"status": "ok"}就完事了。一个好的健康检查应该能真实反映服务的健康状况。我设计了一个分层的健康检查方案。

4.1 健康检查的三个层级

我把健康检查分为三个层级,从浅到深:

  1. 存活检查(Liveness Probe):最基础的检查,回答“服务进程还在吗?”
  2. 就绪检查(Readiness Probe):中等深度的检查,回答“服务准备好接收请求了吗?”
  3. 深度健康检查(Health Check API):最全面的检查,回答“服务的各个部件都健康吗?”

4.2 实现健康检查API

我们需要在vLLM服务中添加一个健康检查端点。这里我提供一个Python实现:

# health_check.py
from fastapi import FastAPI, APIRouter, HTTPException
from pydantic import BaseModel
import torch
import psutil
import time
from typing import Dict, Any, Optional

app = FastAPI()
health_router = APIRouter()

class HealthResponse(BaseModel):
    status: str
    timestamp: str
    components: Dict[str, Any]
    metrics: Dict[str, float]

class ComponentStatus(BaseModel):
    status: str
    details: Optional[str] = None
    last_check: str

# 全局变量,存储健康状态
service_components = {
    "vllm_engine": {"status": "unknown", "details": None, "last_check": ""},
    "gpu_memory": {"status": "unknown", "details": None, "last_check": ""},
    "model_loaded": {"status": "unknown", "details": None, "last_check": ""},
    "api_server": {"status": "unknown", "details": None, "last_check": ""}
}

def check_vllm_engine() -> ComponentStatus:
    """检查vLLM推理引擎状态"""
    try:
        # 这里需要根据你的实际vLLM实例来检查
        # 假设我们有一个全局的llm_engine对象
        from vllm import LLMEngine
        global llm_engine
        
        if llm_engine is None:
            return ComponentStatus(
                status="error",
                details="vLLM engine not initialized",
                last_check=time.strftime("%Y-%m-%d %H:%M:%S")
            )
        
        # 简单的引擎状态检查
        engine_info = llm_engine.get_engine_info()
        if engine_info.get("is_ready", False):
            return ComponentStatus(
                status="healthy",
                details=f"Engine ready, model: {engine_info.get('model_name', 'unknown')}",
                last_check=time.strftime("%Y-%m-%d %H:%M:%S")
            )
        else:
            return ComponentStatus(
                status="degraded",
                details="Engine not ready",
                last_check=time.strftime("%Y-%m-%d %H:%M:%S")
            )
            
    except Exception as e:
        return ComponentStatus(
            status="error",
            details=f"Engine check failed: {str(e)}",
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )

def check_gpu_memory() -> ComponentStatus:
    """检查GPU显存状态"""
    try:
        if not torch.cuda.is_available():
            return ComponentStatus(
                status="error",
                details="CUDA not available",
                last_check=time.strftime("%Y-%m-%d %H:%M:%S")
            )
        
        # 获取GPU信息
        gpu_count = torch.cuda.device_count()
        if gpu_count == 0:
            return ComponentStatus(
                status="error",
                details="No GPU found",
                last_check=time.strftime("%Y-%m-%d %H:%M:%S")
            )
        
        gpu_info = []
        for i in range(gpu_count):
            props = torch.cuda.get_device_properties(i)
            total_memory = props.total_memory / (1024**3)  # 转换为GB
            allocated = torch.cuda.memory_allocated(i) / (1024**3)
            cached = torch.cuda.memory_reserved(i) / (1024**3)
            
            gpu_info.append({
                "id": i,
                "name": props.name,
                "total_gb": round(total_memory, 2),
                "allocated_gb": round(allocated, 2),
                "cached_gb": round(cached, 2),
                "free_gb": round(total_memory - allocated - cached, 2)
            })
        
        # 检查显存使用率
        memory_status = "healthy"
        details = f"{gpu_count} GPU(s) available"
        
        for gpu in gpu_info:
            if gpu["free_gb"] < 2:  # 如果显存少于2GB
                memory_status = "degraded"
                details = f"GPU {gpu['id']} low memory: {gpu['free_gb']}GB free"
                break
        
        return ComponentStatus(
            status=memory_status,
            details=details,
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )
        
    except Exception as e:
        return ComponentStatus(
            status="error",
            details=f"GPU check failed: {str(e)}",
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )

def check_model_loaded() -> ComponentStatus:
    """检查模型是否成功加载"""
    try:
        # 这里需要根据你的实际模型加载状态来检查
        # 假设我们有一个全局的model_loaded标志
        global model_loaded, model_name
        
        if not model_loaded:
            return ComponentStatus(
                status="error",
                details="Model not loaded",
                last_check=time.strftime("%Y-%m-%d %H:%M:%S")
            )
        
        return ComponentStatus(
            status="healthy",
            details=f"Model '{model_name}' loaded successfully",
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )
        
    except Exception as e:
        return ComponentStatus(
            status="error",
            details=f"Model check failed: {str(e)}",
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )

@health_router.get("/health", response_model=HealthResponse)
async def health_check():
    """综合健康检查端点"""
    # 检查各个组件
    components = {}
    
    # 检查vLLM引擎
    vllm_status = check_vllm_engine()
    components["vllm_engine"] = vllm_status.dict()
    
    # 检查GPU显存
    gpu_status = check_gpu_memory()
    components["gpu_memory"] = gpu_status.dict()
    
    # 检查模型加载
    model_status = check_model_loaded()
    components["model_loaded"] = model_status.dict()
    
    # 检查API服务器(自身)
    components["api_server"] = ComponentStatus(
        status="healthy",
        details="API server is running",
        last_check=time.strftime("%Y-%m-%d %H:%M:%S")
    ).dict()
    
    # 收集系统指标
    metrics = {
        "cpu_percent": psutil.cpu_percent(interval=0.1),
        "memory_percent": psutil.virtual_memory().percent,
        "timestamp": time.time()
    }
    
    # 如果有GPU,添加GPU指标
    if torch.cuda.is_available():
        for i in range(torch.cuda.device_count()):
            metrics[f"gpu_{i}_utilization"] = torch.cuda.utilization(i) if hasattr(torch.cuda, 'utilization') else 0
            metrics[f"gpu_{i}_temperature"] = torch.cuda.temperature(i) if hasattr(torch.cuda, 'temperature') else 0
    
    # 判断整体状态
    all_healthy = all(comp["status"] == "healthy" for comp in components.values())
    any_error = any(comp["status"] == "error" for comp in components.values())
    
    overall_status = "healthy"
    if any_error:
        overall_status = "unhealthy"
    elif not all_healthy:
        overall_status = "degraded"
    
    return HealthResponse(
        status=overall_status,
        timestamp=time.strftime("%Y-%m-%d %H:%M:%S"),
        components=components,
        metrics=metrics
    )

@health_router.get("/health/liveness")
async def liveness_probe():
    """存活检查 - 最简单的检查"""
    return {"status": "alive", "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")}

@health_router.get("/health/readiness")
async def readiness_probe():
    """就绪检查 - 检查服务是否准备好接收请求"""
    # 简单检查模型是否加载
    global model_loaded
    if model_loaded:
        return {"status": "ready", "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")}
    else:
        return {"status": "not_ready", "timestamp": time.strftime("%Y-%m-%d %H:%M:%S")}

# 注册路由
app.include_router(health_router, prefix="/api")

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8080)

这个健康检查接口提供了三个端点:

  • /api/health:完整的健康检查,返回所有组件的状态
  • /api/health/liveness:存活检查,只检查进程是否在运行
  • /api/health/readiness:就绪检查,检查服务是否准备好接收请求

5. K8s集成:配置探针与监控

有了健康检查接口,我们现在需要告诉K8s怎么使用它。这主要通过配置探针(Probe)来实现。

5.1 更新Deployment配置

修改之前的Deployment,添加健康检查探针:

# gpt-oss-deployment-with-probes.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: gpt-oss-20b
  namespace: ai-services
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gpt-oss-20b
  template:
    metadata:
      labels:
        app: gpt-oss-20b
    spec:
      containers:
      - name: gpt-oss-container
        image: your-registry/gpt-oss-20b-webui:latest
        resources:
          limits:
            nvidia.com/gpu: 2
            memory: "64Gi"
            cpu: "8"
          requests:
            nvidia.com/gpu: 2
            memory: "32Gi"
            cpu: "4"
        ports:
        - containerPort: 7860  # WebUI
        - containerPort: 8000  # vLLM API
        - containerPort: 8080  # 健康检查端口
        env:
        - name: MODEL_NAME
          value: "gpt-oss-20b"
        - name: GPU_MEMORY_UTILIZATION
          value: "0.9"
        
        # 存活探针 - 检查容器是否还在运行
        livenessProbe:
          httpGet:
            path: /api/health/liveness
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 60  # 给容器60秒启动时间
          periodSeconds: 30  # 每30秒检查一次
          timeoutSeconds: 5  # 5秒超时
          failureThreshold: 3  # 连续失败3次才认为不健康
          successThreshold: 1  # 成功1次就认为健康
        
        # 就绪探针 - 检查服务是否准备好接收流量
        readinessProbe:
          httpGet:
            path: /api/health/readiness
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 90  # 模型加载需要时间,给90秒
          periodSeconds: 20  # 每20秒检查一次
          timeoutSeconds: 3  # 3秒超时
          failureThreshold: 2  # 连续失败2次就认为没准备好
          successThreshold: 1
        
        # 启动探针 - 检查应用是否启动完成
        startupProbe:
          httpGet:
            path: /api/health/liveness
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10  # 启动后10秒开始检查
          periodSeconds: 10  # 每10秒检查一次
          timeoutSeconds: 5
          failureThreshold: 30  # 最多尝试30次(5分钟)
          successThreshold: 1
        
        # 生命周期钩子
        lifecycle:
          preStop:
            exec:
              command: ["/bin/sh", "-c", "echo 'Gracefully shutting down...' && sleep 10"]

5.2 探针配置详解

让我解释一下这些配置的含义:

存活探针(livenessProbe)

  • initialDelaySeconds: 60:容器启动后等60秒再开始检查,给服务启动时间
  • periodSeconds: 30:每30秒检查一次
  • failureThreshold: 3:连续3次检查失败,K8s会重启容器
  • 作用:当服务卡死或无响应时,自动重启

就绪探针(readinessProbe)

  • initialDelaySeconds: 90:给模型加载更多时间(20B模型加载较慢)
  • periodSeconds: 20:每20秒检查一次
  • failureThreshold: 2:连续2次失败,就从Service的端点列表中移除
  • 作用:确保只有完全准备好的Pod才接收流量

启动探针(startupProbe)

  • failureThreshold: 30:最多尝试30次,总共300秒(5分钟)
  • 作用:给大型模型足够的启动时间,避免在启动过程中被误杀

5.3 添加监控指标

除了健康检查,我们还可以添加Prometheus监控指标。首先,在健康检查服务中暴露指标:

# metrics.py
from prometheus_client import Counter, Gauge, Histogram, generate_latest, REGISTRY
from fastapi import Response
import time

# 定义指标
REQUEST_COUNT = Counter(
    'http_requests_total',
    'Total HTTP requests',
    ['method', 'endpoint', 'status']
)

REQUEST_LATENCY = Histogram(
    'http_request_duration_seconds',
    'HTTP request latency',
    ['method', 'endpoint']
)

GPU_MEMORY_USAGE = Gauge(
    'gpu_memory_usage_bytes',
    'GPU memory usage in bytes',
    ['gpu_id']
)

MODEL_INFERENCE_LATENCY = Histogram(
    'model_inference_duration_seconds',
    'Model inference latency'
)

# 在健康检查路由中添加指标端点
@health_router.get("/metrics")
async def metrics():
    """Prometheus指标端点"""
    return Response(generate_latest(REGISTRY), media_type="text/plain")

# 在推理请求中添加指标收集
def track_inference_metrics(func):
    """装饰器:跟踪推理指标"""
    async def wrapper(*args, **kwargs):
        start_time = time.time()
        try:
            result = await func(*args, **kwargs)
            REQUEST_COUNT.labels(
                method="POST",
                endpoint="/v1/completions",
                status="200"
            ).inc()
            REQUEST_LATENCY.labels(
                method="POST",
                endpoint="/v1/completions"
            ).observe(time.time() - start_time)
            return result
        except Exception as e:
            REQUEST_COUNT.labels(
                method="POST",
                endpoint="/v1/completions",
                status="500"
            ).inc()
            raise e
    return wrapper

然后,创建ServiceMonitor让Prometheus自动发现:

# servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: gpt-oss-monitor
  namespace: ai-services
spec:
  selector:
    matchLabels:
      app: gpt-oss-20b
  endpoints:
  - port: metrics  # 需要先在Service中定义这个端口
    interval: 30s
    path: /api/metrics

6. 实战:从部署到监控的全流程

现在,让我们把所有的部分组合起来,走一遍完整的流程。

6.1 完整部署步骤

  1. 准备Docker镜像
# Dockerfile
FROM pytorch/pytorch:2.1.0-cuda12.1-cudnn8-runtime

# 安装依赖
RUN pip install vllm fastapi uvicorn prometheus-client psutil

# 复制代码
COPY . /app
WORKDIR /app

# 健康检查服务
COPY health_check.py /app/health_check.py
COPY metrics.py /app/metrics.py

# 启动脚本
COPY start.sh /app/start.sh
RUN chmod +x /app/start.sh

CMD ["/app/start.sh"]
# start.sh
#!/bin/bash

# 启动vLLM推理服务
python -m vllm.entrypoints.openai.api_server \
  --model gpt-oss-20b \
  --host 0.0.0.0 \
  --port 8000 \
  --gpu-memory-utilization 0.9 \
  --served-model-name gpt-oss-20b &

# 等待vLLM服务启动
sleep 30

# 启动健康检查服务
python health_check.py &

# 等待健康检查服务启动
sleep 5

# 启动WebUI(如果有)
# python webui.py &

# 等待所有子进程
wait
  1. 构建并推送镜像
docker build -t your-registry/gpt-oss-20b-webui:latest .
docker push your-registry/gpt-oss-20b-webui:latest
  1. 部署到K8s
# 创建命名空间
kubectl create namespace ai-services

# 部署应用
kubectl apply -f gpt-oss-deployment-with-probes.yaml -n ai-services
kubectl apply -f gpt-oss-service.yaml -n ai-services

# 部署监控(如果使用Prometheus Operator)
kubectl apply -f servicemonitor.yaml -n ai-services

6.2 验证健康检查

部署完成后,验证健康检查是否正常工作:

# 获取Pod IP
POD_IP=$(kubectl get pod -n ai-services -l app=gpt-oss-20b -o jsonpath='{.items[0].status.podIP}')

# 测试存活检查
curl http://$POD_IP:8080/api/health/liveness
# 预期返回:{"status": "alive", "timestamp": "..."}

# 测试就绪检查
curl http://$POD_IP:8080/api/health/readiness
# 预期返回:{"status": "ready", "timestamp": "..."}

# 测试完整健康检查
curl http://$POD_IP:8080/api/health
# 预期返回完整的健康状态信息

# 测试指标端点
curl http://$POD_IP:8080/api/metrics
# 预期返回Prometheus格式的指标

6.3 查看Pod状态

# 查看Pod详情,关注健康检查状态
kubectl describe pod -n ai-services -l app=gpt-oss-20b

# 查看Pod事件
kubectl get events -n ai-services --field-selector involvedObject.name=<pod-name>

# 查看日志
kubectl logs -f -n ai-services -l app=gpt-oss-20b -c gpt-oss-container

你应该能看到类似这样的输出:

Containers:
  gpt-oss-container:
    State:          Running
    Ready:          True
    Restart Count:  0
    Liveness:       http-get http://:8080/api/health/liveness delay=60s timeout=5s period=30s #success=1 #failure=3
    Readiness:      http-get http://:8080/api/health/readiness delay=90s timeout=3s period=20s #success=1 #failure=2
    Startup:        http-get http://:8080/api/health/liveness delay=10s timeout=5s period=10s #success=1 #failure=30

6.4 模拟故障测试

让我们测试一下健康检查的故障恢复能力:

  1. 模拟服务卡死
# 进入Pod执行命令
kubectl exec -it -n ai-services <pod-name> -- /bin/bash

# 在容器内杀死健康检查服务(模拟故障)
pkill -f "python health_check.py"

# 退出容器
exit

等待一段时间(最多90秒),然后检查Pod状态:

kubectl get pods -n ai-services -l app=gpt-oss-20b -w

你应该能看到Pod重启(因为存活检查失败)。

  1. 模拟模型加载失败: 修改健康检查代码,模拟模型加载失败:
# 在健康检查服务中临时修改
model_loaded = False  # 模拟模型加载失败

等待就绪检查失败,然后检查Service的端点:

kubectl describe service gpt-oss-service -n ai-services

你应该能看到Pod从端点列表中移除。

7. 高级配置与优化建议

基本的健康检查已经能工作了,但我们可以做得更好。这里有一些高级配置和优化建议。

7.1 自定义健康检查逻辑

根据你的具体需求,可以定制更复杂的健康检查逻辑:

def check_inference_performance() -> ComponentStatus:
    """检查推理性能"""
    try:
        # 测试推理延迟
        test_prompt = "The quick brown fox"
        start_time = time.time()
        
        # 这里调用实际的推理接口
        # result = llm_engine.generate(test_prompt, max_tokens=10)
        inference_time = time.time() - start_time
        
        if inference_time < 1.0:  # 1秒内完成
            status = "healthy"
            details = f"Inference latency: {inference_time:.2f}s"
        elif inference_time < 3.0:
            status = "degraded"
            details = f"High inference latency: {inference_time:.2f}s"
        else:
            status = "error"
            details = f"Very high inference latency: {inference_time:.2f}s"
            
        return ComponentStatus(
            status=status,
            details=details,
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )
        
    except Exception as e:
        return ComponentStatus(
            status="error",
            details=f"Inference check failed: {str(e)}",
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )

def check_concurrent_requests() -> ComponentStatus:
    """检查并发处理能力"""
    try:
        # 获取当前活跃请求数
        # active_requests = get_active_requests_count()
        active_requests = 0  # 这里需要根据实际情况获取
        
        max_concurrent = 10  # 假设最大并发数为10
        
        if active_requests < max_concurrent * 0.7:  # 使用率低于70%
            status = "healthy"
            details = f"Active requests: {active_requests}/{max_concurrent}"
        elif active_requests < max_concurrent:
            status = "degraded"
            details = f"High load: {active_requests}/{max_concurrent} requests"
        else:
            status = "error"
            details = f"At capacity: {active_requests}/{max_concurrent} requests"
            
        return ComponentStatus(
            status=status,
            details=details,
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )
        
    except Exception as e:
        return ComponentStatus(
            status="error",
            details=f"Concurrency check failed: {str(e)}",
            last_check=time.strftime("%Y-%m-%d %H:%M:%S")
        )

7.2 配置资源请求与限制

合理的资源配置可以避免很多问题:

resources:
  limits:
    nvidia.com/gpu: 2
    memory: "64Gi"
    cpu: "8"
    ephemeral-storage: "100Gi"  # 临时存储限制
  requests:
    nvidia.com/gpu: 2
    memory: "48Gi"  # 比limit少一些,给系统留空间
    cpu: "4"
    ephemeral-storage: "50Gi"

7.3 配置Pod反亲和性

避免所有Pod调度到同一个节点:

affinity:
  podAntiAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    - weight: 100
      podAffinityTerm:
        labelSelector:
          matchExpressions:
          - key: app
            operator: In
            values:
            - gpt-oss-20b
        topologyKey: kubernetes.io/hostname

7.4 配置HPA(水平自动扩缩)

根据CPU或自定义指标自动扩缩:

# hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: gpt-oss-hpa
  namespace: ai-services
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: gpt-oss-20b
  minReplicas: 1
  maxReplicas: 3
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: 10

7.5 配置PDB(Pod中断预算)

确保至少有一个Pod可用:

# pdb.yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: gpt-oss-pdb
  namespace: ai-services
spec:
  minAvailable: 1
  selector:
    matchLabels:
      app: gpt-oss-20b

8. 总结

通过这篇文章,我们完成了GPT-OSS-20B模型在Kubernetes上的健康检查接口集成。让我们回顾一下关键点:

8.1 核心收获

  1. 健康检查的必要性:对于大模型服务,健康检查不是可选项,而是必选项。它能帮你提前发现问题,避免服务中断影响用户。

  2. 三层健康检查体系

    • 存活检查:确保服务进程正常运行
    • 就绪检查:确保服务准备好接收请求
    • 深度检查:全面检查各个组件状态
  3. K8s探针配置:正确配置livenessProbereadinessProbestartupProbe,让K8s能自动管理服务生命周期。

  4. 监控集成:通过Prometheus指标暴露,实现全方位的监控告警。

8.2 实际效果

部署了健康检查后,你会获得:

  • 自动故障恢复:服务卡死时自动重启
  • 流量智能路由:只有健康的Pod才接收流量
  • 状态实时可见:随时了解服务健康状况
  • 预警能力:在问题影响用户前提前发现

8.3 后续建议

  1. 告警配置:基于健康检查指标配置告警,比如:

    • GPU显存使用率超过90%
    • 推理延迟超过2秒
    • 健康检查连续失败
  2. 日志聚合:使用ELK或Loki收集和分析日志,方便排查问题。

  3. 性能优化:根据监控数据优化资源配置,比如调整GPU内存利用率、批处理大小等。

  4. 多环境部署:在开发、测试、生产环境都部署健康检查,确保一致性。

8.4 最后的话

部署大模型服务就像养一只珍贵的宠物——你不能只是把它放在那里就不管了。你需要定期检查它的健康状况,确保它吃得好、睡得好、跑得快。健康检查就是你的“宠物监控摄像头”,让你随时知道它的状态。

现在,你的GPT-OSS-20B服务已经装上了这个“监控摄像头”。当它生病时,你会第一时间知道;当它饿的时候,你会及时喂食;当它跑不动时,你会帮它恢复活力。

记住,一个好的部署不是“部署完就结束”,而是“部署完才开始”。健康检查让你从这个“开始”就站在了更高的起点上。


获取更多AI镜像

想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,支持一键部署。

更多推荐