题 我应该使用Vagrant还是Docker来创建一个孤立的环境? [关闭]


我使用Ubuntu进行开发和部署,并且需要创建一个隔离的环境。

我正在考虑为此目的使用Vagrant或Docker。有哪些优点和缺点,或者这些解决方案如何比较?


1888
2018-05-20 10:05


起源


两者现在都可以组合: docs.vagrantup.com/v2/provisioning/docker.html - Alp
我们能 不要删除这个伙计们?也许这是偏离主题的,可能是 关闭,但是这两个工具的作者(以及90k视图)的答案很长,这很有价值,不值得删除。 - Jeremy
你的问题很幸运,可以得到两位作者的两个服务答案:米切尔和所罗门希克斯 - itsazzad


答案:


如果您的目的是孤立的,我认为Docker就是您想要的。

Vagrant是一个虚拟机管理器。它允许您编写虚拟机配置和配置的脚本。但是,依赖于它仍然是一个虚拟机 VirtualBox的 (或其他)有巨大的开销。它需要你有一个可能很大的硬盘驱动器文件,它需要很多内存,性能可能不是很好。

另一方面,Docker使用内核cgroup和命名空间via LXC。这意味着您使用的内核与主机和同一文件系统相同。 你可以使用Dockerfile docker build 命令以处理容器的配置和配置。你有一个例子 docs.docker.com 关于如何制作Dockerfile;它非常直观。

你想要使用Vagrant的唯一原因是你需要在Ubuntu盒子上进行BSD,Windows或其他非Linux开发。否则,去Docker。


1044
2018-05-26 16:46



不幸的是,还没有。如果您使用的是32位系统,则需要具有64位客户系统的VM才能运行docker。但是,使用go1.1,32位支持变得更好,并且docker很可能很快支持32位arch - creack
“Mac,Windows和一些Linux发行版目前无法原生运行Docker,因此我们帮助您设置Ubuntu虚拟机并在其中运行Docker”。因此,除非您使用主流Linux发行版,否则您的应用程序将在docker中运行,而docker本身将在VM中运行。 - aleemb
这适用于Mac和Windows,但自从docker 0.7以来,任何Linux发行版都能正常工作。如果您知道不工作的,请告诉我。此外,除非您有Mac或Windows堆栈(这不太可能,但可能发生),您不希望在Linux上的任何地方运行Docker。 docker客户端在Mac上工作正常,应该很快在BSD上工作,守护进程最终将支持BSD,Solaris和Mac。 - creack
如果有人读了这些评论,你应该知道Docker在12天之前命中了ver1.0(blog.docker.com/2014/06/its-here-docker-1-0并且现在有很多不同的平台可以稳定和支持(docs.docker.com/installation) - JorgeArtware
vagrant有LXC和docker provisioners。然而 - Vagrant和docker是根本不同的东西。 Vagrant纯粹用于开发环境,而docker则仅用于生产和Linux。 - Dannyboy


免责声明:我写了Vagrant!但是因为我写了Vagrant,我把大部分时间都花在DevOps世界中,其中包括像Docker这样的软件。我和许多使用Vagrant的公司合作,很多人使用Docker,我看到两者如何相互影响。

在我说太多之前,直接回答: 在您的特定场景中(您自己独立工作,在Linux上工作,在生产中使用Docker),您可以单独使用Docker并简化操作。在许多其他情况下(我进一步讨论),它并不那么容易。

直接将Vagrant与Docker进行比较是不正确的。在某些情况下,它们确实重叠,而在绝大多数情况下,它们不会重叠。实际上,比较像Vagrant和Boot2Docker(可以运行Docker的最小操作系统)之类的东西。在抽象方面,Vagrant比Docker高出一个级别,因此在大多数情况下这不是一个公平的比较。

Vagrant为了开发目的而推出运行应用/服务的东西。这可以在VirtualBox,VMware上。它可以像AWS,OpenStack一样远程。在这些内容中,如果您使用容器,Vagrant并不关心,并且包含:例如,它可以自动安装,下拉,构建和运行Docker容器。凭借Vagrant 1.6,Vagrant拥有 基于docker的开发环境,并支持在Linux,Mac和Windows上使用与Vagrant相同的工作流程。 Vagrant并不试图在这里取代Docker,它包含了Docker的做法。

Docker专门运行Docker容器。如果你直接与Vagrant进行比较:它具体是一个更具体的(只能运行Docker容器),灵活性较低(需要Linux或Linux主机某处)解决方案。当然,如果你在谈论生产或CI,那就没有与Vagrant相比! Vagrant不会生活在这些环境中,所以应该使用Docker。

如果你的组织只运行所有项目的Docker容器,并且只有开发人员在Linux上运行,那么,Docker绝对可以为你工作!

否则,我认为尝试单独使用Docker没有任何好处,因为您失去了很多Vagrant所提供的功能,这些功能具有真正的业务/生产力优势:

  • Vagrant可以推出VirtualBox,VMware,AWS,OpenStack等机器。无论您需要什么,Vagrant都可以推出它。如果您使用的是Docker,Vagrant可以在其​​中任何一个上安装Docker,以便您可以将它们用于此目的。

  • Vagrant是所有项目的单一工作流程。或者换句话说,无论是否在Docker容器中,人们必须学会运行项目。例如,如果将来竞争对手出现与Docker直接竞争,Vagrant也能够运行。

  • Vagrant适用于Windows(返回XP),Mac(返回10.5)和Linux(返回内核2.6)。在所有三种情况下,工作流程都是相同的。如果您使用Docker,Vagrant可以启动可以在所有这三个系统上运行Docker的计算机(VM或远程)。

  • Vagrant知道如何配置一些高级或非平凡的东西,如网络和同步文件夹。例如:Vagrant知道如何将静态IP连接到计算机或转发端口,无论您使用什么系统(VirtualBox,VMware等),配置都是相同的。对于同步文件夹,Vagrant提供多种机制来获取本地文件到远程机器(VirtualBox共享文件夹,NFS,rsync,Samba [插件]等)。如果您正在使用Docker,即使是没有Vagrant的VM的Docker,您也必须手动执行此操作,否则他们必须在这种情况下重新发明Vagrant。

  • Vagrant 1.6拥有一流的支持 基于docker的开发环境。这不会在Linux上启动虚拟机,并将在Mac和Windows上自动启动虚拟机。最终的结果是,使用Docker在所有平台上都是统一的,而Vagrant仍然处理诸如网络,同步文件夹等事情的繁琐细节。

为了解决我听到的支持使用Docker而不是Vagrant的特定反驳论点:

  • “这是不太活跃的部分” - 是的,如果你专门为每个项目使用Docker,它可以。即使这样,它也会牺牲Docker锁定的灵活性。如果您决定不将Docker用于过去,现在或未来的任何项目,那么您将拥有更多移动部件。如果你曾经使用过Vagrant,那么你就拥有了一个支持其余部分的移动部件。

  • “它更快!” - 一旦你拥有了可以运行Linux容器的主机,Docker在运行容器方面肯定比任何虚拟机都要快。但启动虚拟机(或远程机器)是一次性成本。在一天中,大多数Vagrant用户从未真正销毁他们的VM。这对于开发环境来说是一种奇怪的优化。在生产中,Docker真的很棒,我理解需要快速旋转/减少容器。

我希望现在可以清楚地看到,将Docker与Vagrant进行比较是非常困难的,而且我认为这是不正确的。对于开发环境,Vagrant更抽象,更通用。 Docker(以及使其表现得像Vagrant的各种方式)是Vagrant的特定用例,忽略了Vagrant提供的所有其他功能。

总结:在高度特定的用例中,Docker肯定是Vagrant的可能替代品。在大多数用例中,事实并非如此。 Vagrant不会妨碍您使用Docker;它实际上做了它可以使体验更顺畅的事情。如果您发现这不是真的,我很乐意接受改进建议,因为Vagrant的目标是与任何系统同等运作。

希望这可以解决问题!


2173
2018-01-23 16:55



@JaredMarkell我想也许他正在寻找一种基于网络的服务,让他可以管理他的Vagrant机器,比如 Protobox。 - Ryan Kennedy
@Mitchell我只想说谢谢你详细解释这个问题。显然,你不可能完全客观,所以我很欣赏你花时间解释它们可以被使用的细微差别和各种情况。我认为现在围绕各种工具的很多困惑是它们重叠很多,很多人想要一个通用的解决方案,有人只是告诉他们该做什么,他们可以实现它。你的答案的美妙之处在于它回答了基本问题:我如何创建一个孤立的环境? (不论工具)。 - Jordan
@JaredMarkell Docker有一个REST API docs.docker.com/reference/api/docker_remote_api - Tarnay Kálmán
@OğuzÇelikdemirVagrant可以做的远不止这些。当然,如果您为每个项目准备一个特定的虚拟机,这将持续。但在开发过程中,我经常会添加更多服务/守护进程/设置(例如,当我决定在开发期间将RabbitMQ用于项目时)。纯VM方法将要求您在安装和配置RabbitMQ的情况下准备新映像,并强制开发人员将其VM更改为新VM。对于Vagrant - 我在流浪汉配置中添加了适当的行,所有开发人员都可以轻松升级他们的VM(使用 vagrant provision)。 - Tomasz Struczyński
(你的意思是“披露”,揭示重要的东西,而不是“免责声明”,否认责任: english.stackexchange.com/q/115850) - Jerry101


我是Docker的作者。

简短的回答是,如果你想管理机器,你应该使用Vagrant。如果您想构建和运行应用程序环境,则应使用Docker。

Vagrant是一种管理虚拟机的工具。 Docker是一种通过将应用程序打包到轻量级容器中来构建和部署应用程序的工具。容器可以容纳几乎任何软件组件及其依赖项(可执行文件,库,配置文件等),并在保证且可重复的运行时环境中执行它。这使得构建应用程序并在任何地方进行部署非常容易 - 在笔记本电脑上进行测试,然后在不同的服务器上进行实时部署等。

这是一个常见的误解,你只能在Linux上使用Docker。那是不对的;您也可以在Mac上安装Docker,Windows支持正在进行中。当安装在Mac上时,Docker捆绑了一个小型Linux VM(磁盘上25 MB!),它充当容器的包装器。一旦安装,这是完全透明的;您可以以完全相同的方式使用Docker命令行。这为您提供了两全其美的优势:您可以使用容器测试和开发应用程序,容器非常轻便,易于测试且易于移动(例如,请参阅 https://hub.docker.com 用于与Docker社区共享可重用容器),您无需担心管理虚拟机的细节,这无论如何都只是达到目的的手段。

从理论上讲,可以使用Vagrant作为Docker的抽象层。我建议不要这样做有两个原因:

  • 首先,Vagrant不是Docker的好抽象。 Vagrant旨在管理虚拟机。 Docker旨在管理应用程序运行时。这意味着Docker可以通过设计以更丰富的方式与应用程序进行交互,并提供有关应用程序运行时的更多信息。 Docker中的原语是进程,日志流,环境变量和组件之间的网络链接。 Vagrant中的原语是机器,块设备和ssh密钥。 Vagrant只是坐在堆栈的较低位置,它与容器交互的唯一方法就是假装它只是另一种机器,你可以“启动”和“登录”。所以,当然,您可以使用Docker插件键入“vagrant up”,并且会发生一些相当不错的事情。它是Docker可以做的全部广度的替代品吗?尝试本机Docker几天,亲眼看看:)

  • 第二,锁定论证。 “如果你使用Vagrant作为抽象,你将不会被锁定在Docker中!”。从设计用于管理机器的Vagrant的角度来看,这非常有意义:容器不仅仅是另一种机器吗?就像Amazon EC2和VMware一样,我们必须小心不要将我们的配置工具与任何特定供应商联系起来!这将创建锁定 - 更好地用Vagrant将它全部抽象出来。除此之外,完全错过了Docker的观点。 Docker不提供机器;它将您的应用程序包装在轻量级的可移植运行时中,可以在任何地方删除

您为应用程序选择的运行时与您配置机器的方式无关!例如,将应用程序部署到由其他人配置的计算机(例如,系统管理员部署的EC2实例,可能使用Vagrant)或者Vagrant根本无法配置的裸机时,这种情况非常频繁。相反,您可以使用Vagrant配置与开发应用程序无关的计算机 - 例如即用型Windows IIS框等。或者您可以使用Vagrant为不使用Docker的项目配置机器 - 例如,他们可能使用rubygems和rvm的组合来进行依赖关系管理和沙盒。

总结:Vagrant用于管理机器,Docker用于构建和运行应用程序环境。


1282
2018-03-13 06:16



只是想注意这个答案的流浪方面是不正确的。 Vagrant不用于管理机器,Vagrant用于管理开发环境。 Vagrant旋转机器的事实大多是历史性的。 Vagrant的下一个版本拥有一流的支持,可以直接在主机或任何VM(Mac,Win)上使用Docker作为提供程序来启动开发环境。它也可以启动原始LXC,如果这是某人想要的(再次,在主机或VM上)。 Vagrant有兴趣做最好的创建便携式开发环境,无论是否创建VM。 - Mitchell
@Mitchell - 你能否指出一些关于beta的文档,这些文档详细阐述了这个陈述?我对它很感兴趣。 - Davide
“这是一个常见的误解,你只能在Linux上使用Docker”虽然这是真的,但可以准确地说你只能在Docker上使用Linux。如果我想建立一个测试运行器,在各种各样的环境配置(不同的数据库,php版本,缓存后端等)中运行我的应用程序,那么我可以轻松地使用docker容器。但我无法看到我的应用程序是否可以在Windows IIS环境或BSD或OSX上正常运行。 - Mixologic
自Vagrant为docker提供内置提供程序支持以来,您的第一点已经过时了: docs.vagrantup.com/v2/provisioning/docker.html - Alp
这篇文章已经过时了。 Vagrant现在支持Docker作为提供商。还有一些视频演示了如何将Vagrant和Docker统一使用 博客。 - sargas


我接受了我的回复,承认我没有使用Docker的经验,除了作为一个看起来非常简洁的解决方案的狂热观察者,它获得了很大的吸引力。

我对Vagrant有相当多的经验并且可以强烈推荐它。就基于VM而非基于LXC而言,它肯定是一个更重量级的解决方案。但是,我发现一台像样的笔记本电脑(8 GB RAM,i5 / i7 CPU)使用Vagrant / VirtualBox和开发工具一起运行虚拟机没有问题。

Vagrant真正伟大的事情之一就是融合 木偶/厨师/ shell脚本用于自动配置。如果您正在使用其中一个选项来配置生产环境,则可以创建一个与您将要获得的完全相同的开发环境,这正是您想要的。

Vagrant的另一个好处是你可以将你的Vagrant文​​件和你的应用程序代码一起发布。这意味着团队中的其他人都可以共享此文件,并确保每个人都使用相同的环境配置。

有趣的是,Vagrant和Docker实际上可能是免费的。可以扩展Vagrant以支持不同的虚拟化提供商,并且Docker可能是一个在不久的将来获得支持的提供商。看到 https://github.com/dotcloud/docker/issues/404 最近有关该主题的讨论。


73
2018-06-25 21:33



伙计们,我发布了一个 试验 docker的流浪者提供者: github.com/fgrehm/docker-provider。 - fgrehm
Docker不是虚拟化,而是在自己的容器内运行操作系统,使用相同的主机内核,而不是像其他虚拟机那样提供服务器,因此Vagrant已经支持docker。 - Aftab Naveed
Docker是操作系统本身的虚拟化,隐含地重用底层硬件。它是虚拟化,因为它抽象并隔离了容器中运行的文件系统,网络和进程。 - jose.angel.jimenez


它们非常互补。

几个月来,我一直在为所有项目使用VirtualBox,Vagrant和Docker的组合,并且强烈感受到以下好处。

在Vagrant中,您可以完全取消任何Chef独奏配置,并且您需要的所有流浪文件都要准备一台运行一个安装docker的小shell脚本的机器。这意味着我的每个项目的Vagrantfiles几乎完全相同且非常简单。

这是一个典型的Vagrantfile

# -*- mode: ruby -*-
# vi: set ft=ruby :
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "mark2"
  config.vm.box_url = "http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box"
  [3000, 5000, 2345, 15672, 5672, 15674, 27017, 28017, 9200, 9300, 11211, 55674, 61614, 55672, 5671, 61613].each do |p|
    config.vm.network :forwarded_port, guest: p, host: p
  end
  config.vm.network :private_network, ip: "192.168.56.20"
  config.vm.synced_folder ".", "/vagrant", :type => "nfs"
  config.vm.provider :virtualbox do |vb|
    vb.customize ["modifyvm", :id, "--memory", "2048"]
    vb.customize ["modifyvm", :id, "--cpus", "2"]
  end
  # Bootstrap to Docker
  config.vm.provision :shell, path: "script/vagrant/bootstrap", :privileged => true
  # Build docker containers
  config.vm.provision :shell, path: "script/vagrant/docker_build", :privileged => true
  # Start containers
  # config.vm.provision :shell, path: "script/vagrant/docker_start", :privileged => true
end

安装docker的Bootstrap文件如下所示

#!/usr/bin/env bash
echo 'vagrant  ALL= (ALL:ALL) NOPASSWD: ALL' >> /etc/sudoers
apt-get update -y
apt-get install htop -y
apt-get install linux-image-extra-`uname -r` -y
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list
apt-get update -y
apt-get install lxc-docker -y
apt-get install curl -y

现在要获得我需要运行的所有服务,我有一个看起来像这样的docker_start脚本

#!/bin/bash
cd /vagrant
echo Starting required service containers
export HOST_NAME=192.168.56.20
# Start MongoDB
docker run --name=mongodb --detach=true --publish=27017:27017 --publish=28017:28017 dockerfile/mongodb
read -t5 -n1 -r -p "Waiting for mongodb to start..." key
# Start rabbitmq
docker run --name=rabbitmq --detach=true --publish=5671:5671 --publish=5672:5672 --publish=55672:55672 --publish=15672:15672 --publish=15674:15674 --publish=61613:61613 --env RABBITMQ_USER=guest --env RABBITMQ_PASS=guest rabbitmq
read -t5 -n1 -r -p "Waiting for rabbitmq to start..." key
# Start cache
docker run --name=memcached --detach=true --publish=11211:11211  ehazlett/memcached
read -t5 -n1 -r -p "Waiting for cache to start..." key
# Start elasticsearch
docker run --name=elasticsearch --detach=true --publish=9200:9200 --publish=9300:9300 dockerfile/elasticsearch
read -t5 -n1 -r -p "Waiting for elasticsearch to start..." key
echo "All services started"

在这个例子中,我运行的是MongoDB,Elastisearch,RabbitMQ和Memcached

非docker Chef独奏配置会相当复杂。

当你进入生产阶段时,获得了最后一大优势,将开发环境转换为完全相同的主机基础设施,因为他们只有足够的配置来运行docker意味着很少有工作。

如果您有兴趣,我可以在我自己的网站上找到关于开发环境的更详细的文章

实现Vagrant / Docker开发环境


52
2017-08-20 20:42



您完成了所有docker_start编排,但没有打扰将容器链接在一起。您是否只使用硬编码的端口号,因为您在Vagrant下运行它? - WineSoaked
嗨WineSoaked,上面的例子没有显示实际使用所有这些服务的容器。如果你查看上面提到的博客文章,可以使用另一个脚本脚本/ vagrant / docker_web来启动项目的开发容器。这确实在docker run命令上使用了--link,Rails项目使用docker注入的环境变量连接到服务。 - Mark Stratmann
我可以看到两种产品的合并潜力。 Vagrant作为环境测试和app包装器的docker。合并两者可以测试单个应用程序或单元测试许多方案。我认为许多“测试平台服务”正在使用Vagrant + Docker。 - erm3nda
“他们非常免费。” - 两者都可以免费使用。 - Underyx
嗨@koppor我上次使用码头机大约三个月前还没有回到它。我遇到的问题是,在使用VMWare驱动程序时,从我的MAC主机主机到运行docker的VM共享文件夹时出现了错误。这意味着我无法在Mac上本地编辑代码并将更改反映在docker容器中。我不知道他们是否已经修好了,当他们这样做的时候我确实会改用它。然而,自从写完这个答案以来,我已将所有容器编排切换为docker compose - Mark Stratmann


流浪,LXC 是Vagrant的一个插件,让你使用LXC来提供Vagrant。它没有默认的vagrant VM(VirtualBox)所具有的所有功能,但它应该允许您比docker容器更灵活。链接中有一个视频,显示其值得观看的功能。


48
2017-08-01 18:44



这里是项目的直接链接 github.com/fgrehm/vagrant-lxc - gertas


现在使用Vagrant可以将Docker作为提供者。 http://docs.vagrantup.com/v2/docker/。可以使用Docker提供程序代替VirtualBox或VMware。

请注意,您也可以使用Docker配置Vagrant。这与使用Docker作为提供者非常不同。 http://docs.vagrantup.com/v2/provisioning/docker.html

这意味着您可以更换 厨师 要么 木偶 与Docker。您可以使用像Docker这样的组合作为提供者(VM)和Chef作为配置者。或者您可以将VirtualBox用作提供程序,使用Docker作为配置程序。


41
2018-05-30 16:10



世界刚刚疯狂;)我们可以使用docker provider运行vagrant来在vagrant中运行docker容器 - Hoto
@zainengineer,Windows上Vagrant的Docker提供程序是否仍然使用boot2docker或是否使用了Docker Toolbox的某些变体? - Derek Mahar
@zainengineer你有一些说明性例子(不是流浪文档)的链接吗? - Tset Noitamotua