我在开发和部署过程中使用Ubuntu,并需要创建一个隔离的环境。
我正在考虑使用Vagrant或Docker来实现这一目的。这两种解决方案有什么优缺点,或者它们之间如何相互比较?
我在开发和部署过程中使用Ubuntu,并需要创建一个隔离的环境。
我正在考虑使用Vagrant或Docker来实现这一目的。这两种解决方案有什么优缺点,或者它们之间如何相互比较?
声明:我是 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相同的工作流程来使用Docker。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专门用于每个项目,则可以是这样。即使如此,它也会牺牲灵活性以获得Docker锁定。如果您曾经决定不再为任何过去、现在或将来的项目使用Docker,则会有更多的移动部件。如果您使用了Vagrant,则有一个移动部件支持其余部分。
"它更快!" - 一旦您拥有可以运行Linux容器的主机,Docker肯定比任何虚拟机启动容器要快。但是启动虚拟机(或远程机器)是一次性成本。在一天的过程中,大多数Vagrant用户实际上从未销毁他们的VM。这是一个奇怪的开发环境优化。在生产中,Docker真正闪耀的地方,我理解需要快速启动/关闭容器。
我希望现在很清楚,将Docker与Vagrant进行比较非常困难,我认为也不正确。对于开发环境,Vagrant更抽象,更通用。 Docker(以及您可以使其像Vagrant一样运行的各种方法)是Vagrant的一个特定用例,忽略了Vagrant提供的其他所有内容。
总之,在高度特定的使用情况下,Docker肯定可以替代Vagrant。在大多数情况下,它是不能替代Vagrant的。Vagrant不会妨碍您使用Docker;实际上,它会尽力使体验更加顺畅。如果您发现这不是真的,我很乐意听取改进建议,因为Vagrant的目标是与任何系统同样良好地工作。vagrant provision
)。 - Tomasz Struczyński我是Docker的作者。
简单来说,如果你想管理机器,应该使用Vagrant。如果你想构建和运行应用程序环境,应该使用Docker。
Vagrant是一个管理虚拟机的工具。Docker是一个将应用程序打包成轻量级容器进行构建和部署的工具。容器可以包含几乎任何软件组件以及它的依赖项(可执行文件、库、配置文件等),并在保证和可重复的运行时环境中执行它。这使得你可以非常容易地构建你的应用程序一次,并在任何地方部署它——在你的笔记本电脑上进行测试,然后在不同的服务器上进行实际部署等。
有一个普遍的误解是你只能在Linux上使用Docker。这是不正确的;你也可以在Mac和Windows上安装Docker。在Mac上安装Docker时,Docker会捆绑一个微型Linux虚拟机(磁盘上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用于构建和运行应用程序环境。
docker build
命令来处理容器的提供和配置。您可以在docs.docker.com上找到如何制作Dockerfile的示例;它非常直观。我先说明一下,我对Docker没有任何经验,只是一个热心的观察者,看到它是一个非常好的解决方案,并且正在获得很多关注。
我在Vagrant方面有相当多的经验,强烈推荐使用它。从VM(虚拟机)角度来看,它显然是一个更加重量级的解决方案,而不是基于LXC(Linux容器)的解决方案。但是,我发现一台性能不错的笔记本电脑(8GB RAM,i5/i7 CPU)可以轻松地运行使用Vagrant/VirtualBox的VM和开发工具。
Vagrant的另一个真正好处就是与Puppet/Chef/shell脚本的集成,用于自动化配置。如果您使用其中一种选项来配置生产环境,您可以创建一个开发环境,该环境与您要实现的生产环境尽可能接近,这正是您想要的。
Vagrant的另一个好处是,您可以将Vagrantfile与应用程序代码一起进行版本控制。这意味着您团队中的每个人都可以共享此文件,并保证每个人都使用相同的环境配置。
有趣的是,Vagrant和Docker实际上可能是互补的。Vagrant可以扩展支持不同的虚拟化提供商,而Docker可能是其中之一,在不久的将来得到支持。请参见https://github.com/dotcloud/docker/issues/404以获取关于该主题的最新讨论。
它们非常互补。
我已经使用VirtualBox、Vagrant和Docker的组合方式进行所有项目的开发数月了,并深刻感受到以下好处。
在Vagrant中,你可以完全摒弃任何Chef solo配置,你只需要让你的vagrant文件准备一个运行单个小shell脚本来安装docker的机器即可。这意味着我每个项目的Vagrant文件几乎都是相同和非常简单的。
以下是一份典型的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的脚本,大致如下:
Now to get all the services I need running I have a docker_start script that looks somthing like this
#!/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-lxc是Vagrant的一个插件,可以使用LXC来进行Vagrant的配置。它没有默认的Vagrant虚拟机(VirtualBox)那么多功能,但比Docker容器更灵活。链接中有一个视频展示了它的功能,值得一看。
同时使用两者是应用交付测试的重要组成部分。我才刚开始接触Docker,并在认真思考一个构建和交付软件过程中存在着巨大复杂性的应用团队。可以想象一下经典的《凤凰项目 / 持续交付》情况。
思路大致如下:
这似乎是Mitchell的声明,即Vagrant适用于开发,与Farley/Humbles在持续交付方面的思考的逻辑延伸。如果作为开发人员,我可以缩短集成测试和应用程序交付的反馈循环,那么高质量的工作环境就会随之而来。
作为开发人员,我不断且一贯地向VM交付容器并更全面地测试应用程序的事实意味着生产发布将进一步简化。
因此,我认为Vagrant正在发展成为利用Docker将对应用程序部署产生的某些惊人后果的一种方式。
肯定是Docker胜出!
你可能知道Vagrant是用于虚拟机管理,而Docker是用于软件容器管理的。如果您不了解它们之间的区别,这里有一个简要的介绍: 软件容器可以与其他软件容器共享同一台机器和内核。使用容器可以节省资金,因为您不必在多个操作系统(内核)上浪费资源,并且您可以将更多的软件打包在一个服务器上,同时保持良好的隔离程度。
当然,这是一个需要特别关注其自身问题和挑战的新领域。
如果您的要求超过单个机器资源限制,请选择Docker Swarm。