Vagrant多机器配置管理

3

我正在尝试使用Ansible作为提供程序,在Vagrant中创建多机环境。

我的Vagrantfile如下:

   Vagrant.configure("2") do |config|

    config.vm.provision "ansible" do |ansible|
       ansible.limit = "all"
       ansible.playbook = "main.yml"
       ansible.inventory_path = "staging"
       ansible.verbose = "-vvvv"
     end

    config.vm.define "machine1" do |machine1| 
        machine1.vm.box = "ubuntu/trusty64"
        machine1.vm.network "private_network", ip:"192.168.77.10"
        machine1.vm.hostname = "machine1"
        machine1.vm.provider :virtualbox do |vb|
           vb.name = "machine1"
        end
    end    

    config.vm.define "machine2" do |machine2| 
        machine2.vm.box = "ubuntu/trusty64"
        machine2.vm.network "private_network", ip:"192.168.77.11"
        machine2.vm.hostname = "machine2"
        machine2.vm.provider :virtualbox do |vb|
            vb.name = "machine2"
        end
    end    

    config.vm.define "machine3" do |machine3| 
        machine3.vm.box = "ubuntu/trusty64"
        machine3.vm.network "private_network", ip:"192.168.77.12"
        machine3.vm.hostname = "machine3"
        machine3.vm.provider :virtualbox do |vb|
           vb.name = "machine3"
        end
    end      
end

库存:

[AppServers]
192.168.77.10
192.168.77.11
192.168.77.12

[WebServers]
192.168.77.11
192.168.77.12

[WebLoadBalancers]
192.168.77.10

[SlaveDbServers]
192.168.77.10
192.168.77.12

[MasterDbServers]
192.168.77.11

[DbLoadBalancers]
192.168.77.11

main.yml:

- hosts: all
  roles:
  - Common
  - ConsulServer
  - ConsulAgent  

- hosts: WebServers
  roles:
  - WebServer

- hosts: WebLoadBalancers
  roles:
  - LoadBalancer

- hosts: MasterDbServers
  roles:
  - DbServer

我想要获得三台机器,它们都必须包含常用软件(Consul服务器和代理、vim等),并且每台机器还需要一些额外的软件。但是,当我运行 "vagrant up" 命令时,只有第一台机器被创建且执行 provisioner 失败,因为另外两台机器没有被创建。 请问是否可以在所有机器创建完成后再执行 provisioner?或者我的方法不正确,应该采用其他方法?感谢您的时间。

首先,显而易见的是,您的本地主机上是否安装了 ansible?其次,您可以通过 vagrant up --no-provision 命令推迟配置,并可选使用 --no-destroy-on-error。最后,您的 main.yml 需要添加 --- 才能成为有效的 YAML 文件(尽管这可能不会导致失败)。 - Mike D
Ansible已安装在本地主机上并作为provisioner运行,但仅适用于主机192.168.77.10 - 其他主机无法访问。看起来,vagrant在创建每台虚拟机后运行provisioner,而不是在创建Vagrantfile中的所有虚拟机后再运行。 - Pavlo I.
1个回答

8

我遇到的第一个问题是 ERROR: cannot find role in...。我假设你已经有了这些角色并且为了简洁起见将它们排除在外。我的建议是当你测试时要有一个简单的Ansible剧本:

---
- hosts: all
  gather_facts: false
  tasks:
  - command: hostname -f

其次,问题在于静态库存文件的使用及其注意事项。当第一台机器启动后但其他机器未启动时,Ansible provisioner 在运行时无法找到所有主机,因此您会看到一个错误。
最后,每台机器都有不同的密钥,您必须传递。因此,遵循Vagrant关于使用Ansible进行多机并行处理的文档方法并借助这个解决方法,我建议您的Vagrantfile如下所示:
Vagrant.configure("2") do |config|
  N = 3

  VAGRANT_VM_PROVIDER = "virtualbox"
  ANSIBLE_RAW_SSH_ARGS = []

  (1..N-1).each do |machine_id|
    ANSIBLE_RAW_SSH_ARGS << "-o IdentityFile=.vagrant/machines/machine#{machine_id}/#{VAGRANT_VM_PROVIDER}/private_key"
  end

  (1..N).each do |machine_id|
    config.vm.define "machine#{machine_id}" do |machine|
      machine.vm.box = "ubuntu/trusty64"
      machine.vm.hostname = "machine#{machine_id}"
      machine.vm.network "private_network", ip: "192.168.77.#{10+machine_id-1}"

      # Only execute once the Ansible provisioner,
      # when all the machines are up and ready.
      if machine_id == N
        machine.vm.provision :ansible do |ansible|
          # Disable default limit to connect to all the machines
          ansible.limit = "all"
          ansible.playbook = "main.yml"
          ansible.inventory_path = "staging"
          ansible.verbose = "-v"
          ansible.raw_ssh_args = ANSIBLE_RAW_SSH_ARGS
        end
      end
    end
  end
end

实际上有很多方法可以解决这个问题。我不建议您在两步模式中使用 --no-provision。就我个人而言,我喜欢使用 hosts 文件来指定我的组,因为这是我在生产 ansible-playbook 中使用的方式。但是,如果您不需要或不想要静态清单文件,则可以使用 vagrant 内置的主机组支持。请参见 如何生成清单组,我可以提供一个示例。 - Mike D
我已经尝试了您的Vagrantfile和来自我上面帖子的hosts文件,但是出现了新问题:现在Ansible成功连接到了最后一台机器(192.168.77.12),但其他两台(192.168.77.10-11)无法访问:fatal: [192.168.77.11] => SSH Error: while connecting to 192.168.77.11:22 It is sometimes useful to re-run the command using -vvvv, which prints SSH debug output to help diagnose the issue. 看起来需要一些额外的ssh选项。请问您能否建议在哪里查找? - Pavlo I.
目前没有任何专有内容。非常感谢您的时间!这是存储库:GitHub - Pavlo I.
太好了,我会尝试这个!从您的角度和经验来看,支持暂存和生产的更清晰的方法是什么?如果为开发系统保留动态清单并为生产创建分离的静态清单,会怎样呢?Playbook将与分组相关,因此将保持相同。 - Pavlo I.
@PavloI。这完全取决于您的工作流程和用例。还有其他几种实现方式(例如,查看config.ssh.insert_key=false)。对我来说,我尽量避免在代码中使用hack。我在我的repo中发布的方式纯粹是vagrant,并根据您的机器生成inven文件。然后随着您的进展进行改进。顺便说一句,vagrant 1.8.1已经发布了。 - Mike D
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接