我正在构建一个多机器环境,并且对 Vagrantfile 处理过程中看到的行为感到困惑。
我的目标:创建 n 个具有 3 个不同角色的虚拟机。所有 n 个虚拟机将使用一个通用的“bootstrap.sh”脚本,然后每个角色将根据主机名/角色运行另一个脚本。
Vagrantfile 在这里: Vagrant文件
所有单独的部分/部分都正常工作,脚本运行,并在正确的 VM 中创建了正确的数量的额外磁盘。我想了解的是为什么“内联”配置程序的行为不同,如何确保特定于角色的脚本在正确的时间运行。
第一个问题——为什么这段代码只执行一次?
config.vm.provision "Setup shell environment", type: "shell" do |s|
s.inline = <<-SHELL
# Install some tools
#yum install -y net-tools traceroute git ansible gcc make python > /dev/null 2>&1
# Add the public key
mkdir /root/.ssh
chmod 700 /root/.ssh
touch /root/.ssh/authorized_keys
echo "Appending user@Laptop keys to root and vagrant authorized_keys"
echo #{ssh_pub_key} >> /home/vagrant/.ssh/authorized_keys
echo #{ssh_pub_key} >> /root/.ssh/authorized_keys
echo "Appending AdminVM keys to root and vagrant authorized_keys"
echo #{adminvm_karlvkey} >> /home/vagrant/.ssh/authorized_keys
echo #{adminvm_karlvkey} >> /root/.ssh/authorized_keys
echo #{adminvm_rootkey} >> /home/vagrant/.ssh/authorized_keys
echo #{adminvm_rootkey} >> /root/.ssh/authorized_keys
# Copy /etc/hosts
#if [ -e /vagrant/files/hosts ]
# then sudo cat /vagrant/files/hosts >> /etc/hosts
#elif [ -e /home/vagrant/sync/files/hosts ]
# then sudo cat /home/vagrant/sync/files/hosts >> /etc/hosts
#fi
SHELL
end # inline shell provisioner config.provision
但是,这会对已解析的哈希中的每个元素执行一次?因此,对于哈希中的第一个 VM,“admin”,一切正常。但是在后续迭代中,它会对前面的每个元素运行一次?因此,到第六个 VM 时,它会运行六次。
config.vm.provision :shell, :path => "../../scripts/bash/config/bootstrap.sh"
这些也一样:
# - OSD Node
if ("#{servers["name"]}").include? "osd"
puts "I'm an OSD"
puts servers["name"]
config.vm.provision :shell, :path => "../../scripts/bash/ceph/osd.sh"
end
我怀疑我没能理解这里的一些基本原理。我搜索了整个互联网,甚至搜索到了互联网的边缘,但找不到一个很好的解释。
答案1
这将阻止 bootscrap.sh 脚本多次运行:
config.vm.provision "bootstrap", type: "shell" do |script|
script.path = "../../scripts/bash/config/bootstrap.sh"
end
我仍然不知道如何让这些停止执行。我想我明白为什么它们每次都会被执行,只是不确定如何停止它。它们只需要在配置的 VM 上和引导脚本之后运行。我不可能是唯一一个想要这样做的人,我只是找不到任何地方的记录。
if ("#{servers["name"]}").include? "osd"
config.vm.provision "Configure OSD Node", type: "shell" do |script|
script.path = "../../scripts/bash/ceph/osd.sh"
end
end
# - Monitor Node
if ("#{servers["name"]}").include? "mon"
config.vm.provision "Configure Monitor Node", type: "shell" do |script|
script.path = "../../scripts/bash/ceph/monitor.sh"
end
end
# - Admin Node
if ("#{servers["name"]}").include? "admin"
config.vm.provision "Configure Admin Node", type: "shell" do |script|
script.path = "../../scripts/bash/ceph/admin.sh"
end
end
答案2
最终解决方案:
### External shell scripts for configuration
# - Run on every node
config.vm.provision "bootstrap", type: "shell" do |script|
script.path = "../../scripts/bash/config/bootstrap.sh"
end
# Role based setup is in the servers.yml file - pull it out as a key:value
config.vm.provision "Role", type: "shell" do |script|
script.path = "../../scripts/bash/ceph/#{servers["script"]}"
end
我有一个“servers.yml”文件,我向其中添加了 VM 的另一个属性“script”。然后我只需在 script.path 中明确调用它即可。
现在一切都运行正常并且我的 Vagrantfile 已更新。