1. 概要

今日の展開と運用の世界では、物理サーバー上で直接サービスを実行することは珍しいことです。 多くの場合、仮想ホスト(オンプレミスまたはクラウド)を使用するか、Dockerなどのコンテナーを使用するかを決定します。

より高度な抽象化に向けたこの動きには、 Infrastructure as Code(IaC)とKubernetesなどのコンテナオーケストレーションの習得が必要です。 しかし、より小さなステップを使用していくつかの利点を実装できます。

このチュートリアルでは、仮想化とコンテナ化について説明します。 技術的な違いとトレードオフを比較します。

2. なぜ抽象化?

最も単純な構成では、サーバーコンピューターにインストールされているオペレーティングシステム(Linux、Windowsなど)でアプリケーションとサービスをホストします。

これは、無数の中小企業のサーバールームで一般的です。

ただし、データセンターとクラウドでの広範な仮想化は2000年代半ばに始まりました。 Dockerが主導するコンテナの使用は、2010年代半ばに標準化され、注目を集めました。

これらのテクノロジーの採用を推進し続けているものは何ですか?

このようにサービスを実行すると、次のような利点が得られます。

柔軟性とスケーラビリティ:サーバーの機能を拡張または縮小する必要がある場合は、構成を簡単に変更したり、別のホストにコピーしたりできます。 より多くのサービスを実行する必要がある場合は、より多くの仮想マシンやクラウドインスタンスを起動したり、ポッドにコンテナーを追加したりできます。

リソース使用率:何かを処理するために多数のサーバーが必要な場合でも、月に1回だけ、残りの時間はそれらのサーバーをアイドル状態に保つ必要はありません。 ハードウェア(コンピューティングおよびストレージ)リソースを必要に応じて動的に割り当てることができます

プロセスの分離:モノリシックシステムにインストールされているさまざまなサービスを追跡する代わりに、各サービスのコード、構成、および依存関係を分離しておくことができます。 つまり、あるものを更新して別のものを壊すことはありません。 また、1つの空腹のアプリケーションが他のすべてのアプリケーションの速度を低下させないようにすることができます

構成と変更の管理:重要なシステムを変更する必要がある場合は、仮想マシンのスナップショットを作成できます。 事態が非常にうまくいかない場合は、変更をすぐに取り消すことができ、以前よりも悪化することはありません。 また、一度に1つのサービスに対応する場合、構成と変更の文書化ははるかに簡単になります。 また、Infrastructure as Codeに移行し、TerraformやAnsibleなどのツールを使用して構成を作成する場合、これらの定義は、忘れられた、または「今のところ」インフラストラクチャの変更を回避するのに役立ちます。

3. 仮想化の基本

仮想化とは、ソフトウェアで仮想マシンを実行することです。 「ホスト」システムは、通常ハイパーバイザーと呼ばれる仮想化ソフトウェアを実行します。 「ゲスト」システムはハイパーバイザーで実行されます。 「ゲスト」オペレーティングシステムは、ハードウェア(「ベアメタル」)上で直接実行されていないことをほとんどまたはまったく認識していません。

仮想化ソフトウェアのいくつかの例:

これらのツールを使用して、Wikiやそのデータベース、またはネットワーク監視スイートなどのアプリケーションを提供できます。

開発デスクトップでこれらのツールを使用して、他の環境で安全に実験することもできます。

2000年代半ばに、IntelとAMDはCPUに仮想化拡張機能を追加しました(Intel VTとAMD-V、またはSVMモード)。 これらは、今日のサーバーの標準機能です。 ただし、デスクトップでは、BIOS設定でそれらを有効にする必要がある場合があります。 このハードウェア支援により、ハイパーバイザーが大幅に簡素化および高速化されます。

3.1. 仮想マシンで何ができるか?

「ベアメタル」サーバーのインストールではなく仮想マシンイメージを使用すると、移植性が向上します。仮想マシンイメージは標準化されているため、必要に応じてホストマシン間で簡単に移動できます。 多くのハイパーバイザーは、仮想マシンが1つの物理マシンから別の物理マシンにシームレスに転送されるときに、仮想マシンが引き続き実行されるライブマイグレーションもサポートしています。

AWS、GCP、Azureなどのクラウドサービスは、仮想OSのインストール以上のものを提供します。 ただし、それらの基盤は仮想マシンインスタンスに基づいています。 新しいハードウェアを購入してUbuntuServerを自分でインストールする必要はありません。 支払いたいRAMおよびCPUリソースを指定し、特定のOSを要求するだけで、すぐに使用できます。

仮想マシンは、オペレーティングシステムのフルインストールと同様に、起動して独自の機能をすべて提供する必要があります。 それぞれが完全に異なるLinuxカーネルまたはディストリビューションを実行する場合があります。 WindowsやBSDなどの別のOSを完全に実行する場合があります。 これにより、ゲストは互いに完全に隔離され、セキュリティが向上し、構成と依存関係が簡素化されます。 また、より重く、より多くのスペースとより多くのCPUを占有します。

ユーザーの観点からは、仮想マシンは物理マシンとまったく同じように見えます。

4. コンテナの基本

コンテナエンジン(Dockerなど)はフルOS(Linuxなど)で実行されます。 OSは、カーネルと関連サービス(ファイルシステム、ネットワーキング、プロセス管理)を提供します。

コンテナは、特定のサービスを実行するために必要な他のすべてを提供します。

  • コードまたはアプリケーションバイナリ
  • ライブラリなどの依存関係
  • おそらく、PythonやJREなどのインタプリタまたはランタイム
  • 環境設定やユーザーアカウントなどの構成とローカリゼーション

これらの要素はすべて、特定のバージョンに固定されています。 node のpackage-lock.jsonファイル、または pip のrequirements.txtを考えてみてください。コンテナーは、特定のイメージのコマンドとライブラリを使用します。 画像から最新バージョンを使用するように依頼することも、正確なバージョンを指定することもできます。 このように、コンテナーを使用するときは、ソフトウェアの環境も指定します(ホストOSによって決定されるカーネルバージョンは別として)。

4.1. Dockerの役割

私たちの多くにとって、「Docker」と「containers」は同義語です。 また、他のコンテナエンジン(RedHatのPodman など)が存在することはわかっていますが、Dockerエコシステムからコンテナアーキテクチャと使用法の基本を学ぶことができます。

Dockerはまた、コンテナイメージの巨大なライブラリをホストし、そこから独自のローカルコンテナを構築して実行できます。

コンテナイメージは、実行中のコンテナのテンプレートのように機能します。コンテナランタイムがそれらをロードして実行すると、コンテナになります。 コンテナは、使用しているカーネルとオペレーティングシステム上で実行され、必要な他のすべてのものを追加します。 多くの場合、人気のある「alpine」などの最小限のソースイメージに基づいて構築されます。

コンテナイメージを使用する際の主な焦点は、特定のアプリまたはサービスとそれに付随するすべての依存関係をバンドルすることです。 たとえば、JavaWARアーカイブをそのサーバーと一緒にデプロイできます。

Docker用語では、DockerHubからイメージをプルします。 次に、コンテナーエンジンまたはランタイムでローカルに実行します(containerd、Dockerのエンジン、CRI-Oなど)。

4.2. ユニオンまたはオーバーレイファイルシステム

コンテナは仮想マシンよりも大幅に小さくなっています。 これは、ストレージが少なくなるだけでなく、起動時間がほぼ瞬時になることを意味します。

すでに述べたように、コンテナイメージには、アプリケーションに必要なオペレーティングシステムの要素のみを選択的に含めることができます。

サイズが小さいことのもう1つの秘密は、独自のファイルシステムを使用する代わりに、ベースイメージのファイルシステムに要素を重ねる方法にあります。 ベースは読み取り専用のままであり、変更はコンテナ内のローカルレイヤーでのみ発生します。

システムが同じベースイメージから派生したコンテナを実行する場合、読み取り専用レイヤーのコピーが1つだけ必要です。 より多くのスペース節約!

4.3. ホストされたコンテナ

コンテナを使用して、開発、テスト、および本番環境との同期を保つことができます。 これ以上「しかし、それは私のマシンで動作します!」

本番環境でそれらを使用する場合、デプロイメントの一部としてイメージを自分でプル、カスタマイズ、および実行できます。 ただし、これをクラウドインスタンスで実行したとしても、多くの管理と運用作業が必要になります。

クラウドプロバイダーは、コンテナーイメージの直接操作をサポートしています。 たとえば、 Amazon Fargate は画像を受け入れ、いくつかのリソース構成の後でそれを利用できるようにします。

コンテナオーケストレーションのデファクトスタンダードであるKubernetesは、コンテナ化されたアプリケーションに高可用性と自己修復を追加します。 また、さらに複雑になります。 まだk8が必要だとは思わないかもしれませんが、アプリケーションをコンテナ化して準備することで、将来の拡張に備えることができます。

5. 結論

仮想マシンとコンテナは同様の問題を解決します。 ただし、仮想マシンは、インスタンスごとにはるかに多くのオーバーヘッド、イメージング、およびオペレーティングシステム全体の実行を伴います。

コンテナは、単一のオペレーティングシステムで実行されるか、オーケストレーションを介してグループで実行されます。 簡単に交換できる軽量サービスを提供します。

この記事では、完全な仮想マシンの実行と、コンテナーでのアプリケーションの実行を比較しました。

仮想マシンは、柔軟性も必要な長期的なインストールに役立つ場合があります。 コンテナは他のほとんどすべてにうまく機能します。