基于K8s的云原生AI基础设施:架构、部署与实践【014】-AI算力的多机协同(下)

7. 安装 LeaderWorkerSet 控制器

LWS 本身需要先安装控制器和 CRD。本文实践中使用 Helm 安装。

CHART_VERSION=0.7.0
mkdir -p ~/lws-offline

helm pull oci://registry.k8s.io/lws/charts/lws 
  --version $CHART_VERSION 
  --destination ~/lws-offline

tar -zxvf lws-0.7.0.tgz

helm install lws ./ 
  --namespace lws-system 
  --create-namespace 
  --wait --timeout 300s

 

安装完成后检查控制器,正常情况下可以看到:

kubectl get pods -n lws-system
NAME                                      READY   STATUS
lws-controller-manager-xxxxxxxxx-xxxxx    1/1     Running

 

继续检查 CRD 是否注册成功,如果看到如下的结果,说明 LWS API 已经注册到 Kubernetes 中,可以开始创建 LeaderWorkerSet 资源。

kubectl get crd | grep leaderworkerset
leaderworkersets.leaderworkerset.x-k8s.io
kubectl api-resources | grep -i leader
leaderworkersets   lws   leaderworkerset.x-k8s.io/v1   true   LeaderWorkerSet

 


8. 部署基于 LWS 的 vLLM 多机推理服务

在本文实践中,使用 LeaderWorkerSet 部署一个基于 Ray + vLLM 的 Qwen3-32B 多机推理服务。

核心 YAML 结构如下:

apiVersion: leaderworkerset.x-k8s.io/v1
kind: LeaderWorkerSet
metadata:
  name: vllm
spec:
  replicas: 1
  leaderWorkerTemplate:
    size: 6
    restartPolicy: RecreateGroupOnPodRestart
    leaderTemplate:
      metadata:
        labels:
          role: leader
      spec:
        containers:
        - name: vllm-leader
          image: 10.8.17.100:60066/model/vllm:202511260714
          command:
          - sh
          - -c
          - |
            bash /workspace/multi-node-serving.sh leader --ray_cluster_size=$(LWS_GROUP_SIZE);
            /opt/conda/bin/python3 -m vllm.entrypoints.openai.api_server 
              --port 8080 
              --model /workspace/model/Qwen3-32B 
              --tensor-parallel-size 4 
              --pipeline_parallel_size 1
          resources:
            limits:
              mars-tech.com/gpu: 4
              memory: 96Gi
              ephemeral-storage: 50Gi
            requests:
              mars-tech.com/gpu: 4
              cpu: 16
              memory: 96Gi
              ephemeral-storage: 50Gi
          ports:
          - containerPort: 8080
          volumeMounts:
          - mountPath: /dev/shm
            name: dshm
          - mountPath: /workspace/model
            name: localmodelvolume
        volumes:
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: 15Gi
        - name: localmodelvolume
          persistentVolumeClaim:
            claimName: vllm-model-pvc

    workerTemplate:
      spec:
        containers:
        - name: vllm-worker
          image: 10.8.17.100:60066/model/vllm.202511260714
          command:
          - sh
          - -c
          - |
            bash /workspace/multi-node-serving.sh worker --ray_address=$(LWS_LEADER_ADDRESS)
          resources:
            limits:
              mars-tech.com/gpu: 4
              memory: 96Gi
              ephemeral-storage: 50Gi
            requests:
              mars-tech.com/gpu: 4
              cpu: 16
              memory: 96Gi
              ephemeral-storage: 50Gi
          volumeMounts:
          - mountPath: /dev/shm
            name: dshm
          - mountPath: /workspace/model
            name: localmodelvolume
        volumes:
        - name: dshm
          emptyDir:
            medium: Memory
            sizeLimit: 15Gi
        - name: localmodelvolume
          persistentVolumeClaim:
            claimName: vllm-model-pvc

 

同时创建一个 Service,只暴露 leader Pod:

apiVersion: v1
kind: Service
metadata:
  name: vllm-leader
spec:
  type: NodePort
  selector:
    leaderworkerset.sigs.k8s.io/name: vllm
    role: leader
  ports:
  - name: http
    port: 8080
    targetPort: 8080
    nodePort: 32064

 

这个 YAML 中有几个关键点。

replicas: 1 表示创建一个分布式推理 group。

leaderWorkerTemplate.size: 6 表示每个 group 中一共有 6 个 Pod,其中 1 个 leader,5 个 worker。

restartPolicy: RecreateGroupOnPodRestart 表示组内任意 Pod 重启时,整组会重建。这可以避免分布式推理组内部出现 leader / worker 状态不一致的问题。

leaderTemplate 定义 leader Pod,它负责启动 Ray head 和 vLLM API Server。

workerTemplate 定义 worker Pod,它负责连接 leader 的 Ray head 并作为 Ray worker 参与推理。

k8s.v1.cni.cncf.io/networks 是 Multus 网络注解,用于给 leader 和 worker 挂载额外网络。实际环境中,是否需要 Multus、macvlan 或 RDMA 网络,需要结合集群网络设计决定。

/dev/shm 使用 memory 类型的 emptyDir,是为了给推理进程提供更大的共享内存空间。

/workspace/model 挂载模型 PVC,保证 leader 和 worker 都能访问相同的模型文件。


9. 启动状态检查

应用 YAML 后,先检查 StatefulSet:

kubectl get statefulsets
NAME     READY   AGE
vllm     1/1     4h32m
vllm-0   5/5     3h38m

 

这里说明:

vllm:
  leader StatefulSet,负责 leader Pod

vllm-0:
  group 0  worker StatefulSet,负责 5  worker Pod

 

继续检查 Pod:

kubectl get pods -n default 
  -l leaderworkerset.sigs.k8s.io/name=vllm 
  -L role

 

返回结果类似:

NAME       READY   STATUS    ROLE
vllm-0     1/1     Running   leader
vllm-0-1   1/1     Running
vllm-0-2   1/1     Running
vllm-0-3   1/1     Running
vllm-0-4   1/1     Running
vllm-0-5   1/1     Running

 

这说明一个完整的 group 已经起来:

vllm-0      leader
vllm-0-1    worker
vllm-0-2    worker
vllm-0-3    worker
vllm-0-4    worker
vllm-0-5    worker

 

接下来查看 leader 日志:

kubectl logs vllm-0 -n default -c vllm-leader | tail -n 100

 

重点关注几类信息。

<span style="color: rgba(203, 145, 47, 1);"><strong># 通过日志查看详细的启动流程</strong></span>
kubectl logs vllm-0 -n default 
kubectl logs vllm-0 -n default -c vllm-leader | tail -n 80

# 关键信息
<span style="color: rgba(193, 76, 138, 1);"><strong>1.	Ray 集群已经拉起来并完成 worker 注册:
</strong></span>Wait for all ray workers to be active. 5/6 is active
2025-12-04 19:45:30,458 INFO worker.py:1694 -- Connecting to existing Ray cluster at address: 192.168.4.142:6379...
2025-12-04 19:45:30,474 INFO worker.py:1888 -- Connected to Ray cluster.<span style="color: rgba(193, 76, 138, 1);">
</span>All ray workers are active and the ray cluster is initialized successfully.

<span style="color: rgba(193, 76, 138, 1);"><strong>2.	vLLM OpenAI API 服务器也已经启动流程:
</strong></span>INFO ... vLLM API server version 0.8.5
INFO ... args: ... model='/workspace/model/Qwen3-32B' ...

<span style="color: rgba(193, 76, 138, 1);"><strong>3.	开始初始化 vLLM 引擎,并用这个本地模型:
</strong></span>INFO ... Initializing a V1 LLM engine ... model='/workspace/model/Qwen3-32B', tokenizer='/workspace/model/Qwen3-32B'
<span style="color: rgba(193, 76, 138, 1);"><strong>
4.	模型正在一点点从 PVC / NFS 里读出来并加载到 GPU:
</strong></span>INFO ... Starting to load model /workspace/model/Qwen3-32B...
Loading safetensors checkpoint shards:   6% Completed | 1/17 [00:27<07:13, 27.12s/it]

INFO ... Starting to load model /workspace/model/Qwen3-32B...
Loading safetensors checkpoint shards:  88% Completed | 15/17 [...]
Loading safetensors checkpoint shards: 100% Completed | 17/17 [...]
INFO ... Loading weights took 309.10 seconds
INFO ... Model loading took 61.0347 GiB and 309.859165 seconds

👉 说明 /workspace/model/Qwen3-32B 里的 17  model-000xx-of-00017.safetensors已经全部成功读到 GPU 里了,占用大约 61 GiB 显存。这一步完全成功。

<span style="color: rgba(193, 76, 138, 1);"><strong>5.  最后启动完成
</strong></span>INFO:     Started server process [8501]
INFO:     Waiting for application startup.
INFO:     Application startup complete.


# 检查statefulset,一个leader,一个worker
kubectl get statefulsets
NAME     READY   AGE
vllm     1/1     4h32m
vllm-0   5/5     3h38m

# 确认pod中哪个是leader pod
kubectl get pods -n default 
>   -l leaderworkerset.sigs.k8s.io/name=vllm 
>   -L role
NAME       READY   STATUS    RESTARTS   AGE     ROLE
vllm-0     1/1     Running   0          3h30m   leader
vllm-0-1   1/1     Running   0          3h30m   
vllm-0-2   1/1     Running   0          3h30m   
vllm-0-3   1/1     Running   0          3h30m   
vllm-0-4   1/1     Running   0          3h30m   
vllm-0-5   1/1     Running   0          3h30m   

 

第一,Ray worker 是否全部注册成功:

Wait for all ray workers to be active. 5/6 is active
Connected to Ray cluster.
All ray workers are active and the ray cluster is initialized successfully.

 

第二,vLLM API Server 是否开始启动:

vLLM API server version ...
Initializing a V1 LLM engine ...
model='/workspace/model/Qwen3-32B'

 

第三,模型权重是否成功加载:

Loading safetensors checkpoint shards: 100% Completed
Loading weights took 309.10 seconds
Model loading took 61.0347 GiB

 

第四,API Server 是否启动完成:

Started server process
Application startup complete.

 

这些日志说明,Ray 集群已经建立,worker 已经注册,模型已经从 PVC 加载,vLLM API Server 已经启动。至此,LWS + Ray + vLLM 的多机推理服务已经完成启动。


11. 接口验证

服务启动后,可以通过 NodePort 访问 leader 暴露的 OpenAI 兼容接口。先查看模型列表:

curl http://10.8.17.218:32064/v1/models

 

再调用 Chat Completions 接口:

curl -X POST http://10.8.17.218:32064/v1/chat/completions 
  -H "Content-Type: application/json" 
  -d '{
    "model": "/workspace/model/Qwen3-32B",
    "messages": [
      {
        "role": "user",
        "content": "你好,请简单自我介绍一下"
      }
    ]
  }'

 

如果能够正常返回模型输出,说明外部请求已经可以进入 leader,并由 vLLM 完成推理。在正式环境中,建议进一步通过 Gateway API 或 AI Gateway 暴露统一入口,而不是直接使用 NodePort。NodePort 更适合部署验证和内部调试。


10. 关于网络与 RDMA 的说明

在多机推理中,网络路径非常重要。但本小节只为介绍LWS,所以 YAML 中并未引入过多复杂的参数或环境变量,实际生产环境需要通过可能需要高速的RDMA网络。在具体的实践中,可以把网络分成两个层次理解。

第一层是 Ray 的控制和管理通信。Ray head 与 Ray workers 之间的注册、调度和管理通信通常基于 IP 网络进行。因此,Multus/macvlan 可以用于提供一张独立的高速业务网络,让 leader 和 worker 之间通过该网络互通。

第二层是模型并行相关的数据通信。如果 vLLM 的分布式推理涉及跨 GPU 或跨节点 collective communication,则底层可能涉及 NCCL 等通信库。是否使用 RDMA,不应该仅凭 YAML 中是否申请了 RDMA 资源来判断,而应该结合 NCCL 日志、网卡流量、RDMA counters、容器内 /dev/infiniband 可见性以及实际环境变量进行验证。


11. LWS 与 Ray 的关系

LWS 和 Ray 经常一起出现,但它们不是同一层东西。Ray 是分布式运行时。它负责 worker 管理、任务调度、分布式执行和运行时通信。对于 vLLM 多节点推理来说,Ray 可以作为 worker 组织和执行框架。LWS 是 Kubernetes 工作负载 API。它负责把一组 leader / worker Pod 作为一个整体部署、更新、重启和扩缩容。二者的关系可以理解为:

Kubernetes / LWS:
   Pod,管 group,管生命周期

Ray:
  管进程,管 worker,管分布式执行

vLLM:
  管模型,管推理,管 OpenAI API

 

换句话说,Ray 解决的是“组内怎么运行”,LWS 解决的是“这一组 Pod 在 Kubernetes 中怎么表达和管理”。如果没有 LWS,也可以手工用 StatefulSet、Service、脚本等方式拼出 Ray + vLLM 集群;但这种方式会让 group 生命周期、滚动更新、扩缩容和故障恢复变得更复杂。LWS 的价值,就是把这种常见分布式推理模式抽象成一个更清晰的 Kubernetes API。


12. 小结

LeaderWorkerSet 解决的是 Kubernetes 层面的工作负载表达问题,当一个模型副本不再是一个 Pod,而是一组必须协同工作的 Pod 时,Kubernetes 应该如何部署、更新、重启和扩缩这一组 Pod。对于多机推理来说,这一点非常关键。

LWS 将 leader 和 worker 组织成一个 group,使其具备统一生命周期;通过 scale subresource,让 HPA 可以按 group 数量扩缩容;通过 group-level rolling update,让模型服务可以按组滚动发布;通过 all-or-nothing restart,让分布式推理组在异常时重新恢复一致状态;通过 topology-aware placement,为后续更精细的拓扑放置提供能力基础。

在云原生 AI 平台中,随着模型规模从单机走向多机,工作负载的基本单位也在发生变化:

 Pod 推理
    Pod 协同推理

单副本 Deployment
   group 级推理副本

Pod 级扩缩容
   group 级扩缩容

Pod 级滚动更新
   group 级滚动更新

 

这也是 LWS 在 AI 基础设施中的价值所在。它让 Kubernetes 不再只是“运行很多 Pod”,而是能够以更贴近大模型推理实际形态的方式,管理一组协同工作的推理单元。

Leave a Reply