环境准备与集群搭建:用kubeadm搭一个能跑vLLM的K8s集群
说实话,很多人在K8s上栽跟头,不是后面的推理部署有多难,而是第一步集群就没搭稳。我见过太多同学花了两天搭环境,最后发现kubelet起不来,或者网络插件死活装不上。嗯,这节课我们就来把地基打牢。
我个人习惯用kubeadm来搭生产级集群,但如果你只是想在笔记本上快速验证,Kind会更轻量。两种方式我都会讲,你根据场景选就行。
核心目标:搭建一个可用的K8s集群,配置好kubectl和Helm,确保所有组件健康运行。这是后续所有vLLM推理实验的基础。
1. 环境概览:我们需要什么?
先看看整体架构。下面这张图是我自己画的,能帮你快速理解集群的组件关系。
说白了,Master节点是大脑,Worker节点是手脚。你通过kubectl发指令,apiserver接收后调度到Worker上跑Pod。vLLM推理任务最终会以Pod的形式运行在Worker节点上。
2. 方式一:用kubeadm搭建(推荐生产环境)
kubeadm是官方推荐的集群搭建工具。我在项目中用过不下20次,稳定性没得说。但要注意,它要求你提前装好容器运行时和kubelet。
2.1 前置条件
- 两台以上Ubuntu 22.04虚拟机(或物理机),2C4G起步
- 所有节点能互相ping通,关闭swap
- 安装Docker或containerd作为容器运行时
注意:K8s从1.24版本开始移除了对Docker的直接支持,改用containerd。如果你用Docker,需要安装cri-dockerd适配器。我个人建议直接用containerd,少一层转换,性能更好。
2.2 安装步骤
先在所有节点上执行基础配置:
# 关闭swap
sudo swapoff -a
sudo sed -i '/ swap / s/^/#/' /etc/fstab
# 加载内核模块
cat <
然后安装kubeadm、kubelet和kubectl:
sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl
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.0-1.1 kubeadm=1.28.0-1.1 kubectl=1.28.0-1.1
sudo apt-mark hold kubelet kubeadm kubectl
小技巧:用apt-mark hold锁定版本,防止意外升级导致集群不稳定。我曾经在生产环境吃过这个亏,半夜被报警吵醒,就是因为kubelet自动升级了。
2.3 初始化Master节点
在Master节点上执行:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.100
这里的--pod-network-cidr要和你后面选的网络插件匹配。我用Flannel,所以用10.244.0.0/16。如果你用Calico,可以换成192.168.0.0/16。
初始化成功后,会输出一段kubeadm join命令,记得保存好。那是Worker节点加入集群的凭证。
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
2.4 安装网络插件
没有网络插件,Pod之间是没法通信的。我习惯用Flannel,简单稳定:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
等一两分钟,检查一下:
kubectl get pods -n kube-flannel
看到所有Pod都是Running状态,就说明网络通了。
2.5 加入Worker节点
在Worker节点上执行刚才保存的join命令:
sudo kubeadm join 192.168.1.100:6443 --token xxxxx --discovery-token-ca-cert-hash sha256:xxxxx
回到Master节点验证:
kubectl get nodes
应该能看到所有节点都是Ready状态。
3. 方式二:用Kind搭建(适合本地开发)
Kind是用Docker容器模拟节点的工具。你想想看,一台笔记本就能跑一个完整的K8s集群,多方便。我平时做原型验证都用它。
3.1 安装Kind
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind
3.2 创建集群
写一个配置文件,把API Server的端口映射出来,方便后面用kubectl访问:
cat < kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 6443
hostPort: 6443
protocol: TCP
- role: worker
- role: worker
EOF
kind create cluster --config kind-config.yaml --name vllm-cluster
等几分钟,集群就起来了。验证一下:
kind get clusters
kubectl cluster-info --context kind-vllm-cluster
对比总结:kubeadm适合生产或多人协作场景,Kind适合个人开发测试。如果你只是学vLLM推理,Kind完全够用。但如果你想体验完整的集群运维,建议用kubeadm。
4. 配置kubectl
kubectl是操作K8s的瑞士军刀。配置其实很简单,就是把集群的认证信息放到~/.kube/config里。
如果你用kubeadm,初始化后会自动生成。如果你用Kind,它会自动帮你配置好。但如果你需要手动配置,可以这样:
kubectl config set-cluster my-cluster --server=https://192.168.1.100:6443 --certificate-authority=/path/to/ca.crt
kubectl config set-credentials my-user --client-certificate=/path/to/client.crt --client-key=/path/to/client.key
kubectl config set-context my-context --cluster=my-cluster --user=my-user
kubectl config use-context my-context
验证配置是否生效:
kubectl get nodes
kubectl get pods -A
如果能看到节点和Pod列表,说明配置成功了。
5. 安装Helm
Helm是K8s的包管理器。后面部署vLLM时,我们会用Helm Chart来管理配置,省去手动写YAML的麻烦。
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh
验证安装:
helm version
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
个人经验:Helm的模板语法刚开始可能觉得绕,但用熟了会发现它比手写YAML高效得多。尤其是你要部署多个环境(dev/staging/prod)时,一套Chart改改values就能复用。
6. 验证集群健康状态
集群搭好了,怎么确认它真的能用?我一般会跑一套完整的检查流程:
| 检查项 | 命令 | 预期结果 |
|---|---|---|
| 节点状态 | kubectl get nodes |
所有节点Ready |
| 系统Pod | kubectl get pods -n kube-system |
所有Pod Running |
| DNS解析 | kubectl run test --image=busybox --rm -it -- nslookup kubernetes.default |
返回IP地址 |
| 调度测试 | kubectl run nginx --image=nginx --replicas=3 |
3个Pod正常运行 |
| Helm可用 | helm list |
返回空列表(无报错) |
如果DNS解析失败,大概率是CoreDNS没起来。检查一下:
kubectl get pods -n kube-system | grep coredns
如果CoreDNS处于CrashLoopBackOff状态,通常是网络插件没装好。重新apply一下Flannel或Calico就行。
避坑指南:我曾经在部署vLLM时发现Pod一直Pending,查了半天才发现是节点资源不足。建议你在验证阶段就用kubectl describe node看看资源分配情况,别等到跑推理任务了才排查。
7. 小结
到这一步,你应该有了一个健康的K8s集群,kubectl和Helm也都配好了。接下来就可以开始部署vLLM推理服务了。记住,环境准备这一步花点时间打好基础,后面会顺畅很多。
如果你在搭建过程中遇到问题,先检查网络插件和容器运行时。这两个是80%问题的根源。