首页 文章

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

提问于
浏览
14

人们如何处理具有流浪者的dev / prod环境的简单自动化(使用puppet)(理想情况下来自同一个vagrantfile)?

Use case I'm trying to solve

  • 如果没有创建,我想用vagrant旋转 生产环境 机器 .

  • 如果在我的开发环境的puppet文件中进行调整,我很乐意重新加载nginx或apache confs for vagrant .

The Problem

当您使用AWS或Digital Ocean等提供商调用vagrant时,它将成为活动提供者,您无法切换 . 你收到这个错误:

找到了与不同提供商的活动计算机 . Vagrant目前允许每台机器一次只有一个提供商 . 未来版本将删除此限制 . 在此之前,请使用新的提供商销毁现有机器 .

它似乎是破坏它的答案,但我只需要切换 . 我不想破坏 .

我很乐意能说

vagrant up prod

要么

vagrant reload prod

然后一个简单的流浪汉将回落到默认机器 .

这种语法类似于multiple machines的工作原理,但是当我只是调用vagrant up时(这是默认行为),我不想启动开发和 生产环境 环境 .

作为工作流程的一部分,我应该关注打包机吗?我在2013年的puppetconf上观看了Mitchell关于Multi-Provider的演讲http://puppetlabs.com/presentations/multi-provider-vagrant-aws-vmware-and-more

我仍然没有看到我的问题的解决方案 .


UPDATE 9/27/13

如果其他人正在反对这个想法,这篇文章清理了我的很多问题 . http://pretengineer.com/post/packer-vagrant-infra

4 回答

  • 0

    至于变通方法,您应该定义 config.vm.define (如建议的here),以便支持多个提供程序 .

    请查找@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
    

    或者以下示例发布at gist by @maxlinc

    # -*- 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,在那里你可能有一个master,staging和production版本(因为它们通常是不同的遥控器) .

    在这种情况下,您可以通过对Vagrantfile的小编辑来启动prod分支,以便将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
    
  • 0

    这是动态changing the 'default' machine name的一种简单方法,具体取决于命令行中指定的 --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
    

    另见:Multiple provisioners in a single vagrant file?

  • 2

    我想出来使用这个场景是管理2个区别 .vagrant 文件夹 .

    注意:大多数其他答案都涉及设置多提供程序,假设您将在不同的提供程序上运行dev和prod,在大多数情况下这可能是正确的,但您肯定会遇到这样的情况:dev和prod具有相同的提供程序 . 让我们说你正在使用aws并且你想使用dev和prod作为ec2实例它将是同一个提供者 .

    假设您要管理 devprod 实例,可能使用不同的提供程序(但也可能在同一个提供程序上),因此您将执行以下操作:

    • 设置 dev 实例,正常 vagrant up --provider <dev_provider> . 这将创建一个可以管理的开发虚拟机

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

    • 与您选择的提供商 vagrant up --provider <prod_provider> 设置 prod 实例 . 现在这将创建您的prod VM

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

    现在,根据您是否要使用dev或prod,您将 .vagrant.dev.vagrant.prod 目录重命名为 .vagrant ,并且vagrant将运行正确的VM .

    我没有提出一个脚本,主要是在大部分时间我与开发人员一起工作,而且我很少需要切换到其他提供商 . 但我不认为从CLI读取参数并使重命名更具动态性将太难 .

相关问题