4. 环境搭建:安装与配置Kubernetes集群、容器运行时及调度组件

训练任务编排与调度系统的底层依赖是稳定、可扩展的Kubernetes集群。本章将带领你从零搭建一套用于开发与测试的Kubernetes环境,并安装调度系统所需的容器运行时与关键调度组件。我们采用 kubeadm 作为集群初始化工具,因为它提供了生产级、可复现的安装路径,且便于后续版本升级与故障排查。

4.1 核心原理:集群组件与调度链路

在动手安装前,必须先理解Kubernetes调度系统运行所依赖的组件拓扑。训练任务通常以Pod形式运行,而调度器(kube-scheduler)负责将Pending状态的Pod分配到最合适的节点。调度器决策依赖三类信息:集群节点资源(CPU、内存、GPU)、Pod资源请求(requests/limits)以及自定义调度策略(如GPU显存、RDMA网卡)。

下图展示了训练任务从提交到运行的完整链路,以及各组件间的交互关系:

训练任务提交 kubectl / API kube-apiserver 集群唯一入口 etcd 状态存储 kube-scheduler 调度决策 调度扩展组件 GPU/拓扑感知 队列/优先级 kube-controller-manager 节点/副本管理 工作节点(Node Pool) Node-1 (GPU节点) kubelet + CRI (containerd) kube-proxy GPU Driver + Device Plugin Node-2 (CPU节点) kubelet + CRI (containerd) kube-proxy 弹性资源池 Node-3 (混合节点) kubelet + CRI (containerd) kube-proxy 自定义调度器扩展 扩展点:Filter/Score/PreBind

从图中可以看到,调度器并非直接与节点通信,而是通过 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命令。若token过期,可通过kubeadm token 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)。