本文档提供了在两台 Debian 13 虚拟机上部署 Kubernetes v1.33 集群的完整步骤。使用 kubeadm(官方推荐方式)部署,适合学习和测试 Kubernetes 核心功能。
🏗️ 部署架构
VM 1:Control Plane (Master) - 运行 API Server、etcd、Scheduler、Controller Manager
VM 2:Worker Node - 运行 Pods 和 Kubelet
🔧 前置要求 硬件资源
每台虚拟机至少 2 CPU 和 2GB RAM
推荐 4 CPU 和 4GB RAM 以获得更好的性能
网络配置
所有机器相互可通信(检查防火墙规则)
Kubernetes 所需的开放端口已配置或防火墙已关闭
记录每台 VM 的 IP 地址(本指南使用 192.168.199.135 作为 Master 节点示例)
系统检查清单 执行以下检查确保系统就绪:
ip link | grep link /ether cat /sys/class/dmi/id/product_uuidfree | grep Swap
📦 安装步骤 配置 APT 源(两台 VM) 使用清华 TUNA 镜像加速软件包下载:
nano /etc/apt/sources.list
替换为以下内容:
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie main contrib non-free-firmware deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie main contrib non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie-updates main contrib non-free-firmware deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie-updates main contrib non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie-backports main contrib non-free-firmware deb-src https://mirrors.tuna.tsinghua.edu.cn/debian/ trixie-backports main contrib non-free-firmware deb https://mirrors.tuna.tsinghua.edu.cn/debian-security/ trixie-security main contrib non-free-firmware deb-src https://mirrors.tuna.tsinghua.edu.cn/debian-security/ trixie-security main contrib non-free-firmware
禁用 Swap(两台 VM) Kubelet 无法在启用 Swap 的系统上运行:
sudo swapoff -asudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstabfree | grep Swap | awk '{print $2}'
安装并配置容器运行时(两台 VM) 使用 Containerd 作为容器运行时:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlaysudo modprobe br_netfiltercat <<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 --systemsudo apt updatesudo apt install -y containerdsudo mkdir -p /etc/containerdsudo containerd config default | sudo tee /etc/containerd/config.tomlsudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/g' /etc/containerd/config.tomlsudo sed -i 's|registry.k8s.io/pause:3\.[0-9]\+|registry.aliyuncs.com/google_containers/pause:3.10|g' /etc/containerd/config.tomlsudo systemctl restart containerdsudo systemctl enable containerdsudo ctr version
安装 Kubeadm、Kubelet、Kubectl(两台 VM) 添加 Kubernetes 官方仓库并安装 v1.33 版本:
sudo apt-get updatesudo apt-get install -y apt-transport-https ca-certificates curl gnupgcurl -fsSL https://pkgs.k8s.io/core:/stable:/v1.33/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.33/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.listsudo apt-get updatesudo apt-get install -y kubelet=1.33.* kubeadm=1.33.* kubectl=1.33.*sudo apt-mark hold kubelet kubeadm kubectlkubeadm version
初始化 Control Plane(仅 VM 1 - Master 节点) 前置条件: 记录 Master 节点的 IP 地址(本例为 192.168.199.135)
sudo kubeadm init \ --apiserver-advertise-address=192.168.199.135 \ --pod-network-cidr=10.244.0.0/16 \ --kubernetes-version v1.33.6 \ --image-repository registry.aliyuncs.com/google_containers
重要: 初始化完成后,终端会输出:
kubectl 配置命令
kubeadm join 命令 (必须保存供 Worker 节点使用)
配置 Kubectl(仅 VM 1) mkdir -p $HOME /.kubesudo cp -i /etc/kubernetes/admin.conf $HOME /.kube/configsudo chown $(id -u):$(id -g) $HOME /.kube/configkubectl get nodes
Worker Node 加入集群(仅 VM 2) 在 VM 2 上执行步骤 5 中保存的 kubeadm join 命令:
sudo kubeadm join 192.168.199.135:6443 --token <YOUR_TOKEN> \ --discovery-token-ca-cert-hash sha256:<YOUR_HASH>
说明: <YOUR_TOKEN> 和 <YOUR_HASH> 来自步骤 5 的输出。
部署网络插件 - Flannel(VM 1 或任意有 kubectl 访问的节点) Kubernetes 需要网络插件实现 Pod 间通信。我们使用 Flannel:
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml kubectl get pods -n kube-system | grep flannel kubectl get pods -n kube-system
预加载 Flannel 镜像(两台 VM - 可选但推荐) 如果网络不稳定或镜像下载缓慢,可提前在两台 VM 上加载 Flannel 镜像:
方案一:直接拉取镜像
sudo ctr image pull ghcr.io/flannel-io/flannel:v0.27.4sudo ctr image pull ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1
方案二:本地打包后导入
如果镜像源不可达,可在能访问外网的机器上下载后导入:
docker pull ghcr.io/flannel-io/flannel:v0.27.4 docker pull ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1 docker save -o flannel_images.tar \ ghcr.io/flannel-io/flannel:v0.27.4 \ ghcr.io/flannel-io/flannel-cni-plugin:v1.8.0-flannel1 sudo ctr --namespace k8s.io image import flannel_images.tarsudo ctr images list | grep flannelsudo ctr --namespace k8s.io images list | grep flannel
修复 CNI 插件路径(两台 VM) 如果 CoreDNS Pod 仍无法启动,执行以下修复:
sudo mkdir -p /usr/lib/cnicd /usr/lib/cni/for plugin in /opt/cni/bin/*; do sudo ln -sf "$plugin " "$(basename $plugin) " done ls -lh /usr/lib/cni/sudo systemctl restart kubeletkubectl get pods -n kube-system
✅ 集群验证 最终验证(VM 1) kubectl get nodes kubectl get pods -n kube-system kubectl cluster-info kubectl run test-pod --image=nginx --port=80 kubectl get pods kubectl delete pod test-pod
常见验证命令 kubectl describe node <NODE_NAME> kubectl top nodes kubectl get events -n kube-system kubectl get cs
🐛 故障排除 问题:节点处于 NotReady 状态 原因: 网络插件未部署或未就绪
解决方案:
kubectl get pods -n kube-system | grep flannel kubectl logs -n kube-system <FLANNEL_POD_NAME>
问题:CoreDNS Pod 处于 Pending 状态 原因: CNI 插件路径配置不正确
解决方案: 执行步骤 9 的修复步骤
问题:kubeadm join 失败 原因: Token 过期(默认 24 小时有效)
解决方案:
kubeadm token create --print-join-command
获取调试日志 sudo journalctl -u kubelet -fsudo journalctl -u containerd -fsudo cat /var/log/pods/kube-system_*/kubeadm-*/log
📌 常用命令参考 kubectl get nodes kubectl get pods -A kubectl get svc -A kubectl get events -n kube-system kubectl cordon <NODE_NAME> kubectl uncordon <NODE_NAME> kubectl drain <NODE_NAME> kubectl logs -n kube-system <POD_NAME> kubectl describe pod <POD_NAME> kubectl cluster-info kubectl api-resources
📚 参考资源
Kubernetes 官方文档
kubeadm 官方指南
Flannel 官方文档
Containerd 官方文档