4. 环境搭建
训练任务编排与调度系统的底层依赖是稳定、可扩展的Kubernetes集群。本章将带领你从零搭建一套用于开发与测试的Kubernetes环境,并安装调度系统所需的容器运行时与关键调度组件。我们采用 kubeadm 作为集群初始化工具,因为它提供了生产级、可复现的安装路径,且便于后续版本升级与故障排查。
4.1 核心原理:集群组件与调度链路
在动手安装前,必须先理解Kubernetes调度系统运行所依赖的组件拓扑。训练任务通常以Pod形式运行,而调度器(kube-scheduler)负责将Pending状态的Pod分配到最合适的节点。调度器决策依赖三类信息:集群节点资源(CPU、内存、GPU)、Pod资源请求(requests/limits)以及自定义调度策略(如GPU显存、RDMA网卡)。
下图展示了训练任务从提交到运行的完整链路,以及各组件间的交互关系:
从图中可以看到,调度器并非直接与节点通信,而是通过 kube-apiserver 读取节点状态和Pod信息,并将调度结果写回etcd。因此,搭建环境时必须确保控制平面组件(apiserver、etcd、scheduler、controller-manager)与工作节点上的kubelet、容器运行时之间网络互通。
4.2 方法流程:基于kubeadm的集群安装
我们使用三台Ubuntu 22.04虚拟机(或裸机)作为实验环境:1台控制平面节点(4C/8G),2台工作节点(4C/16G,其中1台配置NVIDIA GPU)。所有节点需满足以下前置条件:
- 操作系统:Ubuntu 22.04 LTS,内核 ≥ 5.4
- 关闭swap:
swapoff -a并注释/etc/fstab中的swap行 - 加载内核模块:
overlay、br_netfilter - 设置iptables参数,确保流量正确转发
首先在所有节点上执行基础配置:
# 所有节点执行
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sudo sysctl --system
接下来安装容器运行时。我们选择 containerd 作为CRI实现,因为它轻量且与Kubernetes集成最紧密。安装并配置containerd:
# 安装containerd
sudo apt-get update
sudo apt-get install -y containerd
# 生成默认配置并修改SystemdCgroup
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
# 编辑config.toml,找到SystemdCgroup行并改为true
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
# 重启containerd
sudo systemctl restart containerd
sudo systemctl enable containerd
然后安装kubeadm、kubelet和kubectl。注意需要固定版本以保证兼容性,我们使用v1.28.2:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl gpg
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet=1.28.2-1.1 kubeadm=1.28.2-1.1 kubectl=1.28.2-1.1
sudo apt-mark hold kubelet kubeadm kubectl
在控制平面节点上初始化集群。初始化参数中需要指定Pod网络CIDR(我们使用Calico网络插件,CIDR为192.168.0.0/16):
sudo kubeadm init \
--pod-network-cidr=192.168.0.0/16 \
--apiserver-advertise-address=192.168.1.10 \
--kubernetes-version=v1.28.2
# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
工作节点加入集群时,使用控制平面初始化输出的kubeadm join命令。若过期,可通过kubeadm create --print-join-command重新生成。
4.3 安装调度相关组件
集群基础就绪后,需要安装网络插件和训练调度所需的扩展组件。首先安装Calico网络插件:
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
对于训练任务,GPU资源调度是刚需。若工作节点配备NVIDIA GPU,需要安装NVIDIA设备插件:
# 在GPU节点上安装NVIDIA驱动后,部署设备插件
kubectl create -f https://raw.githubusercontent.com/NVIDIA/k8s-device-plugin/v0.14.5/nvidia-device-plugin.yaml
# 验证GPU是否可调度
kubectl get nodes -o json | jq '.items[].status.allocatable'
对于训练任务调度,我们还需要部署 调度器扩展组件。以开源的 Volcano 调度器为例,它提供了队列管理、公平调度、GPU共享等高级能力:
# 安装Volcano
kubectl apply -f https://raw.githubusercontent.com/volcano-sh/volcano/v1.8.0/installer/volcano-development.yaml
# 验证Volcano组件
kubectl get pods -n volcano-system
安装完成后,需要验证调度链路是否正常。创建一个测试Pod并指定使用Volcano调度器:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: test-scheduler
schedulerName: volcano
spec:
containers:
- name: test
image: busybox
command: ["sleep", "3600"]
EOF
# 查看Pod调度情况
kubectl get pod test-scheduler -o wide
4.4 案例:训练任务调度验证
下面通过一个实际的GPU训练任务来验证整个环境是否正常工作。我们创建一个请求1张GPU卡的PyTorch训练Pod:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: gpu-train-test
labels:
app: gpu-train
spec:
schedulerName: volcano
containers:
- name: pytorch-train
image: pytorch/pytorch:2.0.1-cuda11.7-cudnn8-runtime
command: ["python", "-c", "import torch; print('CUDA available:', torch.cuda.is_available())"]
resources:
limits:
nvidia.com/gpu: 1
EOF
# 查看日志
kubectl logs gpu-train-test
如果输出CUDA available: True,说明GPU资源已正确调度并透传到容器中。此时可以通过kubectl describe pod gpu-train-test查看调度器日志,确认Volcano参与了调度决策。
4.5 误区与复盘:常见安装问题
| 常见问题 | 现象 | 根因与解决方案 |
|---|---|---|
| 节点NotReady | kubectl get nodes显示NotReady | CNI网络插件未安装或Pod网段冲突。检查Calico DaemonSet日志,确认--pod-network-cidr与Calico配置一致 |
| Pod一直Pending | Pod无法调度到任何节点 | 资源不足或调度器异常。用kubectl describe pod查看Events,确认节点是否有足够CPU/内存/GPU |
| GPU无法识别 | Pod请求GPU但调度失败 | NVIDIA驱动未安装或设备插件未运行。执行nvidia-smi验证驱动,检查kubectl get pods -n kube-system | grep nvidia |
| containerd拉取镜像慢 | 镜像拉取超时 | 配置镜像加速器。编辑/etc/containerd/config.toml,在[plugins."io.containerd.grpc.v1.cri".registry.mirrors]下添加加速地址 |
kubeadm init的默认参数。生产环境需要配置高可用(多个控制平面节点)、证书管理、审计日志等。此外,所有节点的时间必须同步(使用chrony或NTP),否则会导致证书验证失败。
kubectl get events --sort-by=.lastTimestamp → kubectl describe pod <pod-name> → 查看kube-scheduler日志(kubectl logs -n kube-system kube-scheduler-<node>)→ 查看kubelet日志(journalctl -u kubelet -f)。