直接用kubeadm写脚本是最可行起点,但必须绕开swap未关闭、sysctl参数缺失、cgroup驱动不一致、镜像拉取失败四大硬坑,并显式配置--image-repository、--pod-network-cidr、--cri-socket、--control-plane-endpoint四个关键参数。

直接用 kubeadm 写脚本是最可行的起点,但必须绕开三个硬坑:系统参数未预设、containerd 配置错位、镜像拉取失败。其他方案(如 kubeasz、Proxmox Helper-Scripts)适合特定环境,不是通用解法。
为什么不能直接跑 kubeadm init 就完事
裸调 kubeadm init 在多数生产环境会卡在第一步——kubelet 启动失败或 control plane 组件 CrashLoopBackOff。根本原因不是命令写错了,而是它依赖的底层状态没准备好:
-
swap未关闭 →kubelet拒绝启动,报错failed to run Kubelet: unable to load bootstrap kubeconfig -
sysctl参数缺失(如net.bridge.bridge-nf-call-iptables=1)→ Calico 或 Flannel 初始化失败,pod无法分配 IP -
cgroup驱动不一致(systemdvscgroupfs)→containerd和kubelet对不上,kubeadm init卡在 “waiting for the control plane to become ready” - 国内网络下默认镜像仓库(
k8s.gcr.io)不可达 →kubeadm init卡在 pull 阶段,日志里反复出现Failed to pull image "k8s.gcr.io/kube-apiserver:v1.30.2"
kubeadm 脚本必须显式配置的 4 个关键参数
这些不是可选项,漏掉任意一个都会导致初始化失败或后续节点无法加入:
针对 Kubernetes 仪表板和 Web UI 的浏览器自动化。适用于与 Kubernetes Dashboard、Grafana、ArgoCD UI 或其他 Web 界面交互。需要设置 MCP_BROWSER_ENABLED=true。
-
--image-repository registry.cn-hangzhou.aliyuncs.com/google_containers:国内必须换阿里云镜像源,否则所有组件镜像拉不到 -
--pod-network-cidr=10.244.0.0/16:必须和后续 CNI 插件(如 Calico 的calico-3.30.7.yaml)中CALICO_IPV4POOL_CIDR值严格一致,否则 Pod 网络不通 -
--cri-socket unix:///run/containerd/containerd.sock:明确告诉kubeadm用 containerd,避免它误判为 Docker(尤其在旧系统残留 docker 包时) -
--control-plane-endpoint:多控制面场景下必须指定 VIP 或 LB 地址,否则kubeadm join --control-plane会连错节点
离线部署时,镜像和二进制怎么塞进脚本
离线环境不能靠 kubeadm config images pull,得提前把所有依赖打包进脚本执行路径:
- 镜像用
docker save或ctr images export导出为 tar,脚本里用ctr images import xxx.tar加载(注意:ctr命令需先确认 containerd 已运行) - k8s 组件二进制(
kubeadm/kubelet/kubectl)从https://dl.k8s.io/release/v1.30.2/bin/linux/amd64/下载后校验 SHA256,脚本中直接cp到/usr/bin/并chmod +x - CNI 插件 YAML(如
calico-3.30.7.yaml)需提前下载,脚本中用sed -i "s#192.168.0.0/16#$POD_CIDR#g" calico.yaml替换 CIDR,再kubectl apply -f - 别忘了
etcd镜像 —— 如果用外部 etcd,脚本要检查etcdctl连通性;如果用 kubeadm 托管 etcd,则必须确保etcd镜像已导入且版本与 k8s 版本兼容(如 v1.30.2 对应etcd-3.5.12-0)
脚本里最容易被忽略的权限和路径细节
很多脚本在本地测试成功,一上生产就挂,问题往往出在这些“看不见”的地方:
-
kubelet服务文件(/etc/systemd/system/kubelet.service.d/10-kubeadm.conf)里cgroup-driver必须和/etc/containerd/config.toml中[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]下的值完全一致,常见错误是脚本改了前者却漏改后者 -
kubeadm init生成的/etc/kubernetes/admin.conf默认权限是600,脚本若用非 root 用户执行kubectl,必须加chown $USER:$USER /etc/kubernetes/admin.conf && chmod 600 -
containerd配置中的registry.mirrors必须包含"docker.io"和"k8s.gcr.io"两个域名,否则即使换了镜像源,pause镜像仍会尝试直连原站 - 脚本末尾验证用的
kubectl get nodes,如果返回空,别急着重装——先journalctl -u kubelet -n 50看最后一屏日志,90% 的问题是kubelet没读到正确的--node-ip或--address参数










