两节点异构裸机实战教程(从0部署):Kubernetes + Flyte + Ray + KubeRay 基于 NVIDIA Time-Slicing 实现 4 Pod 并发 GPU 验证
2026/5/31 2:28:30 网站建设 项目流程

下面给出一版从零开始、面向小白、基于 NVIDIA Time-Slicing 的两节点异构裸机实战教程。我保留了你给的 CSDN 参考文章的“部署条件 → 目标架构 → 步骤编号 → 〖需要执行〗/〖验证〗”风格;区别是:这里不使用 MIG,而是把 Node-2 上的 1 张物理 GPU 通过 Time-Slicing 暴露成 4 个共享 GPU 资源,实现4 个 GPU Pod 并发验证。参考文章本身采用 Node-1192.168.1.41、Node-2192.168.1.42的两节点裸机 Kubernetes + Flyte + Ray + KubeRay 架构,本教程沿用这个节点规划。(CSDN)


两节点异构裸机实战教程:Kubernetes + Flyte + Ray + KubeRay 基于 NVIDIA Time-Slicing 实现 4 Pod 并发 GPU 验证

部署条件:

Node-1: 主机名:node-1 内网 IP:192.168.1.41 CPU:88 核 内存:64G GPU:无 Pod CPU 约束:最少 4 核,最多 11 核 Node-2: 主机名:node-2 内网 IP:192.168.1.42 CPU:256 核 内存:64G GPU:RTX PRO 6000 96G GPU 共享方案:NVIDIA Time-Slicing Time-Slicing 副本数:4 目标效果:1 张物理 GPU 暴露为 4 个 nvidia.com/gpu.shared 资源 Pod CPU 约束:最少 4 核,最多 32 核 Kubernetes: 使用标准 kubeadm Kubernetes 不使用 K3s 操作系统: Ubuntu 22.04.5 LTS Codename:jammy

Time-Slicing 和 MIG 的核心区别:

MIG: 真的把 GPU 硬件资源切成多个隔离实例 显存、计算资源、故障域都有更强隔离 Time-Slicing: 不切硬件 不隔离显存 不隔离故障域 多个 Pod 轮流共享同一张物理 GPU 适合学习、开发、轻量推理、多实验并发

NVIDIA 官方文档说明,GPU Time-Slicing 通过 ConfigMap 配置replicas,例如replicas: 4会让 GPU 资源被超额订阅;当renameByDefault=true时,节点会暴露nvidia.com/gpu.shared,其容量等于物理 GPU 数量 × 副本数。Time-Slicing 不是显存切分方案,NVIDIA device plugin 文档也明确说明,Time-Slicing 不会为共享同一 GPU 的 workload 做显存或故障隔离。(NVIDIA Docs)


1. 最终目标架构

用户 / 浏览器 / flytectl / pyflyte | v Node-1: 192.168.1.41 - Kubernetes Control Plane - etcd - kube-apiserver - kube-controller-manager - kube-scheduler - containerd - kubelet - Flyte - PostgreSQL - MinIO - KubeRay Operator - Ray Head Pod - Ray CPU Worker Pods Node-2: 192.168.1.42 - Kubernetes Worker - containerd - kubelet - NVIDIA GPU Operator - NVIDIA Device Plugin - NVIDIA Container Toolkit - 1 × RTX PRO 6000 96G - Time-Slicing:replicas = 4 - 暴露资源:nvidia.com/gpu.shared = 4 - Ray GPU Worker Pods - GPU 验证 Pods

逻辑图:

Flyte Workflow | v Flyte Ray Task | v KubeRay Operator | v RayCluster | +-- Ray Head Pod -> Node-1 / 192.168.1.41 +-- CPU Worker Pods -> Node-1 / 192.168.1.41 +-- GPU Shared Worker Pods -> Node-2 / 192.168.1.42 申请 nvidia.com/gpu.shared: 1

Time-Slicing 后的 GPU 逻辑图:

Node-2 / 192.168.1.42 物理 GPU: RTX PRO 6000 96G | v NVIDIA Time-Slicing | +-- nvidia.com/gpu.shared #1 -> Pod-1 +-- nvidia.com/gpu.shared #2 -> Pod-2 +-- nvidia.com/gpu.shared #3 -> Pod-3 +-- nvidia.com/gpu.shared #4 -> Pod-4

注意:

这不是 4 张独立 GPU 这不是 4 个 24G 显存分区 这是 4 个 Kubernetes 可调度的共享 GPU 入口 4 个 Pod 共享同一张 96G 显存的物理 GPU

2. 三个系统分别负责什么

2.1 Kubernetes 负责“资源调度”

Kubernetes 负责:

创建 Pod 把 Pod 放到 Node-1 或 Node-2 管理 CPU / 内存 / GPU 资源 管理 Service / DNS 管理 Namespace 管理 PVC / PV 管理 nodeSelector / taint / toleration 管理 CRD / Operator

本教程使用:

kubeadm kubelet kubectl containerd

Kubernetes 官方 kubeadm 安装文档目前按 v1.36 给出 Debian/Ubuntu 仓库安装方式;如果后续版本变化,把文中的v1.36替换成你实际要安装的稳定版本即可。containerd 与 kubelet 的 cgroup driver 应保持一致,Kubernetes 文档也建议 kubelet 使用 systemd 时,容器运行时也配置 systemd cgroup。(Kubernetes)


2.2 NVIDIA GPU Operator 负责“让 Kubernetes 认识 GPU”

GPU Operator 负责:

NVIDIA Driver NVIDIA Container Toolkit NVIDIA Device Plugin GPU Feature Discovery DCGM Exporter GPU Operator Validator

在 Time-Slicing 方案里,关键组件是:

NVIDIA Device Plugin GPU Feature Discovery GPU Operator ClusterPolicy Time-Slicing ConfigMap

NVIDIA GPU Operator 官方文档给出的 Time-Slicing 配置流程是:创建 ConfigMap、让 ClusterPolicy 中的 device plugin 使用该 ConfigMap、再给目标节点打nvidia.com/device-plugin.config=<配置名>标签。(NVIDIA Docs)


2.3 Ray 负责“分布式计算”

Ray 负责:

一个大任务拆成多个小任务 多个 CPU worker 并行处理 多个 GPU worker 并行训练 / 推理 运行 Ray Data 运行 Ray Train 运行 Ray Tune 运行 Ray Serve

KubeRay 提供:

RayCluster RayJob RayService

Ray 官方文档说明,KubeRay 使用 CRD 管理 RayCluster / RayJob / RayService;RayCluster 适合开发和常驻集群,RayJob 可以自动创建 RayCluster、提交任务并在任务完成后删除集群。(Ray)


2.4 Flyte 负责“工作流编排”

Flyte 负责:

定义 task 定义 workflow 管理 task 依赖关系 管理输入输出 失败重试 缓存 版本管理 执行记录 把 Ray task 交给 KubeRay 执行

Flyte 的 Ray 插件可以在 Kubernetes 上原生运行 Ray job,并为每个 task execution 创建临时 Ray 集群,任务完成后再清理;这适合把“数据准备 → Ray 并行计算 → GPU 推理/训练 → 保存结果”做成可追踪 workflow。(Union)


3. IP 与主机规划

节点主机名IP角色
Node-1node-1192.168.1.41Kubernetes control-plane + worker
Node-2node-2192.168.1.42Kubernetes worker + GPU Time-Slicing

两台机器都修改/etc/hosts

sudotee-a/etc/hosts<<EOF 192.168.1.41 node-1 192.168.1.42 node-2 EOF

设置主机名:

# 在 192.168.1.41 上执行sudohostnamectl set-hostname node-1# 在 192.168.1.42 上执行sudohostnamectl set-hostname node-2

验证:

hostnamecat/etc/hosts

期望:

Node-1 显示 node-1 Node-2 显示 node-2 两台机器都能 ping 通 node-1 和 node-2

4. 重要网络规划

你的机器内网是:

192.168.1.0/24

所以 Kubernetes Pod 网段不要使用:

192.168.0.0/16

否则可能和物理内网冲突。

推荐:

Pod CIDR:10.244.0.0/16 Service CIDR:10.96.0.0/12 Node CIDR:192.168.1.0/24

最终:

物理节点 IP: node-1 = 192.168.1.41 node-2 = 192.168.1.42 Kubernetes Pod IP: 10.244.x.x Kubernetes Service IP: 10.96.x.x

Calico 支持 VXLAN Overlay 网络,用于在底层网络不直接感知 Pod IP 的场景下转发 Pod 流量;本教程用 VXLAN 简化两节点裸机环境的网络配置。(Calico 文档)


5. 部署顺序总览

完整顺序如下:

1. 两台 Ubuntu 基础准备 2. 安装 containerd 3. 安装 kubeadm / kubelet / kubectl 4. Node-1 初始化 Kubernetes 控制面 5. 安装 Calico CNI 6. 允许 Node-1 调度业务 Pod 7. Node-2 加入集群 8. 设置节点标签和污点 9. 安装 Helm 10. 安装 NVIDIA GPU Operator 11. 配置 NVIDIA Time-Slicing:replicas = 4 12. 验证 node-2 暴露 nvidia.com/gpu.shared = 4 13. 直接创建 4 个 GPU Pod 并发验证 14. 安装 KubeRay Operator 15. 部署 RayCluster 学习示例 16. 用 Ray 验证 4 个 GPU task 并发 17. 部署 PostgreSQL / MinIO 18. 部署 Flyte 19. 配置 Flyte workload namespace 20. 测试 Flyte + Ray + Time-Slicing GPU 任务

6. 两台机器基础准备

以下命令两台机器都执行。

lsb_release-auname-r

期望:

Ubuntu 22.04.5 LTS Codename: jammy

安装基础依赖:

sudoaptupdatesudoaptinstall-y\curlwgetvimgitjqhtopnet-tools iproute2 pciutils build-essential\apt-transport-https ca-certificates gnupg lsb-release\linux-headers-$(uname-r)\software-properties-common

关闭 swap:

sudoswapoff-asudosed-i'/ swap / s/^/#/'/etc/fstab

加载内核模块:

sudomodprobe overlaysudomodprobe br_netfiltersudotee/etc/modules-load.d/k8s.conf<<EOF overlay br_netfilter EOF

配置 sysctl:

sudotee/etc/sysctl.d/k8s.conf<<EOF net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOFsudosysctl--system

验证:

lsmod|grep-E'overlay|br_netfilter'sysctlnet.ipv4.ip_forward

期望:

net.ipv4.ip_forward = 1

7. 安装 containerd

两台机器都执行:

sudoaptupdatesudoaptinstall-ycontainerdsudomkdir-p/etc/containerd containerd config default|sudotee/etc/containerd/config.toml>/dev/null

启用 systemd cgroup:

sudosed-i's/SystemdCgroup = false/SystemdCgroup = true/'/etc/containerd/config.toml

重启 containerd:

sudosystemctl restart containerdsudosystemctlenablecontainerdsudosystemctl status containerd --no-pager

验证:

containerd--versiongrepSystemdCgroup /etc/containerd/config.toml

期望:

SystemdCgroup = true

8. 安装 kubeadm / kubelet / kubectl

两台机器都执行。这里以 Kubernetes v1.36 为例:

sudoapt-getupdatesudoapt-getinstall-yapt-transport-https ca-certificatescurlgpgsudomkdir-p-m755/etc/apt/keyringscurl-fsSLhttps://pkgs.k8s.io/core:/stable:/v1.36/deb/Release.key\|sudogpg--dearmor-o/etc/apt/keyrings/kubernetes-apt-keyring.gpgecho'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.36/deb/ /'\|sudotee/etc/apt/sources.list.d/kubernetes.listsudoapt-getupdatesudoapt-getinstall-ykubelet kubeadm kubectlsudoapt-mark hold kubelet kubeadm kubectl

启用 kubelet:

sudosystemctlenable--nowkubelet

检查:

kubeadm version kubelet--versionkubectl version--client

9. Node-1 初始化标准 Kubernetes 控制面

只在 Node-1:192.168.1.41上执行:

sudokubeadm init\--apiserver-advertise-address=192.168.1.41\--control-plane-endpoint=192.168.1.41:6443\--pod-network-cidr=10.244.0.0/16\--service-cidr=10.96.0.0/12\--cri-socket=unix:///run/containerd/containerd.sock

配置 kubectl:

mkdir-p

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询