实验 1: 在线安装 HAMi
本实验将在一台 Google Cloud GPU 虚拟机上,从零搭建 Kubernetes 集群并在线安装 HAMi,形成完整的 GPU 虚拟化运行环境。
你将得到什么
完成本实验后,你将拥有一台完整的 GPU 虚拟化 Kubernetes 集群。关于集群架构和各组件职责的详细解释,参见 HAMi 集群架构。
安装全景图
整个安装过程分 6 步,每一步都在解决一个具体问题:
| 步骤 | 目的 | 解决什么问题 |
|---|---|---|
| 创建 GCP VM | 准备一台带 GPU 的 Linux 服务器 | Kubernetes 需要 GPU 硬件才能调度 GPU 工作负载 |
| 安装 Helm | Kubernetes 的包管理器 | 后续所有组件都通过 Helm 安装,类似 apt/yum |
| 安装 Kubernetes | 容器编排平台 | HAMi 运行在 Kubernetes 之上,所有 GPU 资源由 K8s 管理 |
| 安装 Prometheus | 监控系统 | HAMi 和 GPU Operator 依赖 Prometheus 采集和存储指标 |
| 安装 GPU Operator | NVIDIA GPU 软件栈自动化管理 | 自动安装 GPU 驱动、容器工具包、指标采集器等组件 |
| 安装 HAMi | GPU 虚拟化与共享 | 让多个 Pod 共享同一张 GPU,实现显存切分和算力分配 |
前提条件
- Google Cloud 账号,已启用 Compute Engine API
- 已安装
gcloudCLI 并完成认证(gcloud auth login) - GCP 配额中有 NVIDIA T4 GPU 可用
费用提示:
n1-standard-4+ T4 虚拟机约 $0.55/小时。实验 3 和实验 4 直接复用这套集群,一次开机即可完成全部三个实验。实验结束后请删除虚拟机。
步骤 1: 创建 GCP 虚拟机
目的
创建一台带 GPU 的虚拟机,作为整个实验的基础环境。HAMi 需要物理 GPU 硬件(或直通虚拟 GPU)才能工作,它不是模拟 GPU,而是在真实 GPU 之上做切分和共享。
操作
设置环境变量:
export PROJECT_ID=$(gcloud config get-value project)
export ZONE=us-central1-a
export VM_NAME=hami-workshop
export MACHINE_TYPE=n1-standard-4
export GPU_TYPE=nvidia-tesla-t4
export IMAGE_FAMILY=ubuntu-2204-lts
export IMAGE_PROJECT=ubuntu-os-cloud
export DISK_SIZE=100
创建虚拟机:
gcloud compute instances create ${VM_NAME} \
--project=${PROJECT_ID} \
--zone=${ZONE} \
--machine-type=${MACHINE_TYPE} \
--accelerator=type=${GPU_TYPE},count=1 \
--maintenance-policy=TERMINATE \
--image-family=${IMAGE_FAMILY} \
--image-project=${IMAGE_PROJECT} \
--boot-disk-size=${DISK_SIZE}GB \
--boot-disk-type=pd-ssd
--maintenance-policy=TERMINATE是必须的,GPU 不支持在线迁移,如果 GCP 要维护宿主机,VM 会被终止而不是迁移。
SSH 登录:
gcloud compute ssh ${VM_NAME} --zone=${ZONE}
登录后切换到 root:
sudo su -
步骤 2: 安装 Helm
目的
Helm 是 Kubernetes 的包管理器,后续安装 Prometheus、GPU Operator、HAMi 都通过 Helm 完成。你可以把它理解成 Kubernetes 世界里的 apt 或 yum。
操作
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
验证:
helm version
步骤 3: 安装 Kubernetes
目的
HAMi 是 Kubernetes 上的 GPU 调度增强层,它以 Pod 形式运行在 Kubernetes 中。没有 Kubernetes,HAMi 没有运行的基础。
本步骤使用 kubeadm 搭建一个单节点集群。在单节点上,这个节点既是 Master(控制平面)也是 Worker(运行工作负载)。
操作
3.1 关闭 swap
Kubernetes 要求关闭 swap,因为 Kubernetes 的资源调度假设内存是固定的,swap 会导致性能不可预测。
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
3.2 加载内核模块
容器网络需要 overlay 和 br_netfilter 内核模块。overlay 用于容器文件系统层叠,br_netfilter 用于让 iptables 正确处理桥接流量。
cat <<EOF | tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
3.3 配置内核网络参数
这些参数确保容器之间的网络流量能被正确路由和转发。
cat <<EOF | 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
sysctl --system
3.4 安装 containerd
containerd 是 Kubernetes 默认的容器运行时,负责真正创建和运行容器。Docker 在 Kubernetes 1.24 后已不再是默认运行时。
apt-get update
apt-get install -y containerd
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
# 启用 systemd cgroup 驱动,Kubernetes 要求运行时和 kubelet 使用相同的 cgroup 驱动
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/g' /etc/containerd/config.toml
systemctl restart containerd
systemctl enable containerd
3.5 安装 kubeadm、kubelet、kubectl
这三个工具的关系:
- kubeadm:一次性工具,用来初始化集群
- kubelet: 常驻进程,负责本节点上 Pod 的创建和销毁
- kubectl:日常运维使用的命令行工具
apt-get install -y apt-transport-https ca-certificates curl gpg
mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.34/deb/Release.key | \
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.34/deb/ /' | \
tee /etc/apt/sources.list.d/kubernetes.list
apt-get update
apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
apt-mark hold防止这些包被自动升级,Kubernetes 组件版本需要手动控制。
3.6 初始化集群
kubeadm init --pod-network-cidr=10.244.0.0/16
初始化完成后,配置 kubectl 访问权限:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config