必须为每个节点显式配置相同子网的静态private_network IP(如192.168.50.10/11/12),确保子网一致、IP不冲突且避开宿主机常用网段,才能实现多节点稳定互通。

如何用 private_network 配置 Vagrant 多节点静态 IP 互通
多节点集群的前提是各虚拟机之间能稳定通信,vagrant up 后不能靠 DHCP 动态分配——IP 变动会导致 Ansible 或脚本反复失败。必须为每个节点显式绑定固定 private_network,且确保子网一致、IP 不冲突。
- 所有节点都用
config.vm.network "private_network", ip: "192.168.50.10"这类写法,子网掩码默认/24,所以192.168.50.10和192.168.50.11能直接 ping 通 - 避免使用
192.168.1.x等宿主机常用网段,否则可能和物理网络冲突,192.168.50.x是 Vagrant 官方推荐隔离网段 - 不要给多个节点配相同 IP,Vagrant 不报错但后续 SSH 会混乱;建议在 IP 后加注释,比如
# master/# node1 - Windows/macOS 宿主机需确认 VirtualBox 或 Parallels 的 Host-Only 网卡已启用,否则
vagrant up时会卡在 “Waiting for domain to get an IP address…”
如何用 config.vm.provision 正确触发多节点差异化初始化
同一个 Vagrantfile 里定义多个 config.vm.define,但每个节点的初始化逻辑往往不同(如只有 master 装 kubeadm、worker 节点只 join)。不能把所有命令堆在全局 config.vm.provision 里,必须按节点名做条件分发。
- 用
config.vm.define "master" do |master|包裹专属配置,再在其内部调用master.vm.provision,这样脚本只作用于该节点 - Shell provisioner 中避免硬编码路径或依赖宿主机环境变量;改用
file方式同步脚本:master.vm.provision "shell", path: "scripts/master-init.sh" - 若要用同一份 shell 脚本但参数不同,可传
args:node.vm.provision "shell", path: "scripts/common-setup.sh", args: "--role worker --ip 192.168.50.11" - 注意 provision 执行顺序:Vagrant 按
define块出现顺序启动节点,但 provision 是并行执行的——如果某节点依赖另一节点服务(如 etcd),得在脚本里加until nc -z master 2379; do sleep 2; done等等待逻辑
为什么 vagrant reload --provision 有时不生效?关键在 synced_folder 和 provision 触发时机
修改了 scripts/ 下的初始化脚本后,运行 vagrant reload --provision 却发现旧逻辑还在执行——大概率是 synced_folder 没同步新文件,或 provision 被跳过。
- 默认
vagrant reload不重新同步synced_folder,必须先vagrant rsync(对 rsync 类型)或确保用了type: "nfs"/type: "rsync"显式声明同步方式 -
--provision只对已 created 的机器生效;如果某节点之前vagrant destroy过,reload会跳过它——此时应改用vagrant up --provision或单独vagrant provision node1 - Shell provisioner 默认只在首次 up 时运行;要每次强制重跑,加
run: "always":vm.provision "shell", run: "always", path: "scripts/install-docker.sh" - 如果脚本里有
apt update,注意 Ubuntu 节点可能因 metadata server 不可达而卡住,可在vb.customize ["setextradata", :id, "VBoxInternal/Devices/VMMDev/0/Config/GetHostTimeDisabled", "1"]关闭时间同步干扰
如何让多节点集群启动后自动完成 service 注册或集群 join(比如 Kubernetes)
单纯靠 vagrant up 启动 VM 并不够,真正形成集群需要跨节点协调:master 先生成 token,worker 再用它 join。Vagrant 本身不提供跨节点变量传递机制,得靠外部协调或临时存储。
- master 节点 provision 脚本末尾生成 token 并写入共享路径,例如:
mkdir -p /vagrant/tokens && kubeadm token create --print-join-command > /vagrant/tokens/join-cmd.sh - worker 节点脚本开头读取该文件:
if [ -f /vagrant/tokens/join-cmd.sh ]; then source /vagrant/tokens/join-cmd.sh; fi - 更健壮的做法是加等待逻辑:worker 脚本里用
while [ ! -f /vagrant/tokens/join-cmd.sh ]; do sleep 3; done,避免 race condition - 注意
/vagrant是默认 synced_folder,所有节点可见;但不要往里面写大文件或频繁 IO,会影响性能
跨节点协调没有银弹,token 文件共享只是最轻量的方案;复杂场景建议用 Consul、etcd 或甚至一个简单的 Python HTTP server 临时托管元数据——毕竟 Vagrant 是开发测试工具,不是生产编排平台。
















