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

Should I use Vagrant or Docker for creating an isolated environment?

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

为此,我正在考虑流浪者或码头工人。优缺点是什么,或者这些解决方案是如何比较的?


免责声明:我写的流浪汉!但因为我写了《漂泊者》,我大部分时间都生活在DevOps世界,其中包括Docker之类的软件。我和很多使用流浪者的公司合作,很多使用Docker,我看到了这两种方式的相互作用。好的。

在我说得太多之前,有一个直接的答案:在你的特定场景中(你自己一个人工作,在Linux上工作,在生产中使用Docker),你可以只使用Docker并简化事情。在许多其他场景中(我会进一步讨论),这并不容易。好的。

把流浪者和码头工人直接比较是不正确的。在某些情况下,它们确实是重叠的,而且在绝大多数情况下,它们没有重叠。实际上,比较起来更为恰当的是,与boot2docker(可以运行docker的最小操作系统)之类的东西比较起来,它们是可变的。在抽象方面,Vagrant高于Docker,所以在大多数情况下这不是一个公平的比较。好的。

Vagrant发布了一些东西来运行应用程序/服务以进行开发。这可以在virtualbox、vmware上进行。它可以像AWS、OpenStack那样远程。在这些容器中,如果您使用容器,vagrant不在乎,并接受:例如,它可以自动安装、下拉、构建和运行docker容器。对于Vagrant1.6,Vagrant具有基于Docker的开发环境,并且支持在Linux、Mac和Windows中使用与Vagrant具有相同工作流的Docker。Vagrant不想取代Docker,它接受Docker实践。好的。

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

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

否则,我不认为单独使用Docker有什么好处,因为你失去了很多Vagrant必须提供的功能,这些功能具有真正的业务/生产力优势:好的。

  • Vagrant可以启动virtualbox、vmware、aws、openstack等机器。不管你需要什么,流浪者都可以发射它。如果您使用docker,vagrant可以在其中任何一个上面安装docker,这样您就可以使用它们。好的。

  • Vagrant是所有项目的单一工作流。或者换句话说,不管项目是否在码头集装箱中,人们都必须学习如何运行它。例如,如果未来出现竞争对手直接与Docker竞争,Vagrant也能做到这一点。好的。

  • Vagrant在Windows(回到XP)、Mac(回到10.5)和Linux(回到内核2.6)上工作。在这三种情况下,工作流是相同的。如果使用docker,vagrant可以启动一台机器(vm或remote),可以在这三个系统上运行docker。好的。

  • 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,过去、现在或将来,那么你会有更多的移动部件。如果你使用了迷走神经,你有一个活动的部分来支撑其余的部分。好的。

  • "更快!"-一旦拥有了可以运行Linux容器的主机,Docker运行容器的速度肯定比任何虚拟机都要快。但是启动虚拟机(或远程机器)是一次性的成本。在一天中,大多数游民用户从未真正破坏过他们的虚拟机。对于开发环境来说,这是一种奇怪的优化。在生产中,Docker真的闪耀着光芒,我理解快速旋转上/下集装箱的必要性。好的。

我希望现在能清楚地看到,把码头工人和流浪汉作比较是非常困难的,而且我认为这是不正确的。对于dev环境,vagrant更抽象、更一般。Docker(以及使其表现得像Vagrant的各种方法)是Vagrant的一个特定用例,它忽略了Vagrant必须提供的所有其他功能。好的。

综上所述:在高度特定的用例中,docker无疑是一种可以替代vagrant的工具。在大多数用例中,它不是。漂泊不妨碍你使用Docker,它实际上是尽其所能让你的体验更顺畅。如果你发现这不是真的,我很乐意接受改进的建议,因为流浪者的目标是在任何系统中都能同样出色地工作。好的。

希望这能解决问题!好的。好啊。


我是Docker的作者。

简而言之,如果你想管理机器,你应该使用流浪者。如果您想构建和运行应用程序环境,应该使用Docker。

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

普遍的误解是你只能在Linux上使用Docker。这是不正确的;您也可以在Mac和Windows上安装Docker。当安装在Mac上时,Docker捆绑了一个小型Linux虚拟机(磁盘上25 MB!)作为容器的包装。一旦安装,这是完全透明的;您可以以完全相同的方式使用docker命令行。这给了你最好的两个方面:你可以使用容器来测试和开发你的应用程序,这些容器非常轻,易于测试,并且易于移动(参见https://hub.docker.com与docker社区共享可重用的容器),而且你不必担心管理虚拟machi的具体细节。这只是一个结束的手段。

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

  • 首先,对于码头工人来说,流浪者并不是一个好的抽象概念。Vagrant是为管理虚拟机而设计的。Docker设计用于管理应用程序运行时。这意味着Docker,通过设计,可以以更丰富的方式与应用程序交互,并拥有更多关于应用程序运行时的信息。Docker中的原语是进程、日志流、环境变量和组件之间的网络链接。Vagrant中的原语是机器、块设备和ssh密钥。Vagrant只是位于堆栈的较低位置,它与容器交互的唯一方式就是假装它只是另一种机器,您可以"引导"和"登录"。所以,当然,你可以用Docker插件输入"vagrant up",然后会发生一些漂亮的事情。它是码头工人所能做的全部工作的替代品吗?试试本地Docker几天,自己看看:)

  • 第二,锁定参数。"如果你把流浪汉当作抽象概念,你就不会被锁在码头上!".从设计用于管理机器的Vagrant的角度来看,这是完全合理的:容器不是另一种机器吗?就像AmazonEC2和VMware一样,我们必须小心,不要将我们的资源调配工具与任何特定的供应商捆绑在一起!这将创建一个锁定——最好用vagrant将其抽象化。但这完全忽略了码头工人的观点。Docker不提供机器;它将您的应用程序包装在一个轻量级的可移植运行时中,可以放在任何地方。

为应用程序选择的运行时与如何配置计算机无关!例如,将应用程序部署到由其他人提供的机器(例如系统管理员部署的EC2实例,可能使用vagrant)或vagrant根本无法提供的裸机上是非常频繁的。相反,您可以使用vagrant来提供与开发应用程序无关的机器,例如随时可用的WindowsIIsbox或其他东西。或者,您可以使用vagrant为不使用docker的项目提供机器——例如,它们可能使用rubygems和rvm的组合来进行依赖性管理和沙盒化。

总之:vagrant用于管理机器,docker用于构建和运行应用程序环境。


如果你的目的是孤立,我想Docker就是你想要的。

Vagrant是一个虚拟机管理器。它允许您编写虚拟机配置和配置的脚本。然而,它仍然是一个虚拟机,依赖于具有巨大开销的virtualbox(或其他)。它要求您有一个巨大的硬盘文件,它需要大量的RAM,并且性能可能不是很好。

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

如果您需要在Ubuntu设备上进行BSD、Windows或其他非Linux开发,那么您可以使用Vagrant的唯一原因就是。否则,去找Docker。


首先,我承认我对Docker没有经验,除了作为一个热心的观察者,我认为这是一个非常好的解决方案,并获得了很大的吸引力。

我确实对流浪者有相当多的经验,我可以强烈推荐它。它当然是一个更重的解决方案,因为它是基于虚拟机而不是基于LXC的。但是,我发现一台像样的笔记本电脑(8 GB RAM,i5/i7 CPU)在使用Vagrant/VirtualBox和开发工具运行VM时没有问题。

Vagrant的一个真正伟大的功能是与Puppet/Chef/Shell脚本集成以实现配置自动化。如果您正在使用这些选项之一来配置生产环境,那么您可以创建一个与您将要获得的环境几乎相同的开发环境,这正是您想要的。

Vagrant的另一个好处是,可以将VagrantFile与应用程序代码一起进行版本转换。这意味着团队中的其他人都可以共享此文件,并且您可以保证每个人都使用相同的环境配置。

有趣的是,流浪者和码头工人实际上是免费的。Vagrant可以扩展到支持不同的虚拟化提供者,Docker可能是在不久的将来得到支持的一个这样的提供者。有关此主题的最新讨论,请参阅https://github.com/dotcloud/docker/issues/404。


它们是非常互补的。

几个月来,我一直在为我的所有项目使用virtualbox、vagrant和docker的组合,并强烈感受到以下好处。

在Vagrant中,您完全可以不使用任何Chef Solo配置,您只需要准备一台运行一个安装Docker的小shell脚本的机器。这意味着我的每个项目的漂泊文件几乎是相同的,非常简单。

这是典型的迷走神经

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# -*- 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的引导文件如下

1
2
3
4
5
6
7
8
9
10
#!/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启动脚本,看起来像这样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/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,这实际上意味着几乎没有什么工作。

如果您感兴趣,我在自己的网站上有一篇关于开发环境的更详细的文章

实现一个漂泊/码头开发环境


vagrant lxc是vagrant的一个插件,让我们使用lxc来提供vagrant。它没有默认的vagrant vm(virtualbox)拥有的所有特性,但是它应该允许您比Docker容器更灵活。链接中有一段视频显示了它的功能,值得一看。


现在有了Vagrant,你就可以让Docker作为提供者了。http://docs.vagrantup.com/v2/docker/。Docker提供程序可以代替virtualbox或vmware。

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

这意味着你可以用码头工人代替厨师或木偶。您可以使用像Docker作为提供者(VM)和Chef作为提供者这样的组合。或者可以使用virtualbox作为提供程序,使用docker作为提供程序。


使用两者是应用程序交付测试的一个重要部分。我刚刚开始涉足Docker,并且非常认真地思考一个在构建和交付其软件方面非常复杂的应用程序团队。想想典型的菲尼克斯项目/连续交付情况。

这种想法是这样的:

  • 使用Java/Go应用程序组件并将其构建为容器(注意,不确定应用程序是应该在容器中构建还是应该在容器中构建,然后安装到容器中)
  • 将容器运送到一个移动虚拟机。
  • 对所有应用程序组件重复此操作。
  • 迭代要编码的组件。
  • 持续测试Vagrant管理的虚拟机的传送机制
  • 睡眠很好地知道什么时候是部署容器的时候,集成测试发生在比Docker之前更连续的基础上。

这似乎是Mitchell关于"流浪者是为了发展"的说法的逻辑延伸,以及Farley/Humbles在持续交付中的思考。如果作为开发人员,我能够缩小集成测试和应用程序交付的反馈循环,那么将遵循更高的质量和更好的工作环境。

作为一名开发人员,我不断地、一致地向虚拟机交付容器,并更全面地测试应用程序,这意味着生产版本将进一步简化。

因此,我认为流浪者的发展是一种利用Docker对应用程序部署的一些可怕后果的方式。


绝对是为了胜利!

正如您可能知道的,vagrant用于虚拟机管理,docker用于软件容器管理。如果您不知道这两者之间的区别,这里是:软件容器可以与其他软件容器共享同一台机器和内核。使用容器可以节省资金,因为您不会在多个操作系统(内核)上浪费资源,您可以为每台服务器打包更多的软件,以保持良好的隔离度。

当然,这是一种新的纪律,可以照顾自己的陷阱和挑战。

如果你的需求超过了单台机器的资源限制,那就去找Docker Swarm吧。


在实际的Oracle Java杂志上有一篇关于使用DoCKER与流浪者(和傀儡)结合的信息性文章:

结论

Docker’s lightweight containers are faster compared with classic VMs
and have become popular among developers and as part of CD and DevOps
initiatives. If your purpose is isolation, Docker is an excellent choice.
Vagrant is a VM manager that enables you to script configurations of
individual VMs as well as do the provisioning. However, it is sill a
VM dependent on VirtualBox (or another VM manager) with relatively
large overhead. It requires you to have a hard drive idle that can be
huge, it takes a lot of RAM, and performance can be suboptimal. Docker
uses kernel cgroups and namespace isolation via LXC. This means that
you are using the same kernel as the host and the same ile system.
Vagrant is a level above Docker in terms of abstraction, so they are
not really comparable. Configuration management tools such as Puppet are
widely used for provisioning target environments. Reusing existing
Puppet-based solutions is easy with Docker. You can also slice your
solution, so the infrastructure is provisioned with Puppet; the
middleware, the business application itself, or both are provisioned
with Docker; and Docker is wrapped by Vagrant. With this range of
tools, you can do what’s best for your scenario.

如何在DevOps中构建、使用和协调Docker容器http://www.javamagazine.mozaicreader.com/Julyaug 2015&;pageset=34&;page=0