kubeadm是虚拟机中快速搭建K8s集群最可靠方案,因Minikube易与宿主机Docker冲突、二进制部署调试成本高;需严格完成关闭swap/SELinux、开启网桥转发、配置hosts、统一cgroup driver等初始化步骤;镜像拉取失败最常见,推荐用--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers指定阿里云镜像源。

kubeadm 是当前在虚拟机环境里快速搭建 Kubernetes 集群最可靠的选择,它能把一主两从的集群在 10 分钟内拉起来,前提是系统初始化没踩坑。
为什么不用 Minikube 或二进制部署?
Minikube 适合单节点本地开发,但它的 driver=none 模式在 CentOS/Ubuntu 虚拟机里容易和宿主机 Docker 冲突;而二进制部署要手动配证书、etcd、kube-apiserver 启动参数,调试成本高,不适合“快速搭建”这个目标。kubeadm 封装了这些细节,只要控制平面组件镜像能拉下来,kubeadm init 和 kubeadm join 就能闭环。
CentOS 7/8 或 Ubuntu 22.04/24.04 上必须做的初始化
这些步骤不是可选项,跳过任何一个都可能让 kubeadm init 卡在 preflight check 或直接失败:
- 关闭 swap:
swapoff -a并注释/etc/fstab中 swap 行(否则 kubelet 启动失败) - 关闭 SELinux:
setenforce 0+ 修改/etc/selinux/config为disabled(否则 containerd 拉镜像权限被拒) - 开启网桥流量转发:
sysctl -w net.bridge.bridge-nf-call-iptables=1,并写入/etc/sysctl.d/k8s.conf(否则 Calico/Flannel 网络插件无法建立 Pod 间通信) - 确保
hostname -f可解析,且所有节点/etc/hosts互相映射 IP 和主机名(kubeadm join依赖 DNS 或 hosts 解析 master 地址) - 统一 cgroup driver:Docker 或 containerd 必须和 kubelet 一致,常见错误是 Docker 用
systemd,而 kubelet 默认用cgroupfs—— 在/var/lib/kubelet/config.yaml里确认cgroupDriver: systemd,并重启 kubelet
镜像拉取失败是最常卡住的环节
kubeadm init 默认从 k8s.gcr.io 拉 control plane 镜像,在国内虚拟机环境中几乎必失败。不要等它超时,提前准备好:
- 用阿里云镜像站中转:运行
kubeadm config images list --kubernetes-version v1.30.2查出所需镜像列表 - 逐个用
docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/<image>:<tag>拉取(注意 tag 要对齐,比如kube-apiserver:v1.30.2) - 再用
docker tag重打标签为官方地址,例如:docker tag registry.cn-hangzhou.aliyuncs.com/google_containers/kube-apiserver:v1.30.2 k8s.gcr.io/kube-apiserver:v1.30.2 - 或者更省事:用
kubeadm init --image-repository registry.cn-hangzhou.aliyuncs.com/google_containers --kubernetes-version v1.30.2直接指定仓库
网络插件选 Calico 还是 Flannel?
两者都能跑通,但行为差异影响后续排障:
- Flannel(
host-gw模式):不依赖 etcd 外部存储,纯 host 网络路由,启动快,但不支持 NetworkPolicy - Calico(v3.30+):基于 eBPF 或 iptables 实现策略,支持细粒度 NetworkPolicy,但要求节点时间同步(
chrony或systemd-timesyncd必须启用),且首次安装后需等calico-nodePod 全 Running 才能调度其他 Pod - 别用 Weave:在 VMware Workstation NAT 网络下偶发 Pod DNS 解析失败,排查耗时远超收益
真正容易被忽略的是:Calico 的 podSubnet 必须和 kubeadm init 时传入的 --pod-network-cidr 完全一致,差一个字(比如 192.168.0.0/16 vs 192.168.0.0/24)会导致所有 Node 处于 NotReady 状态,且 kubectl get nodes -o wide 不报错,只显示 STATUS 为 NotReady —— 这个细节连很多文档都没强调清楚。


















