DockerとフルVMの違いを理解するために、Dockerのドキュメントを読み続けています。どのようにして、それほど重いものではなく、完全なファイルシステム、分離されたネットワーク環境などを提供するのですか?
ソフトウェアをDockerイメージに展開する(正しい場合)のは、一貫した本番環境に単に展開するよりも簡単なのはなぜですか。
DockerとフルVMの違いを理解するために、Dockerのドキュメントを読み続けています。どのようにして、それほど重いものではなく、完全なファイルシステム、分離されたネットワーク環境などを提供するのですか?
ソフトウェアをDockerイメージに展開する(正しい場合)のは、一貫した本番環境に単に展開するよりも簡単なのはなぜですか。
回答:
Dockerは当初LinuX Containers(LXC)を使用していましたが、その後、ホストと同じオペレーティングシステムで実行されるrunC(以前はlibcontainerと呼ばれていました)に切り替えました。これにより、ホストオペレーティングシステムリソースの多くを共有できます。また、階層化ファイルシステム(AuFS)を使用し、ネットワークを管理します。
AuFSは階層化されたファイルシステムであるため、読み取り専用部分と書き込み部分をマージすることができます。オペレーティングシステムの共通部分を読み取り専用(およびすべてのコンテナー間で共有)にし、各コンテナーに書き込み用の独自のマウントを与えることができます。
したがって、1 GBのコンテナイメージがあるとします。フルVMを使用する場合は、1 GB x必要な数のVMが必要です。DockerとAuFSを使用すると、すべてのコンテナー間で1 GBの大部分を共有できます。1000のコンテナーがある場合でも、コンテナーのOSには1 GBを少し超えるスペースしかない場合があります(すべてが同じOSイメージを実行している場合) 。
完全仮想化システムは、それに割り当てられた独自のリソースのセットを取得し、最小限の共有を行います。あなたはより多くの分離を得ますが、それはより重いです(より多くのリソースを必要とします)。Dockerを使用すると分離が少なくなりますが、コンテナーは軽量です(必要なリソースが少なくなります)。したがって、ホスト上で何千ものコンテナを簡単に実行でき、点滅することもありません。Xenでそれを試してみてください、そしてあなたが本当に大きなホストを持っていない限り、それは可能ではないと思います。
完全仮想化システムの起動には通常数分かかりますが、Docker / LXC / runCコンテナは数秒、多くの場合は1秒もかかりません。
仮想化システムのタイプごとに長所と短所があります。リソースが保証された完全な分離が必要な場合は、完全なVMが適しています。プロセスを互いに分離し、適切なサイズのホストで大量のプロセスを実行したい場合は、Docker / LXC / runCが適しています。
詳細については、LXCがどのように機能するかを説明するために役立つ一連のブログ投稿をチェックしてください。
ソフトウェアをDockerイメージ(正しい用語の場合)に展開する方が、一貫した運用環境に展開するよりも簡単なのはなぜですか?
一貫した本番環境の導入は、言うより簡単です。ChefやPuppetなどのツールを使用していても、ホストと環境の間でOSの更新やその他の変更が常に発生します。
Dockerを使用すると、OSを共有イメージにスナップショットでき、他のDockerホストに簡単にデプロイできます。ローカル、dev、qa、prodなど:すべて同じイメージ。もちろん、他のツールを使用してこれを行うことはできますが、それほど簡単または高速ではありません。
これはテストに最適です。データベースに接続する必要のある何千ものテストがあり、各テストにはデータベースの元のコピーが必要で、データに変更を加えるとします。これに対する古典的なアプローチは、カスタムコードまたはFlywayのようなツールを使用して、すべてのテストの後にデータベースをリセットすることです。これは非常に時間がかかり、テストを連続して実行する必要があることを意味します。ただし、Dockerを使用すると、データベースのイメージを作成し、テストごとに1つのインスタンスを実行し、データベースの同じスナップショットに対してすべてのテストが実行されることがわかっているため、すべてのテストを並行して実行できます。テストは並行して実行され、Dockerコンテナーで実行されるため、すべてを同じボックスで同時に実行することができ、より速く終了するはずです。フルVMでそれを試してください。
コメントから...
面白い!「OSのスナップショット」という概念にまだ混乱していると思います。OSのイメージを作成せずに、どうやってそれを行うのでしょうか。
さて、私が説明できるか見てみましょう。基本イメージから始めて、変更を加え、Dockerを使用してそれらの変更をコミットすると、イメージが作成されます。この画像には、ベースとの違いのみが含まれています。イメージを実行する場合は、ベースも必要です。これは、レイヤードファイルシステムを使用してベースの上にイメージをレイヤー化します。前述のように、DockerはAuFSを使用します。AuFSは異なるレイヤーをマージし、必要なものを取得します。実行するだけです。ますます多くの画像(レイヤー)を追加し続けることができ、差分のみを保存し続けます。Dockerは通常、レジストリの既製のイメージの上に構築するため、OS全体を自分で「スナップショット」する必要はほとんどありません。
HISTORY The jail utility appeared in FreeBSD 4.0.
仮想化とコンテナーが低レベルでどのように機能するかを理解することが役立つ場合があります。それは多くのことを片付けるでしょう。
注:以下の説明では、少し簡略化しています。詳細については、リファレンスを参照してください。
仮想化は低レベルでどのように機能しますか?
この場合、VMマネージャーはCPUリング0(または新しいCPUの「ルートモード」)を引き継ぎ、ゲストOSが行ったすべての特権呼び出しを傍受して、ゲストOSが独自のハードウェアを持っているように見せかけます。おもしろい事実:1998年以前は、この種のインターセプトを行う方法がなかったため、x86アーキテクチャでこれを実現することは不可能であると考えられていました。VMWareの人々は、これを実現するためにゲストOSの特権呼び出しのためにメモリ内の実行可能バイトを書き換えるという考えを持った最初の人でした。
最終的には、仮想化により、同じハードウェア上で2つのまったく異なるOSを実行できるようになります。各ゲストOSは、ブートストラップ、カーネルのロードなどのすべてのプロセスを実行します。たとえば、ゲストOSはホストOSまたは他のゲストへのフルアクセスを取得できず、混乱を招く可能性があります。
コンテナは低レベルでどのように機能しますか?
2006年頃、Googleの一部の従業員を含む人々が名前空間と呼ばれる新しいカーネルレベルの機能を実装しました(ただし、そのアイデアはFreeBSDにずっと以前から存在していました))。OSの機能の1つは、ネットワークやディスクなどのグローバルリソースをプロセスに共有できるようにすることです。これらのグローバルリソースが名前空間にラップされていて、同じ名前空間で実行されているプロセスにのみ表示される場合はどうなりますか?たとえば、ディスクのチャンクを取得して名前空間Xに配置すると、名前空間Yで実行されているプロセスはそれを表示またはアクセスできなくなります。同様に、名前空間Xのプロセスは、名前空間Yに割り当てられているメモリ内の何にもアクセスできません。もちろん、Xのプロセスは、名前空間Yのプロセスを参照または通信できません。これにより、一種の仮想化とグローバルリソースの分離が提供されます。これがdockerの仕組みです。各コンテナーは独自の名前空間で実行されますが、まったく同じものを使用します他のすべてのコンテナと同様にカーネル。分離が発生するのは、カーネルがプロセスに割り当てられた名前空間を認識しており、API呼び出し中に、プロセスが自分の名前空間のリソースにのみアクセスできるようにするためです。
コンテナーとVMの制限は明らかになりました。VMのようにコンテナー内で完全に異なるOSを実行することはできません。ただし、同じカーネルを共有しているため、Linuxのさまざまなディストリビューションを実行できます。分離レベルはVMほど強力ではありません。実際、初期の実装では、「ゲスト」コンテナがホストを引き継ぐ方法がありました。また、新しいコンテナをロードすると、OSの新しいコピー全体がVMの場合のように起動しないこともわかります。すべてのコンテナーが同じカーネルを共有する。これが、コンテナが軽量である理由です。また、VMとは異なり、OSの新しいコピーを実行していないため、コンテナーに大量のメモリを事前に割り当てる必要はありません。これにより、1つのOSで数千のコンテナをサンドボックス化しながら実行できますが、独自のVMでOSの個別のコピーを実行している場合は実行できません。
ケンコクランの答えが好きです。
ただし、ここでは詳しく説明しませんが、視点を追加したいと思います。私の意見では、Dockerはプロセス全体でも異なります。VMとは対照的に、Dockerはハードウェアの最適なリソース共有について(だけ)ではなく、アプリケーションをパッケージ化するための「システム」を提供します(マイクロサービスのセットとして推奨されますが、必須ではありません)。
私には、rpm、Debianパッケージ、Maven、npm + Git などの開発者向けツールと、Puppet、VMware、Xen などのopsツールのギャップに収まります。
ソフトウェアをDockerイメージ(正しい用語の場合)に展開する方が、一貫した運用環境に展開するよりも簡単なのはなぜですか?
あなたの質問は、一定の生産環境を前提としています。しかし、どのように一貫性を保つのですか? パイプラインのステージで、サーバーとアプリケーションの一部(> 10)を検討します。
これを同期させるには、Puppet、Chef、独自のプロビジョニングスクリプト、未公開のルール、多数のドキュメントなどの使用を開始します。理論的には、サーバーは無期限に実行でき、完全に一貫性があり、最新の状態に保たれます。練習ではサーバーの構成を完全に管理できないため、構成のドリフトや実行中のサーバーへの予期しない変更のかなりの範囲があります。
そのため、これを回避するための既知のパターン、いわゆる不変サーバーがあります。しかし、不変のサーバーパターンは愛されていませんでした。主に、Docker以前に使用されていたVMの制限が原因です。数ギガバイトの大きな画像を処理し、それらの大きな画像を移動して、アプリケーションの一部のフィールドを変更するだけでは、非常に骨が折れました。わかりました...
Dockerエコシステムを使用すると、「小さな変更」でギガバイト単位で移動する必要がなくなり(aufsとRegistryに感謝)、実行時にアプリケーションをDockerコンテナーにパッケージ化することでパフォーマンスが低下することを心配する必要がありません。そのイメージのバージョンについて心配する必要はありません。
そして最後に、Linuxラップトップでも複雑な本番環境を再現できることがよくあります(あなたのケースでうまくいかない場合は電話しないでください;))
そしてもちろん、VMでDockerコンテナーを起動することもできます(これは良い考えです)。VMレベルでのサーバープロビジョニングを減らします。上記はすべてDockerで管理できます。
PS一方、DockerはLXCではなく、独自の実装「libcontainer」を使用します。ただし、LXCは引き続き使用できます。
Dockerは仮想化手法ではありません。コンテナベースの仮想化またはオペレーティングシステムレベルの仮想化を実際に実装する他のツールに依存しています。そのため、Dockerは最初はLXCドライバーを使用していましたが、libcontainerに移動され、現在はruncに名前が変更されています。Dockerは主に、アプリケーションコンテナー内のアプリケーションのデプロイメントの自動化に焦点を当てています。アプリケーションコンテナは単一のサービスをパッケージ化して実行するように設計されていますが、システムコンテナは仮想マシンのように複数のプロセスを実行するように設計されています。そのため、Dockerはコンテナー化されたシステムでのコンテナー管理またはアプリケーション展開ツールと見なされます。
他の仮想化との違いを知るために、仮想化とその種類について見ていきましょう。そうすれば、違いが何であるかを理解しやすくなります。
仮想化
複数のアプリケーションを同時に実行できるように、メインフレームを論理的に分割する方法と考えられていました。ただし、企業とオープンソースコミュニティが特権命令を何らかの方法で処理する方法を提供し、複数のオペレーティングシステムを単一のx86ベースのシステムで同時に実行できるようになると、シナリオは大幅に変わりました。
ハイパーバイザー
ハイパーバイザーは、ゲスト仮想マシンが動作する仮想環境の作成を処理します。ゲストシステムを監視し、必要に応じてリソースがゲストに割り当てられるようにします。ハイパーバイザーは物理マシンと仮想マシンの間に位置し、仮想マシンに仮想化サービスを提供します。これを実現するために、仮想マシン上のゲストオペレーティングシステムの操作をインターセプトし、ホストマシンのオペレーティングシステム上の操作をエミュレートします。
主にクラウドでの仮想化テクノロジーの急速な発展により、Xen、VMware Player、KVMなどのハイパーバイザーを使用して単一の物理サーバー上に複数の仮想サーバーを作成できるようになり、仮想化の使用がさらに促進されました。 Intel VTやAMD-Vなどのコモディティプロセッサにハードウェアサポートを組み込む。
仮想化のタイプ
仮想化方法は、ハードウェアをゲストオペレーティングシステムに模倣し、ゲストオペレーティング環境をエミュレートする方法に基づいて分類できます。主に、3種類の仮想化があります。
エミュレーション
完全仮想化としても知られるエミュレーションは、仮想マシンOSカーネルを完全にソフトウェアで実行します。このタイプで使用されるハイパーバイザーは、タイプ2ハイパーバイザーと呼ばれます。これは、ゲストOSカーネルコードをソフトウェア命令に変換する役割を持つホストオペレーティングシステムの上部にインストールされます。翻訳はすべてソフトウェアで行われ、ハードウェアの関与は必要ありません。エミュレーションを使用すると、エミュレートされる環境をサポートする、変更されていないオペレーティングシステムを実行できます。このタイプの仮想化の欠点は、他のタイプの仮想化と比較してパフォーマンスの低下につながる追加のシステムリソースオーバーヘッドです。
このカテゴリの例には、VMware Player、VirtualBox、QEMU、Bochs、Parallelsなどが含まれます。
準仮想化
タイプ1ハイパーバイザーとも呼ばれる準仮想化は、ハードウェアまたは「ベアメタル」で直接実行され、仮想化サービスを、その上で実行されている仮想マシンに直接提供します。オペレーティングシステム、仮想化ハードウェア、および実際のハードウェアが協調して最適なパフォーマンスを実現するのに役立ちます。これらのハイパーバイザーは通常、フットプリントがかなり小さく、それ自体は、広範なリソースを必要としません。
このカテゴリの例には、Xen、KVMなどが含まれます。
コンテナベースの仮想化
コンテナベースの仮想化は、オペレーティングシステムレベルの仮想化とも呼ばれ、単一のオペレーティングシステムカーネル内で複数の分離された実行を可能にします。可能な限り最高のパフォーマンスと密度を備え、動的リソース管理を備えています。このタイプの仮想化によって提供される分離された仮想実行環境はコンテナーと呼ばれ、トレースされたプロセスのグループと見なすことができます。
コンテナーの概念は、Linuxカーネルバージョン2.6.24に追加された名前空間機能によって可能になりました。コンテナーは、そのIDをすべてのプロセスに追加し、新しいアクセス制御チェックをすべてのシステムコールに追加します。以前にグローバルな名前空間の個別のインスタンスを作成できるclone()システムコールによってアクセスされます。
名前空間はさまざまな方法で使用できますが、最も一般的なアプローチは、コンテナの外部にあるオブジェクトへの可視性やアクセス権がない隔離されたコンテナを作成することです。コンテナー内で実行されているプロセスは、通常のLinuxシステムで実行されているように見えますが、他の種類のオブジェクトと同様に、他の名前空間にあるプロセスとカーネルを共有しています。たとえば、名前空間を使用する場合、コンテナー内のrootユーザーはコンテナー外のrootとして扱われず、セキュリティが強化されます。
コンテナーベースの仮想化を可能にする次の主要コンポーネントであるLinux Control Groups(cgroups)サブシステムは、プロセスをグループ化し、それらの総リソース消費を管理するために使用されます。コンテナーのメモリとCPUの消費を制限するために一般的に使用されます。コンテナー化されたLinuxシステムにはカーネルが1つしかなく、カーネルはコンテナーに対する完全な可視性を持っているため、リソースの割り当てとスケジューリングのレベルは1つだけです。
Linuxコンテナーでは、LXC、LXD、systemd-nspawn、lmctfy、Warden、Linux-VServer、OpenVZ、Dockerなど、いくつかの管理ツールを使用できます。
コンテナーと仮想マシン
仮想マシンとは異なり、コンテナーはオペレーティングシステムのカーネルを起動する必要がないため、コンテナーは1秒未満で作成できます。この機能により、コンテナーベースの仮想化は他の仮想化アプローチよりもユニークで望ましいものになります。
コンテナベースの仮想化はホストマシンにオーバーヘッドをほとんどまたはまったく追加しないため、コンテナベースの仮想化はネイティブに近いパフォーマンスを発揮します
コンテナベースの仮想化の場合、他の仮想化とは異なり、追加のソフトウェアは必要ありません。
ホストマシン上のすべてのコンテナは、ホストマシンのスケジューラを共有して、追加のリソースを節約します。
コンテナー状態(DockerまたはLXCイメージ)は、仮想マシンイメージに比べてサイズが小さいため、コンテナーイメージの配布は簡単です。
コンテナー内のリソース管理は、cgroupsによって実現されます。cgroupsは、コンテナーが割り当てられているよりも多くのリソースを消費することを許可しません。ただし、現時点では、ホストマシンのすべてのリソースは仮想マシンに表示されますが、使用できません。これは、実行することによって実現することができtop
たりhtop
、同時にコンテナとホストマシン上で。すべての環境での出力は同じようになります。
更新:
Dockerは非Linuxシステムでコンテナーをどのように実行しますか?
Linuxカーネルで利用可能な機能のためにコンテナーが可能である場合、明らかな問題は、非Linuxシステムがコンテナーをどのように実行するかです。Docker for MacとWindowsはどちらもLinux VMを使用してコンテナーを実行します。Virtual Box VMでコンテナーを実行するために使用されるDocker Toolbox。ただし、最新のDockerはWindowsではHyper-V、MacではHypervisor.frameworkを使用しています。
ここで、Docker for Macがコンテナーを実行する方法について詳しく説明します。
Docker for Macはhttps://github.com/moby/hyperkitを使用してハイパーバイザー機能をエミュレートし、Hyperkitはコアでhypervisor.frameworkを使用します。Hypervisor.frameworkは、Macのネイティブハイパーバイザーソリューションです。Hyperkitは、VPNKitとDataKitを使用して、それぞれネットワークとファイルシステムの名前空間を設定します。
DockerがMacで実行するLinux VMは読み取り専用です。ただし、次のコマンドを実行することでbashを実行できます。
screen ~/Library/Containers/com.docker.docker/Data/vms/0/tty
。
これで、このVMのカーネルバージョンを確認することもできます。
# uname -a
Linux linuxkit-025000000001 4.9.93-linuxkit-aufs #1 SMP Wed Jun 6 16:86_64 Linux
。
すべてのコンテナはこのVM内で実行されます。
hypervisor.frameworkにはいくつかの制限があります。そのため、Dockerはdocker0
Macのネットワークインターフェイスを公開しません。したがって、ホストからコンテナにアクセスすることはできません。現在、docker0
はVM内でのみ使用できます。
Hyper-vはWindowsのネイティブハイパーバイザーです。また、Windows 10の機能を活用してLinuxシステムをネイティブに実行しようとしています。
この投稿を通じて、VMとLXCの違いをいくつか説明します。まずそれらを定義しましょう。
VM:
仮想マシンは物理的なコンピューティング環境をエミュレートしますが、CPU、メモリ、ハードディスク、ネットワーク、その他のハードウェアリソースに対する要求は、これらの要求を基盤となる物理ハードウェアに変換する仮想化レイヤーによって管理されます。
このコンテキストでは、VMはゲストと呼ばれ、VMが実行される環境はホストと呼ばれます。
LXC s:
Linuxコンテナー(LXC)は、1つの制御ホスト(LXCホスト)で複数の分離されたLinuxコンテナーを実行できるようにするオペレーティングシステムレベルの機能です。Linuxコンテナーはハイパーバイザーvizを必要としないため、VMの軽量な代替として機能します。Virtualbox、KVM、Xenなど
あなたがアラン(ザックガリフィアナキス-二日酔いシリーズから)によって薬物を服用され、昨年ラスベガスに滞在していない限り、Linuxコンテナーテクノロジーに対する多大な関心が高まっていること、そして私が特定の1つのコンテナーであるかどうかについては十分に理解できるでしょう。過去数か月の間に世界中で話題を呼んだプロジェクトは– Dockerは、クラウドコンピューティング環境は仮想マシン(VM)を放棄し、オーバーヘッドが低く、パフォーマンスが向上する可能性があるため、仮想マシン(VM)をコンテナーに置き換える必要があるという反響を呼んでいます。
しかし、大きな問題は、それは実現可能ですか?、それは賢明でしょうか?
a。LXCのスコープはLinuxのインスタンスです。Linuxのフレーバーは異なる場合があります(たとえば、CentOSホスト上のUbuntuコンテナーですが、それでもLinuxです)。同様に、Windowsベースのコンテナーは、かなり広い範囲のVMを見て、ハイパーバイザーは、オペレーティングシステムLinuxまたはWindowsに限定されません。
b。LXCはオーバーヘッドが低く、VMと比較してパフォーマンスが優れています。ツールviz。LXCテクノロジーの肩の上に構築されたDockerは、アプリケーションを実行するためのプラットフォームを開発者に提供すると同時に、運用サーバーやデータセンターに同じコンテナーを展開できるツールを運用担当者に提供しました。アプリケーションの実行、アプリケーションの起動とテスト、およびそのアプリケーションを展開する運用担当者の間のエクスペリエンスをシームレスにすることを試みます。これは、すべての摩擦が原因であり、DevOpsの目的はそれらのサイロを分解することであるからです。
したがって、最善のアプローチは、クラウドインフラストラクチャプロバイダーがVMとLXCの適切な使用を提唱することです。これらはそれぞれ特定のワークロードとシナリオの処理に適しているためです。
VMを破棄することは、現時点では実用的ではありません。そのため、VMとLXCの両方に独自の存在と重要性があります。
ここでの答えのほとんどは、仮想マシンについて語っています。Dockerの使用の過去2年間で私を最も助けてくれたこの質問に対して、一言で回答します。これです:
Dockerは仮想マシンではなく、プロセスを実行するための優れた方法です。
それでは、それが何を意味するかについてもう少し説明しましょう。仮想マシンは自分の獣です。私は何を説明するように感じるドッカーがあることは、あなたがより多くの仮想マシンが何であるかを説明するよりも、このことを理解するのに役立ちます。特に、「仮想マシン」と言ったときに誰かが何を意味するのかを正確に伝える多くの良い答えがあるからです。そう...
Dockerコンテナーは、ホストシステムのカーネル内の残りのプロセスからのcgroupを使用して区分化された単なるプロセス(およびその子)です。ps aux
ホスト上で実行すると、実際にDockerコンテナープロセスを確認できます。たとえば、apache2
「コンテナ内」の開始はapache2
、ホスト上の特別なプロセスとして開始するだけです。マシンの他のプロセスから区分されただけです。コンテナーはコンテナー化されたプロセスの存続期間外には存在しないことに注意することが重要です。プロセスが停止すると、コンテナも停止します。これは、Dockerがpid 1
コンテナー内をアプリケーション(pid 1
通常はinitシステム)に置き換えるためです。この最後の点pid 1
は非常に重要です。
これらのコンテナープロセスのそれぞれで使用されるファイルシステムに関しては、DockerはUnionFSでバックアップされたイメージを使用します。これは、を実行するときにダウンロードするものですdocker pull ubuntu
。各「画像」は、一連のレイヤーと関連するメタデータです。ここでは、レイヤー化の概念が非常に重要です。各レイヤーは、その下のレイヤーからの変更点です。たとえば、Dockerコンテナの作成中にDockerfile内のファイルを削除すると、実際には、「このファイルは削除されました」という最後のレイヤーの上にレイヤーを作成しているだけです。ちなみに、これがファイルシステムから大きなファイルを削除できる理由ですが、イメージは同じ量のディスク容量を占有します。ファイルは、現在のファイルの下のレイヤーにあります。レイヤー自体は単なるファイルのtarballです。あなたはこれをテストすることができますdocker save --output /tmp/ubuntu.tar ubuntu
そしてcd /tmp && tar xvf ubuntu.tar
。その後、周りを見ることができます。長いハッシュのように見えるすべてのディレクトリは、実際には個々のレイヤーです。それぞれにファイル(layer.tar
)とメタデータ(json
)その特定のレイヤーに関する情報。これらのレイヤーは、元の状態の「上の」レイヤーとして保存されるファイルシステムへの変更を説明するだけです。「現在の」データを読み取るとき、ファイルシステムは、変更の最上位層のみを参照しているかのようにデータを読み取ります。ファイルシステムは最上位のレイヤーのみを参照しているため、「前の」レイヤーにまだ存在しているにもかかわらず、ファイルが削除されたように見えるのはそのためです。これにより、各コンテナーの最上位レイヤーのファイルシステムにいくつかの重要な変更が発生した場合でも、完全に異なるコンテナーがファイルシステムレイヤーを共有できます。これにより、コンテナーがベースイメージレイヤーを共有するときに、大量のディスク領域を節約できます。しかしながら、
Dockerのネットワーキングは、(docker0
ホストで呼び出される)イーサネットブリッジと、ホスト上のすべてのコンテナーの仮想インターフェイスを使用して実現されます。docker0
コンテナが互いに「間」で通信するための仮想サブネットを作成します。ここには、コンテナ用のカスタムサブネットの作成や、コンテナが直接アクセスするためのホストのネットワークスタックを「共有」する機能など、ネットワークに関する多くのオプションがあります。
Dockerは非常に速く動いています。そのドキュメントは、私が今まで見た中で最高のドキュメントの一部です。それは一般的によく書かれ、簡潔で正確です。詳細については、入手可能なドキュメントを確認し、Stack Overflowを含め、オンラインで読む他のドキュメントよりも信頼できることをお勧めします。特定の質問がある場合は#docker
、Freenode IRCに参加して質問することを強くお勧めします(FreenodeのWebチャットを使用することもできます!)。
#docker
Freenode IRCのチャネルからprogrammerqに送られます。
Dockerは、すべての依存関係を持つアプリケーションをカプセル化します。
バーチャライザは、通常ベアメタルマシンで実行できるすべてのアプリケーションを実行できるOSをカプセル化します。
どちらも非常に異なります。Dockerは軽量で、LXC / libcontainer(カーネルのネームスペースとcgroupに依存)を使用し、ハイパーバイザー、KVMなどのマシン/ハードウェアエミュレーションを備えていません。重いXen。
DockerとLXCは、サンドボックス化、コンテナー化、およびリソース分離のためのものです。ホストOS(現在はLinuxカーネルのみ)のクローンAPIを使用して、IPC、NS(マウント)、ネットワーク、PID、UTSなどのネームスペースを提供します。
メモリ、I / O、CPUなどはどうですか?これは、特定のリソース(CPU、メモリなど)の仕様/制限を持つグループを作成し、そこにプロセスを配置できるcgroupsを使用して制御されます。LXCに加えて、Dockerはストレージバックエンド(http://www.projectatomic.io/docs/filesystems/)を提供します。たとえば、異なるマウント名前空間間でレイヤーを追加し、レイヤーを共有できるユニオンマウントファイルシステムです。
これは、基本イメージが通常読み取り専用であり、コンテナーがレイヤー内の何かを変更したときにのみ、読み取り/書き込みパーティションに書き込み(別名、コピーオンライト)する強力な機能です。レジストリやイメージのバージョン管理など、他の多くのラッパーも提供します。
通常のLXCでは、いくつかのrootfsが付属しているか、rootfsを共有する必要があります。共有すると、変更が他のコンテナーに反映されます。これらの追加機能の多くにより、DockerはLXCよりも人気があります。LXCは、ネットワークやUIなどの外部エンティティに公開されるプロセスにセキュリティを実装するための組み込み環境で人気があります。Dockerは、一貫した本番環境が期待されるクラウドマルチテナンシー環境で人気があります。
通常のVM(たとえば、VirtualBoxおよびVMware)はハイパーバイザーを使用し、関連するテクノロジーには、最初のOS(ホストOS、またはゲストOS 0)の最初のレイヤーになる専用ファームウェア、またはホストOSで実行されるソフトウェアがあります。 CPU、USB /アクセサリ、メモリ、ネットワークなどのハードウェアエミュレーションをゲストOSに提供します。VMは依然として(2015年の時点で)高セキュリティのマルチテナント環境で人気があります。
Docker / LXCはほとんどの安価なハードウェアで実行できます(新しいカーネルを使用している限り、1 GB未満のメモリでも問題ありません)。通常のVMでは、少なくとも2 GBのメモリなどが必要です。 。ただし、ホストOSのDockerサポートは、WindowsなどのOS(2014年11月現在)では利用できません。Windows、Linux、MacでVMのタイプを実行できる場合があります。
これはおそらく多くのドッカー学習者にとっての第一印象です。
まず、Dockerイメージは通常VMイメージよりも小さいため、ビルド、コピー、共有が簡単になります。
次に、Dockerコンテナは数ミリ秒で起動し、VMは数秒で起動します。
これは、Dockerのもう1つの重要な機能です。画像にはレイヤーがあり、さまざまな画像でレイヤーを共有できるため、さらに省スペースで高速に構築できます。
すべてのコンテナーがUbuntuを基本イメージとして使用する場合、すべてのイメージが独自のファイルシステムを持っているわけではありませんが、同じ下線のubuntuファイルを共有し、独自のアプリケーションデータのみが異なります。
コンテナーをプロセスと考えてください!
ホスト上で実行されているすべてのコンテナは、実際にはさまざまなファイルシステムを持つ一連のプロセスです。それらは同じOSカーネルを共有し、システムライブラリと依存関係のみをカプセル化します。
これはほとんどの場合に有効です(追加のOSカーネルは維持しません)が、コンテナー間で厳密な分離が必要な場合は問題になる可能性があります。
これらはすべて革命ではなく、改善のように見えます。まあ、量的蓄積は質的変化につながります。
アプリケーションの配備について考えてみましょう。新しいソフトウェア(サービス)を導入するか、アップグレードする場合は、新しいVMを作成するのではなく、構成ファイルとプロセスを変更することをお勧めします。更新されたサービスでVMを作成し、それをテスト(DevとQAの間で共有)するため、本番環境へのデプロイには数時間、場合によっては数日もかかります。何か問題が発生した場合は、もう一度始めなければならず、さらに時間を無駄にします。したがって、構成管理ツール(puppet、saltstack、chefなど)を使用して新しいソフトウェアをインストールし、新しいファイルをダウンロードすることをお勧めします。
dockerに関しては、新しく作成されたdockerコンテナーを使用して古いものを置き換えることは不可能です。新しいイメージの構築、QAとの共有、テスト、展開には数分(すべてが自動化されている場合)、最悪の場合は数時間しかかかりません。これは不変インフラストラクチャと呼ばれます。ソフトウェアを維持(アップグレード)せず、代わりに新しいものを作成します。
サービスの提供方法が変わります。私たちはアプリケーションが必要ですが、VMを維持する必要があります(これは面倒で、アプリケーションとはほとんど関係がありません)。Dockerはアプリケーションに集中し、すべてをスムーズにします。
Dockerは基本的にコンテナであり、OSの仮想化をサポートしています。つまり、アプリケーションはOSの完全なインスタンスを持っていると感じますが、VMはハードウェアの仮想化をサポートしています。それは、どのOSでも起動できる物理マシンのようなものです。
Dockerでは、実行中のコンテナーはホストOSカーネルを共有しますが、VMでは独自のOSファイルを持っています。アプリケーションを開発する環境(OS)は、「テスト」や「本番」などのさまざまなサービス環境にデプロイする場合と同じです。
たとえば、ポート4000で実行するWebサーバーを開発して「テスト」環境にデプロイすると、そのポートはすでに他のプログラムによって使用されているため、機能しなくなります。コンテナにはレイヤーがあります。OSに加えたすべての変更は1つ以上のレイヤーに保存され、それらのレイヤーはイメージの一部になるため、イメージがどこに移動しても、依存関係が存在します。
以下の例では、ホストマシンに3つのVMがあります。VMでアプリケーションを完全に分離するために、それぞれがOSファイル、ライブラリ、およびアプリケーションコードの独自のコピーと、OSの完全なメモリ内インスタンスを備えています。 下の図は、コンテナを使用した同じシナリオを示しています。ここでは、コンテナーはカーネルとライブラリーを含むホストオペレーティングシステムを共有するだけなので、OSを起動したり、ライブラリーをロードしたり、これらのファイルのプライベートメモリコストを支払う必要はありません。それらが取る唯一の増分スペースは、アプリケーションがコンテナで実行されるために必要なメモリとディスクスペースです。アプリケーションの環境は専用OSのように感じられますが、アプリケーションは専用ホストにデプロイする場合と同じようにデプロイされます。コンテナ化されたアプリケーションは数秒で起動し、VMの場合よりも多くのアプリケーションのインスタンスがマシンに収まります。
ソース:https : //azure.microsoft.com/en-us/blog/containers-docker-windows-and-trends/
アプリケーションを実行するためのスタックを提供する3つの異なるセットアップがあります(これは、コンテナーとは何か、他のソリューションよりもコンテナーが非常に強力になる理由を認識するのに役立ちます)。
1) Traditional Servers(bare metal)
2) Virtual machines (VMs)
3) Containers
1)従来のサーバースタックは、オペレーティングシステムとアプリケーションを実行する物理サーバーで構成されます。
利点:
生資源の活用
隔離
短所:
2)VMスタックは、オペレーティングシステムを実行する物理サーバーと、仮想マシン、共有リソース、およびネットワークインターフェイスを管理するハイパーバイザーで構成されます。各VMは、ゲストオペレーティングシステム、アプリケーション、またはアプリケーションのセットを実行します。
利点:
短所:
3)コンテナのセットアップ、他のスタックとの主な違いは、コンテナベースの仮想化がホストOSのカーネルを使用して、複数の分離されたゲストインスタンスを処理することです。これらのゲストインスタンスはコンテナと呼ばれます。ホストは、物理サーバーまたはVMのいずれかです。
利点:
短所:
コンテナーのセットアップを以前のものと比較することで、コンテナー化が、これまでで最も速く、最もリソース効率がよく、最も安全なセットアップであると結論付けることができます。コンテナーは、アプリケーションを実行する分離されたインスタンスです。Dockerはある方法でコンテナーを起動し、レイヤーはランタイムストレージを取得します。デフォルトのストレージドライバー(オーバーレイドライバー)は数秒以内に実行され、コンテナーにコミットすると、その上にコピーオンライトレイヤーが作成されます。コンテナ。VMの場合、すべてを仮想化環境にロードするのに約1分かかります。これらの軽量インスタンスは、簡単に交換、再構築、移動できます。これにより、本番環境と開発環境をミラーリングできるようになり、CI / CDプロセスで非常に役立ちます。コンテナが提供できる利点は非常に説得力があり、間違いなくここにとどまります。
に関して:-
「ソフトウェアをDockerイメージに展開するのが、一貫した本番環境に展開するよりも簡単なのはなぜですか?」
ほとんどのソフトウェアは多くの環境に展開されており、通常は次の3つ以上が必要です。
考慮すべき次の要素もあります。
推定されるように、組織のサーバーの合計数が1桁になることはめったになく、3桁になることもよくあります。
つまり、最初から一貫した環境を作成することは、ボリュームがないため(グリーンフィールドのシナリオであっても)十分に困難ですが、サーバーの数が多いこと、新しいサーバーの追加(動的または手動で)、o / sベンダー、アンチウイルスベンダー、ブラウザーベンダーなどからの自動更新、開発者やサーバー技術者が手動でソフトウェアをインストールしたり、設定を変更したりします。繰り返しますが、これは事実上(意図しない)不可能です。環境を一貫性のある状態に保つために(そう、純粋主義者であれば可能ですが、膨大な時間、労力、規律が含まれるため、VMとコンテナー(Dockerなど)が最初に考案されたのはそのためです)。
したがって、「すべての環境の整合性を保つことは非常に難しいため、学習曲線を考慮に入れても、ソフトウェアをDockerイメージに展開する方が簡単ですか?」という質問について考えてみてください。。答えは必ず「はい」になると思いますが、この新しい質問をスタックオーバーフローに投稿する方法は1つしかありません。
違いについてより詳細に説明する答えはたくさんありますが、これは私の非常に簡単な説明です。
重要な違いの1つは、VMがOSを実行するために別のカーネルを使用することです。これが重いため、起動に時間がかかり、より多くのシステムリソースを消費します。
Dockerでは、コンテナはホストとカーネルを共有します。そのため、軽量で、すぐに起動および停止できます。
仮想化では、セットアップの最初にリソースが割り当てられるため、多くの場合、仮想マシンがアイドル状態のとき、リソースは完全には利用されません。Dockerでは、コンテナには固定量のハードウェアリソースが割り当てられておらず、要件に応じてリソースを自由に使用できるため、非常にスケーラブルです。
DockerはUNIONファイルシステムを使用します。Dockerは、コピーオンライトテクノロジーを使用して、コンテナーが消費するメモリ領域を削減します。詳細はこちら
では、仮想マシン、私たちはそのサーバー上のホスト・オペレーティング・システムを持っている、サーバーがあり、その後、我々はハイパーバイザーを持っています。そして、そのハイパーバイザーの上で実行すると、そのサーバー上に、アプリケーションとその依存バイナリ、およびライブラリを備えたゲストオペレーティングシステムがいくつもあります。ゲストOS全体をもたらします。かなり重いです。また、各物理マシンに実際に配置できる量には制限があります。
一方、Dockerコンテナーは少し異なります。サーバーがあります。ホストオペレーティングシステムがあります。ただし、この場合はハイパーバイザーではなく、Dockerエンジンを使用します。この場合、ゲストオペレーティングシステム全体を持ち込むわけではありません。私たちはオペレーティングシステムの非常に薄い層を持っています。そして、コンテナは、そこでカーネル機能に到達するためにホストOSに話しかけることができます。これにより、非常に軽量なコンテナを作成できます。
必要なのは、アプリケーションコードと、必要なバイナリおよびライブラリだけです。また、これらのバイナリとライブラリは、必要に応じて実際に異なるコンテナ間で共有することもできます。そして、これが私たちにできることは、いくつかのことです。彼らははるかに速い起動時間を持っています。そのように数秒で単一のVMを立ち上げることはできません。同様に、それらをできるだけ早くダウンさせることで、非常に迅速にスケールアップとダウンを行うことができます。これについては後で説明します。
すべてのコンテナは、独自のオペレーティングシステムのコピーで実行されていると考えています。独自のファイルシステムやレジストリなどがあり、それは一種のうそです。実際に仮想化されています。
私は実稼働環境でDockerを使用しており、非常にステージングしています。慣れると、マルチコンテナーと分離された環境を構築するのに非常に強力になります。
DockerはLXC(Linuxコンテナー)に基づいて開発され、多くのLinuxディストリビューション、特にUbuntuで完全に動作します。
Dockerコンテナーは分離された環境です。top
Dockerイメージから作成されたDockerコンテナーでコマンドを発行すると表示されます。
その上、dockerFile構成のおかげで、非常に軽量で柔軟です。
たとえば、Dockerイメージを作成してDockerFileを構成し、たとえば実行中にwget 'this'、apt-get 'that'、run 'some shell script'、環境変数の設定などを行うことができます。
マイクロサービスプロジェクトとアーキテクチャでは、Dockerは非常に実行可能な資産です。Docker、Docker swarm、Kubernetes、Docker Composeを使用して、スケーラビリティ、復元力、弾力性を実現できます。
Dockerに関するもう1つの重要な問題は、Docker Hubとそのコミュニティです。たとえば、Prometheus、Grafana、Prometheus-JMX-Exporter、Dockerを使用してカフカを監視するためのエコシステムを実装しました。
それを行うために、zookeeper、kafka、Prometheus、Grafana、jmx-collectorの構成済みDockerコンテナーをダウンロードしてから、YAMLファイルを使用してそれらの一部に独自の構成をマウントしました。このアーキテクチャを複数のサーバーに簡単に移動できる分離性とスケーラビリティ、復元力を備えた単一のマシンで、マルチコンテナのDockersを使用してカフカを監視するためのシステム全体を構築します。
Docker Hubサイトのほかに、quay.ioと呼ばれる別のサイトがあります。このサイトを使用して、独自のDockerイメージダッシュボードを作成し、そこにプル/プッシュできます。Docker HubからDockerイメージを岸壁にインポートして、自分のマシンの岸壁から実行することもできます。
注:そもそもDockerの学習は複雑で難しいように見えますが、慣れてくると、それなしでは作業できません。
Dockerを使用して最初の数日間、間違ったコマンドを発行したり、コンテナーとすべてのデータと構成を誤って削除したことを覚えています。
これがDockerの自己紹介です。
Dockerは、コンテナーの動きを牽引する会社であり、ハイブリッドクラウド全体ですべてのアプリケーションに対応する唯一のコンテナープラットフォームプロバイダーです。今日のビジネスはデジタル変換への圧力にさらされていますが、クラウド、データセンター、アプリケーションアーキテクチャのますます多様化するポートフォリオを合理化しながら、既存のアプリケーションとインフラストラクチャに制約されています。Dockerは、アプリケーションとインフラストラクチャ、開発者とIT運用者の間の真の独立を可能にし、それらの可能性を解き放ち、より優れたコラボレーションとイノベーションのためのモデルを作成します。
したがって、Dockerはコンテナーベースです。つまり、現在のマシンで実行できるイメージとコンテナーがあります。VMのようなオペレーティングシステムは含まれていませんが、Java、Tomcatなどのさまざまな作業パックのパックのようです。
コンテナーを理解すると、Dockerとは何か、VMとはどのように異なるのかがわかります ...
コンテナイメージは、コード、ランタイム、システムツール、システムライブラリ、設定など、それを実行するために必要なすべてを含む、ソフトウェアの軽量なスタンドアロンの実行可能パッケージです。LinuxベースのアプリとWindowsベースのアプリの両方で利用できるコンテナ化されたソフトウェアは、環境に関係なく常に同じように実行されます。コンテナは、開発環境とステージング環境の違いなど、ソフトウェアを周囲から分離し、同じインフラストラクチャで異なるソフトウェアを実行しているチーム間の競合を減らすのに役立ちます。
下の画像にあるように、各コンテナには個別のパックがあり、そのマシンのオペレーティングシステムを共有する単一のマシンで実行されています...それらは安全で出荷が簡単です...
ここには、VMとコンテナーの違い、およびDockerの起源について明確に説明している技術的な答えがたくさんあります。
私にとって、VMとDockerの基本的な違いは、アプリケーションのプロモーションの管理方法です。
VMを使用すると、アプリケーションとその依存関係を1つのVMから次のDEV、UAT、PRDに昇格できます。
Dockerのアイデアは、必要なライブラリーとともにアプリケーションを独自のコンテナー内にバンドルし、コンテナー全体を単一のユニットとしてプロモートすることです。
したがって、VMの最も基本的なレベルでは、アプリケーションとその依存関係を個別のコンポーネントとして宣伝しますが、Dockerを使用すると、すべてを1つのヒットで宣伝します。
そして、そうです。KubernetesやDocker Swarmなどのツールでタスクが大幅に簡略化されますが、コンテナの管理を含むコンテナには問題があります。