使用Vagrant管理开发和生产环境?

14

人们如何使用Puppet进行简单自动化来处理开发/生产环境,并在同一个Vagrantfile中使用(理想情况下)?

我试图解决的用例

  • 如果尚未创建,则希望使用Vagrant启动生产机器。
  • 如果在我的开发环境的Puppet文件中进行了调整,则希望使用Vagrant重新加载生产中的nginx或apache配置文件。

问题

当您使用AWS或Digital Ocean等提供程序调用vagrant up时,它将成为活动提供程序,您无法切换。 您会收到以下错误:

找到不同提供程序的活动机器。 Vagrant当前仅允许每台机器一次使用单个提供程序。 未来版本将删除此限制。 在那之前,请销毁现有机器以使用新提供程序。

看起来答案是销毁,但我只需要切换。 我不想销毁。

我希望能够说

vagrant up prod

或者

vagrant reload prod

然后只需使用简单的“vagrant up”命令就可以回到默认的虚拟机。这种语法类似于多台机器的工作方式,但是当我调用“vagrant up”时(这是默认行为),我不想启动开发和生产环境。我应该考虑将Packer作为工作流程的一部分吗?我看了米切尔在2013年PuppetConf上关于Multi-Provider http://puppetlabs.com/presentations/multi-provider-vagrant-aws-vmware-and-more 的演讲。
我仍然没有看到我的问题的解决方案。
更新于2013年9月27日:
如果还有其他人在对抗这个想法,这篇文章解决了我很多疑问。http://pretengineer.com/post/packer-vagrant-infra
4个回答

2
关于解决方法,建议您按照这里的建议定义config.vm.define,以支持多个提供者。
请参考@kzap发布的以下配置作为示例:
Vagrant.configure("2") do |config|

  # Store the current version of Vagrant for use in conditionals when dealing
  # with possible backward compatible issues.
  vagrant_version = Vagrant::VERSION.sub(/^v/, '')

  # Configuration options for the VirtualBox provider.
  def configure_vbox_provider(config, name, ip, memory = 2048, cpus = 1)
    config.vm.provider :virtualbox do |v, override| 
      # override box url
      override.vm.box = "ubuntu/trusty64"
      # configure host-only network
      override.vm.hostname = "#{name}.dev"
      override.vm.network :private_network, id: "vvv_primary", ip: ip

      v.customize ["modifyvm", :id, 
        "--memory", memory,
        "--cpus", cpus,
        "--name", name,
        "--natdnshostresolver1", "on",
        "--natdnsproxy1", "on"
      ]
    end
  end

  default_provider = "virtualbox"
  supported_providers = %w(virtualbox rackspace aws managed)
  active_provider = ENV['VAGRANT_ACTIVE_PROVIDER'] # it'd be better to get this from the CLI --provider option
  supported_providers.each do |provider|
  next unless (active_provider.nil? && provider == default_provider) || active_provider == provider

    #
    # VM per provider
    #
    config.vm.define :"sample-#{provider}" do | sample_web_config |

      case provider
      when "virtualbox"
        configure_vbox_provider(sample_web_config, "examine-web", "192.168.50.1")

      when "aws"
        configure_aws_provider(sample_web_config)

      when "managed"
        configure_managed_provider(sample_web_config, "1.2.3.4")

      when "rackspace"
        configure_rackspace_provider(sample_web_config)  

      end
  end

end

还有下面这个例子是由 @maxlinc 在 gist 上发布的

# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "dummy"

  config.vm.provider :rackspace do |rs|
    rs.username = ENV['RAX_USERNAME']
    rs.api_key  = ENV['RAX_API_KEY']
    rs.rackspace_region   = :ord
  end

  supported_providers = %w(virtualbox rackspace)
  active_provider = ENV['VAGRANT_ACTIVE_PROVIDER'] # it'd be better to get this from the CLI --provider option
  supported_providers.each do |provider|
    next unless active_provider.nil? || active_provider == provider

    config.vm.define "exact_name_#{provider}" do |box|
      box.vm.provider :rackspace do |rs|
        rs.flavor = '1 GB Performance'
        rs.image  = 'Ubuntu 14.04 LTS (Trusty Tahr) (PVHVM)'
      end
    end

    config.vm.define "regex_#{provider}" do |box|
      box.vm.provider :rackspace do |rs|
        rs.flavor = /1\s+GB\s+Performance/
        rs.image  = /Ubuntu.*Trusty Tahr.*(PVHVM)/
      end
    end

    config.vm.define "id_#{provider}" do |box|
      box.vm.provider :rackspace do |rs|
        rs.flavor = 'performance1-1'
        rs.image  = 'bb02b1a3-bc77-4d17-ab5b-421d89850fca'
      end
    end

    config.vm.define "unlisted_#{provider}" do |box|
      box.vm.provider :rackspace do |rs|
        rs.flavor = 'performance1-1'
        rs.image = '547a46bd-d913-4bf7-ac35-2f24f25f1b7a'
      end
    end
  end
end

1
不是理想的解决方案,但使用git分支怎么样?我的想法是它在概念上可能类似于使用heroku,你可能会有主版本、暂存版本和生产版本(因为它们通常是不同的远程)。
在这种情况下,您可以从dev分支开始,对Vagrantfile进行小修改以稍微更改VM的名称。然后,您应该能够随时将所有更改从dev合并到prod分支中。因此,您的工作流程如下:
$ git checkout prod
$ vagrant up
$ git checkout master
...  make changes to puppet ...
$ git checkout prod
$ git merge master
$ vagrant reload
$ git checkout master

你可以编写脚本和别名来实现这些,这样你最终就会得到。
$ start_production
$ reload_production

分支的问题不在于我需要更改的文件,而在于隐藏的.vagrant文件夹。一旦提供程序启动,它就会接管该文件夹。 - jcrichto
目前,我只是在检查一个独立的克隆版本,并在数字海洋提供商上启动生产机器。这有点讨厌,但是有效。 - jcrichto

0

这里有一种简单的动态更改“默认”机器名称的方法,取决于从命令行指定的--provider,以便它们不会在不同的提供程序之间发生冲突:

require 'getoptlong'
opts = GetoptLong.new(
  [ '--provider', GetoptLong::OPTIONAL_ARGUMENT ],
  [ '--vm-name',  GetoptLong::OPTIONAL_ARGUMENT ]
)

provider=ENV['PROVIDER'] || 'virtualbox'
vm_name=ENV['VM_NAME'] || 'default'
opts.each do |opt, arg|
  case opt
    when '--provider'
      provider=arg
    when '--vm-name'
      vm_name=arg
  end
end

Vagrant.configure(2) do |config|

  # HERE you are dynamically changing the machine name to prevent conflict.
  config.vm.define "mt-#{provider}-#{vm_name}"

  # Below sections are just examples, not relevant.
  config.vm.provider "virtualbox" do |vm|
    vm.name = "test.local"
    vm.network "private_network", ip: "192.168.22.22"
    vm.customize ['modifyvm', :id, '--natdnshostresolver1', 'on']
    config.vm.box = "ubuntu/wily64"
  end

  config.vm.provider :aws do |aws, override|
    aws.aws_profile = "testing"
    aws.instance_type = "m3.medium"
    aws.ami = "ami-7747d01e"
    config.vm.box = "testing"
  end
end

使用示例:

VM_NAME=dev PROVIDER=virtualbox vagrant up --provider=virtualbox
VM_NAME=uat PROVIDER=aws vagrant up --provider=aws
VM_NAME=test PROVIDER=aws vagrant up --provider=aws
VM_NAME=prod PROVIDER=aws vagrant up --provider=aws
VM_NAME=uat PROVIDER=aws vagrant destroy -f
VM_NAME=test PROVIDER=aws vagrant status

另请参阅:如何在单个Vagrant文件中使用多个provisioners?


0

我想到的解决方案是管理两个不同的.vagrant文件夹。

注意:大多数其他答案都涉及设置多提供程序,假设您将在不同的提供程序上运行dev和prod,在大多数情况下可能是正确的,但您肯定可以有dev和prod使用相同的提供程序的情况。比如说,您正在使用aws,并且希望将dev和prod用作ec2实例,则将是相同的提供程序。

假设您想要管理devprod实例,可能使用不同的提供程序(但也可能非常适合使用相同的提供程序),因此您将执行以下操作:

  • 使用正常的vagrant up --provider <dev_provider>命令来设置开发环境实例。 这将创建一个开发虚拟机,您可以进行管理。

  • 备份项目目录中创建的.vagrant文件夹,并将其重命名为.vagrant.dev

  • 使用您选择的提供商和vagrant up --provider <prod_provider>命令来设置生产环境实例。现在,您的生产虚拟机已经创建。

  • 备份项目目录中新创建的.vagrant文件夹,并将其重命名为.vagrant.prod

现在,根据您想要使用的是开发环境还是生产环境,您将把.vagrant.dev.vagrant.prod目录重命名为.vagrant,然后vagrant将操作正确的虚拟机。

我没有编写脚本,因为大部分时间我都在使用开发环境,很少需要切换到其他提供商。但我认为从命令行界面读取参数并使重命名更加动态化不会太难。


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