私は開発と展開に Ubuntu を使用しており、隔離された環境を作成する必要があります。
この目的のために、Vagrant または Docker のいずれかを検討しています。長所と短所は何ですか、またはこれらのソリューションはどのように比較されますか?
私は Docker の作成者です。
簡単に言うと、マシンを管理したい場合は、Vagrant を使用する必要があります。また、アプリケーション環境を構築して実行する場合は、Docker を使用する必要があります。
Vagrant は、仮想マシンを管理するためのツールです。Docker は、アプリケーションを軽量のコンテナーにパッケージ化することで、アプリケーションを構築およびデプロイするためのツールです。コンテナーは、ほぼすべてのソフトウェア コンポーネントとその依存関係 (実行可能ファイル、ライブラリ、構成ファイルなど) を保持し、保証された反復可能なランタイム環境で実行できます。これにより、アプリを一度ビルドすれば、どこにでも展開することが非常に簡単になります。たとえば、ラップトップでテストし、別のサーバーでライブ展開するなどです。
Linux でのみ Docker を使用できるというのはよくある誤解です。それは正しくありません。Mac と Windows に Docker をインストールすることもできます。Docker を Mac にインストールすると、コンテナーのラッパーとして機能する小さな Linux VM (ディスク上で 25 MB!) がバンドルされます。インストールすると、これは完全に透過的になります。まったく同じ方法で Docker コマンドラインを使用できます。これにより、両方の長所が得られます。コンテナーを使用してアプリケーションをテストおよび開発できます。コンテナーは非常に軽量で、テストと移動が簡単です (たとえば、再利用可能なコンテナーを共有するためのhttps://hub.docker.comを参照してください)。仮想マシンの管理の詳細について心配する必要はありません。仮想マシンは目的を達成するための手段にすぎません。
理論的には、Vagrant を Docker の抽象化レイヤーとして使用することは可能です。これには次の 2 つの理由からお勧めしません。
まず、Vagrant は Docker の適切な抽象化ではありません。Vagrant は、仮想マシンを管理するために設計されました。Docker は、アプリケーションのランタイムを管理するために設計されました。これは、設計上、Docker がより豊富な方法でアプリケーションとやり取りでき、アプリケーションのランタイムに関するより多くの情報を持っていることを意味します。Docker のプリミティブは、プロセス、ログ ストリーム、環境変数、およびコンポーネント間のネットワーク リンクです。Vagrant のプリミティブは、マシン、ブロック デバイス、および ssh キーです。Vagrant は単純にスタックの下位に位置し、コンテナとやり取りできる唯一の方法は、「起動」して「ログイン」できる別の種類のマシンであるかのように装うことです。したがって、確かに、Docker プラグインで「vagrant up」と入力すると、かなりのことが起こります。それは、Docker ができるすべての機能の代わりになりますか? ネイティブ Docker を数日間試してみて、自分の目で確かめてください :)
第二に、ロックインの議論。「抽象化として Vagrant を使用すれば、Docker に縛られることはありません!」. マシンを管理するように設計された Vagrant の観点からは、これは完全に理にかなっています。コンテナは単なる別の種類のマシンではないでしょうか? Amazon EC2 や VMware と同様に、プロビジョニング ツールを特定のベンダーに結び付けないように注意する必要があります。これによりロックインが発生します。Vagrant ですべてを抽象化することをお勧めします。これがDockerの要点を完全に見逃していることを除いて。Docker はマシンをプロビジョニングしません。どこにでもドロップできる軽量のポータブル ランタイムでアプリケーションをラップします。
アプリケーションにどのランタイムを選択するかは、マシンのプロビジョニング方法とは関係ありません! たとえば、他の誰かによってプロビジョニングされたマシン (たとえば、システム管理者が Vagrant を使用してデプロイした EC2 インスタンスなど) や、Vagrant がまったくプロビジョニングできないベアメタル マシンにアプリケーションをデプロイすることはよくあります。逆に、Vagrant を使用して、アプリケーションの開発とは関係のないマシン (たとえば、すぐに使用できる Windows IIS ボックスなど) をプロビジョニングすることもできます。または、Vagrant を使用して、Docker を使用しないプロジェクトのマシンをプロビジョニングすることもできます。たとえば、依存関係の管理とサンドボックス化のために rubygems と rvm の組み合わせを使用する場合があります。
要約すると、Vagrant はマシンの管理用であり、Docker はアプリケーション環境の構築と実行用です。
分離が目的なら、Docker が必要だと思います。
Vagrant は仮想マシン マネージャーです。これにより、仮想マシンの構成とプロビジョニングをスクリプト化できます。ただし、これは依然としてVirtualBox (またはその他) に依存する仮想マシンであり、オーバーヘッドが非常に大きくなります。巨大な可能性のあるハード ドライブ ファイルが必要であり、大量の RAM を必要とし、パフォーマンスがあまり良くない可能性があります。
一方、Docker はLXCを介してカーネル cgroup と名前空間を使用します。これは、ホストと同じカーネルおよび同じファイル システムを使用していることを意味します。docker build
コンテナーのプロビジョニングと構成を処理するために、コマンドでDockerfile を使用できます。docs.docker.com に、 Dockerfileの作成方法の例があります。それは非常に直感的です。
Vagrant を使用する唯一の理由は、Ubuntu ボックスで BSD、Windows、またはその他の非 Linux 開発を行う必要がある場合です。それ以外の場合は、Docker を使用してください。
返信の前に、Docker の経験がまったくないことを認めます。それは、多くの注目を集めている本当に優れたソリューションのように見えるものを熱心に観察すること以外にはありません。
私は Vagrant についてかなりの経験を積んでおり、Vagrant を強くお勧めします。LXC ベースではなく VM ベースであるという点で、これは確かにより重いソリューションです。ただし、まともなラップトップ (8 GB RAM、i5/i7 CPU) では、開発ツールと一緒に Vagrant/VirtualBox を使用して VM を実行しても問題がないことがわかりました。
Vagrant の本当に素晴らしい点の 1 つは、構成を自動化するためのPuppet / Chef /shell スクリプトとの統合です。これらのオプションのいずれかを使用して実稼働環境を構成している場合は、取得するものとほぼ同じ開発環境を作成できます。これはまさにあなたが望むものです。
Vagrant のもう 1 つの優れた点は、アプリケーション コードと共に Vagrantfile をバージョン管理できることです。これは、チームの他の全員がこのファイルを共有できることを意味し、全員が同じ環境構成で作業していることが保証されます。
興味深いことに、Vagrant と Docker は実際には補完的かもしれません。Vagrant は、さまざまな仮想化プロバイダーをサポートするように拡張できます。近い将来、Docker がそのようなプロバイダーの 1 つとしてサポートされる可能性があります。このトピックに関する最近の議論については、https://github.com/dotcloud/docker/issues/404を参照してください。
それらは非常に補完的です。
数か月間、すべてのプロジェクトで VirtualBox、Vagrant、および Docker を組み合わせて使用しており、次の利点を強く感じています。
Vagrant では、Chef のソロ プロビジョニングを完全に廃止できます。vagrant ファイルに必要なのは、docker をインストールする単一の小さなシェル スクリプトを実行するマシンを準備することだけです。これは、すべてのプロジェクトの私の 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 を実行するのに十分な構成しかないという点ですべて同じホストのインフラストラクチャに変換することは、実際にはほとんど作業を意味しません。
興味のある方は、開発環境に関するより詳細な記事を私自身の Web サイト (次の URL) に掲載しています。
Vagrant を使用すると、Docker をプロバイダーとして使用できるようになりました。http://docs.vagrantup.com/v2/docker/。VirtualBox や VMware の代わりに Docker プロバイダーを使用できます。
Vagrant でのプロビジョニングに Docker を使用することもできることに注意してください。これは、Docker をプロバイダーとして使用する場合とは大きく異なります。http://docs.vagrantup.com/v2/provisioning/docker.html
つまり、 ChefまたはPuppetを Dockerに置き換えることができます。Docker をプロバイダー (VM) として、Chef をプロビジョナーとして組み合わせて使用できます。または、VirtualBox をプロバイダーとして使用し、Docker をプロビジョナーとして使用することもできます。
両方を使用することは、アプリケーション配信テストの重要な部分です。私は Docker に関わり始めたばかりで、ソフトウェアの構築と提供が非常に複雑なアプリケーション チームについて真剣に考えています。古典的な Phoenix プロジェクト / 継続的デリバリーの状況を考えてみてください。
思考は次のようになります。
これは、Vagrant は継続的デリバリーにおける Farley/Humbles の考え方と組み合わせた開発用であるという Mitchell の声明の論理的な拡張のようです。私が開発者として、統合テストとアプリケーション配信に関するフィードバック ループを縮小できれば、より高い品質とより良い作業環境が得られます。
開発者として、コンテナを常に一貫して VM に提供し、アプリケーションをより全体的にテストしているという事実は、本番リリースがさらに簡素化されることを意味します。
そのため、Vagrant は、Docker がアプリの展開にもたらすすばらしい結果のいくつかを活用する方法として進化していると思います。