コンテナ化とは
2022年5月23日 // 1 min read
DevOps の導入が成功すれば、密接なコラボレーションとインクリメンタル リリースに役立つ自動化と文化的プラクティスが組み合わさることで、software development lifecycle (ソフトウェア開発ライフサイクル、SDLC) がこれまで以上に期待どおりに実現するようになり、ソフトウェアの信頼性を変革できます。差異が小さくなれば、コードに関する問題が本番環境で発生することも少なくなります。
しかし、問題が発生するのはコードそのものだけではありません。ある人のマシンで機能しても、同僚のノート PC や、さらに悪い場合は、本番環境では異なる動作をする可能性があります。コンテナ化は DevOps プラクティスで使用される技術の一種であり、開発、テスト、本番運用において、マシン間で一貫したソフトウェア環境を確保します。
GitHub では、企業が DevOps プラクティスにおいてコンテナを導入し管理するのを支援するツールを提供しています。その経験を通して、企業がコンテナを SDLC に正常に統合するために考慮する必要のある重要な領域を特定しました。
このガイドでは以下の質問に回答を提供します。
- コンテナ化とは
- コンテナ化の利点とは
- コンテナ化は DevOps においてどのような役割を果たすか
- 一般的なコンテナ化ツールにはどのようなものがあるか
- GitHub はどのようにコンテナ化ツールを取り入れているか
コンテナ化とは
コンテナ化とは、ソフトウェア コードを依存関係やオペレーティング システムとともに、他のコンピューター上で実行可能なスタンドアロン アプリケーションの形式でパッケージ化することです。これらの仮想化環境は設計上軽量で、必要なコンピューティング パワーは比較的少なくて済みます。また、基になるインフラストラクチャを問わず実行でき、移植が可能で、あらゆるプラットフォームで一貫して実行できます。
アプリケーション コード、構成ファイル、operating system (オペレーティング システム、OS) ライブラリ、全ての依存関係を一緒にバンドルすることで、コンテナはソフトウェア開発でよく見られる問題の解決を支援します。よくあるのは、ある環境で開発されたコードを別の環境に移植すると、バグやエラー メッセージが発生するという問題です。たとえば、開発者が Linux 環境でコードをビルドし、それを virtual machine (仮想マシン、VM) や Windows コンピューターに移植すると、コードが想定どおりに動作しなくなることがあります。これに対して、コンテナはホスト インフラストラクチャから独立しており、一貫した開発環境を提供します。
しかし、コンテナが特に優れているのは、簡単に共有できるという点です。コンテナ イメージはコンテナのコード、構成、その他のデータのスナップショットとして機能するファイルであり、これを使用することで SDLC の各ステージで一貫性した環境を迅速に立ち上げることができます。これにより、組織は開発からテスト、運用に至るまで、迅速かつ簡単に作業できる再現性のある環境を作成できるようになります。
アプリケーションのコンテナ化
通常、コンテナはアプリケーションの一部のみを扱い、組織は多数のコンテナを利用してアプリケーション コンポーネントを分離し、それらを連携させて実行します。
たとえば、バックエンドのアプリケーション サーバーのコンテナ、データベース システムのコンテナ、監視ツールを実行するコンテナというように、単純に分かれている場合もあります。一方で、コンテナを使用して複雑なシステムを構築することもできます。たとえば、マイクロサービス アーキテクチャでは、数百あるいは数千のコンテナが存在し、それぞれが大規模なアプリケーションのほんの一部をホストしていることがあります。このような大量のコンテナを管理するために、チームは Kubernetes などのコンテナ オーケストレーション ツールを利用します。そうすることで、組織は本番環境のコンテナをより簡単に管理できます。
このようにアプリケーションを分離することで、アプリケーションの各部分をより簡単に開発できるようになります。また、プログラムが許可なくデータにアクセスするリスクを軽減し、必要に応じて追加のコンテナを迅速にデプロイすることで需要に合わせてスケールできます。また、コンテナには特定の必要なもののみが含まれるため、新しいコンテナを追加するのとアプリケーションを直接実行するのとでは、ほとんど差はありません。
仮想化とコンテナ化の違い
コンテナはよく VM と比較されますが、これはオペレーティング システムを基になるインフラストラクチャから切り離して抽象化するという点で類似しており、同様のタスクに使用されることがあるためです。しかし、コンテナと VM の仕組みには根本的な違いがあります。
仮想化では、組織はさまざまなオペレーティング システムやアプリケーションを同時に実行しつつ、同じインフラストラクチャやコンピューティング リソースを利用できます。たとえば、VM を使用して 1 台のサーバーで Windows と Linux を同時に実行できます。サーバー上の各 VM は、スタンドアロンで抽象化された「コンピューティング」環境として動作し、基になるサーバーやコンピューターの必要なリソースをすべて利用します。
VM とは対照的に、コンテナ化では OS 全体ではなく、コード、構成ファイル、ライブラリ、依存関係をバンドルすることで、コンピューティング リソースをより効率的に使用します。コンテナ化では代わりにホスト コンピューターのランタイム エンジンを利用し、プロビジョニングされた全てのコンテナで基となる OS を共有します。
コンテナを使用するか VM を使用するかを選択するときには、これらの技術的な違いによる影響を比較検討してください。たとえば、長期間稼働するモノリシック アプリケーションの場合は、長期間の保存や安定性の点から VM が最適でしょう。一方、軽量なコンテナは、多くの VM によるオーバーヘッドが現実的ではないマイクロサービス アーキテクチャにより適しています。
コンテナ化 | 仮想化 | |
---|---|---|
オペレーティング システム (OS) | コンテナはホスト OS を使用するため、全てのコンテナはその OS に対応している必要があります。 | VM は事実上独自の OS を実行する独立したコンピューターです。たとえば、ホスト OS が Ubuntu であっても、VM は Windows を実行できます。 |
コンピューティング リソース | コンテナは軽量で、アプリケーションとコンテナ マネージャーの実行に必要なリソースのみを使用します。 | VM は完全なコンピューターをエミュレートし、ホスト環境の大部分を再現します。そのため、より多くのメモリ、CPU サイクル、ディスク領域を使用します。 |
共有性 | コンテナ イメージは比較的サイズが小さいため、共有が容易です。 | VM イメージは OS 全体を含むため、多くの場合非常に大きくなります。 |
セキュリティ | コンテナ間の分離が非常に弱い場合があります。たとえば、あるコンテナのプロセスが別のコンテナで使用されているメモリにアクセスする可能性があります。 | 同じハードウェア上で稼働する VM は、別々の OS を実行するため、コンテナよりも相互間の分離が強くなります。 |
オーケストレーション | Kubernetes などのツールを使用すると、複数のコンテナを一緒に実行するのが比較的容易になり、コンテナがやり取りする方法やタイミングを指定できます。 | Terraform や Ansible などの構成管理ツールを使用すると、VM のデプロイとインテグレーションを自動化できます。 |
ストレージ | コンテナはエフェメラルであり、大規模なシステムで必要とされる間だけ稼働します。ストレージは通常コンテナの外部で管理されます。 | VM は稼働時間が長く、自身の完全なファイル システムを持つことが多いです。 |
DevOps におけるコンテナ化の利点
DevOps の中心になるのは、ソフトウェア開発プロセスを自動化する軽量で反復可能なプロセスです。しかし、最新のアプリケーションはますます複雑になり、特にさまざまなサービスを備えるようになっています。
コンテナは優れた標準化と反復性により複雑さを軽減し、より速く、高品質で、効率的な SDLC を実現します。
コンテナ化には次のような利点があります。
移植性: 基になる環境の一見小さな違いでも、コードの動作に影響を与える可能性があります。「私のマシンでは動作する」というよくある表現が大抵は無意味で、冗談のようになりがちなのはこのためです。また、「一度書けば、どこでも実行できる」という言葉が、ソフトウェア開発のプラクティスの向上を目指す人々に繰り返し目標とされてきた理由でもあります。コンテナはアプリケーションに必要な全てのものを一貫した移植可能な環境にまとめ、アプリケーションのパフォーマンスの標準化を容易にして、組織がこれを実現するのを支援します。
スケーラビリティ: Kubernetes などのオーケストレーション管理ツールを使用することで、コンテナ同士が大規模なシステム アーキテクチャで連携して動作するようにデプロイ、構成できます。これらのツールを使用すると、新しいコンテナ化された環境のプロビジョニングを自動化し、リアルタイムの需要に合わせてスケールすることもできます。つまり、コンテナ化された環境を適切に構成すれば、ほとんど人手を介さずに迅速にスケール アップやスケール ダウンできます。
クラウドに依存しない: コンテナは移植可能に構成すれば、ノート PC 、ベア メタル サーバー、クラウド プロバイダーのプラットフォームなど、あらゆる場所で実行できます。また、コンテナは基になるプラットフォームの違いを考慮せず抽象化するため、プラットフォームのロックインのリスクを軽減できます。コンテナを使用して複数のクラウド プラットフォーム間でアプリケーションを実行し、プロバイダーを切り替えることもできます。
DevOps パイプラインへの統合: コンテナ化プラットフォームは、多くの場合、大規模なオートメーション ワークフローに挿入できるように設計されています。そのため、CI/CD ツールでテストや本番環境へのデプロイなどのタスク用にコンテナを自動で作成や破棄する DevOps に最適です。
システム リソースの効率的な使用: 仮想マシンとは異なり、コンテナは多くの場合、効率的でオーバーヘッドが少なくて済みます。通常、コンテナにネイティブなハイパーバイザーや追加のオペレーティング システムはありません。代わりにコンテナ ツールは、各コンテナを可能な限りホスト システムの共有リソースを利用するスタンドアロン環境にするのに十分な構成を提供し、これには基になるオペレーティング システムも含まれます。
ソフトウェア リリースの加速: コンテナを使用すると、基になるコード ベースを連携して動作する小さなランタイム プロセスに分割することで、大規模で複雑なアプリケーションを簡素化できます。これにより、実行者は広範なコード ベース全体を扱うのではなく、アプリケーションの特定の部分に集中できるため、組織は SDLC の各ステップを加速させることができます。
柔軟性: コンテナは、組織がより多くのコンピューティング リソースをすばやくプロビジョニングしてリアルタイムの需要を満たすことを可能にし、SDLC に固有の柔軟性をもたらします。また、コンテナを使用すると多くの場合、冗長性を実現し、アプリケーションの信頼性とアップタイムを向上させることができます。
アプリケーションの信頼性とセキュリティの向上: アプリケーション環境を DevOps パイプラインの一部にすることで、コンテナはアプリケーションの残りの部分と同じ品質を保証されます。また、コンテナは連携して動作しますが、コンテナが提供する分離環境により、アプリケーションの一部分の問題が広範なシステムに影響を与えないようにしやすくなります。
DevOps におけるコンテナ化の役割
まず、DevOps とはチームが価値を構築して提供する方法を変える組織的な変革であり、通常はソフトウェア コンポーネントを伴います (ただし、ハードウェアのみでも DevOps は可能です)。コンテナはソフトウェアをより効率的かつ大規模に開発するための最新の方法を提供します。
つまり、コンテナは DevOps プラクティスを成功させるための必須要件ではありませんが、組織のニーズや優先順位によっては最適である可能性があります。
これは一つには、コンテナを使用することでテストの信頼性を高め、本番環境により近い開発環境を構築し、デプロイ プロセスを簡素化して、DevOps の利点を強化できるためです。
通常、この DevOps におけるコンテナ化の役割には、次のような利点があります。
信頼性の向上: 反復可能な自動化されたプロセスにより、コードがコミット、マージ、デプロイされるたびにテストとセキュリティ チェックが実行されます。チーム間のサイロを壊すという文化的な変革が起こることで、全員が品質に責任を持つようになります。コンテナはあらゆる場所で同じように動作するため、テストの信頼性が向上します。
デリバリーの高速化: 継続的な改善、マイクロサービス アーキテクチャ、自動化された DevOps パイプラインにより、変更の判断が容易になり、開発が速くなり、テストが簡素化され、意図しない結果が生じることが少なくなります。アプリケーションの一部を個々のコンテナに分離することで、DevOps の実行者は一度にソリューションの 1 つの側面に集中でき、ある領域の変更が他の領域に与える影響について懸念することが減ります。
コラボレーションの強化: DevOps は役割ベースのチームを廃止し、各個人が一緒に共通の製品目標に向かって作業できるようにします。コンテナの共有性により、各自がどのようなハードウェアを使用していても同じアプリケーション環境で作業できるため、コラボレーションが容易になります。コンテナの一元化されたディレクトリであるコンテナレジストリを使用することで、組織でのコンテナの公開や検索が容易になります。
DevOps ワークフローにコンテナを組み込む
コンテナは一度ビルドされると、変更されることはありません。コンテナの特定のバージョンがデプロイされると、必ずそれまでのデプロイ時と同じように動作します。
しかし状況は変化します。コンテナはどのようにしてセキュリティ修正や新機能を含む新しいパッケージを取り込むのでしょうか。コンテナを更新する場合、新しいバージョンをビルドし、対象のコンテナが使用されている全ての場所で前のバージョンを明示的に置き替えます。新しいパッケージの内容に変更があったとしても、コンテナのメンテナーは、コンテナが外部とやり取りする方法に変更を加えないように作業します。
DevOps パイプラインのコンテキストにおいて、この再現性は、CI/CD パイプラインのコンテナで実行されるテストが、たとえばそのコンテナが本番環境にある場合と同じように動作することを意味します。これによりテストの信頼性が高まり、コードの問題、バグ、エラーがエンド ユーザー側で発生する可能性が低くなります。
では、DevOps ワークフローにおいてコンテナは他にどのような役割を果たすのでしょう。
コード: コードが 1 行も書かれていない状況であっても、コンテナは開発環境に一定の標準化をもたらします。アプリケーションに必要なパッケージ バージョンを指定することで、コンテナは開発者のノート PC と他のノート PC で一貫した環境を実現します。このため、環境の違いによってバグが発生する可能性が低くなります。
ビルド: ターゲットがライブですぐに使用できる状態でなければならない VM やベアメタル サーバーに直接デプロイするのとは異なり、コンテナは一度ビルドすれば、保存して後でデプロイできます。これにより、ビルド フェーズがターゲット環境から分離され、コンテナが変更されたときにのみビルドする必要があります。
テスト: コンテナはコード自体のみでなく、環境全体をテストできるようにすることで、自動テストのアイディアを拡張します。これにより、テスト環境が本番環境と一致するため、より品質の高いソフトウェア デリバリーが可能になります。
リリースとデプロイ: コンテナが再現性を持つということは、本番環境のコードを変更するには、新しいコンテナをビルドしてデプロイする必要があるということです。そのため、コンテナは通常エフェメラルであり、組織がアプリケーションを構築する方法に影響を与え、マイクロサービス モデルに適します。
運用: コンテナは更新されたコードや依存関係が本番稼働中のアプリケーションにデプロイされるリスクを低減します。あるコンテナで行われた変更は、そこで隔離されます。たとえば、別々のコンテナの 2 つのマイクロサービスは同じ JSON エンコーディング/デコーディング ライブラリの異なるバージョンに依存でき、一方を変更するともう一方に影響が及ぶというリスクはありません。
CI/CD におけるコンテナの仕組み
CI/CD パイプラインは DevOps ワークフローを動かすベルトコンベヤーと考えることができます。CI/CD パイプラインが効率的であるためには、速度と完全性のバランスが取れていなければなりません。速度が遅ければ、CI/CD フローでパイプラインを通過するよりも早くコミットが発生するため、バックログが発生するリスクがあります。完全性に欠ければ、本番環境で問題が発生し、CI/CD パイプラインに対する信頼が失われます。
コンテナ化により、CI/CD の両側面が主要ステージでどのように強化されるかを以下で説明します。
インテグレーション: コンテナを使用することで、コードの変更を大規模なコード ベースに統合するときにゼロから始める必要がなくなります。アプリケーションの依存関係をあらかじめ保持している基になるコンテナを作成し、インテグレーション フェーズでそれを変更します。
テスト: コンテナは必要に応じて迅速にプロビジョニングや廃止できます。明示的なテスト環境を手動で維持したり、構成スクリプトが環境を構築するのを待ったりする必要がなく、コンテナをプロビジョニングして大規模に自動でデプロイできます。そのため、テストをより迅速に実行でき、人手を介してテスト環境を構築する必要も少なくて済みます。
リリース: 全てのテストが合格すると、CI/CD パイプラインのビルド フェーズでコンテナ イメージが生成され、コンテナレジストリに保存されます。通常、そのイメージが存在していれば、リリースとデプロイのフェーズで行われる作業の多くはすでに完了しています。Kubernetes などのオーケストレーション ツールは、コンテナのデプロイ先やコンテナ同士がどのようにやり取りするかを管理します。
マイクロサービスとコンテナ化
マイクロサービス アーキテクチャは、アプリケーションを特定の機能を果たすことを目的とする小さなユニットに分割します。たとえば、オンライン バンキング アプリケーションの場合、リアルタイムの為替レートを取得してそのデータを内部 API 経由で他のマイクロサービスに公開するマイクロサービスが考えられます。重要なのは、マイクロサービスの内部の仕組みを公開する必要はなく、API のみであるという点です。
多くの組織において、DevOps、マイクロサービス、コンテナは密接に関連しています。継続的改善という DevOps の哲学は、マイクロサービスのスコープの集中という考えにまさに当てはまります。また、マイクロサービスはステートレスであることが一般的です。つまり、マイクロサービスはそれ自体の中にはデータを保存せず、代わりに専用のデータ サービスを使用します。コンテナが生成し依存するデータの永続化方法について心配することなく、コンテナをデプロイや破棄できるため、これはコンテナの短期的な特性に適しています。
マイクロサービス アーキテクチャでは、マイクロサービスの各インスタンスとコンテナは 1 対 1 の関係です。オーケストレーション ツールを設定して、需要の高まりに応じて特定のマイクロサービスに多くのコンテナをデプロイし、需要が減少したときに廃止するようにできます。
一般的なコンテナ化ツール
コンテナを使用して作業するための最初のステップは、コンテナのツール導入の状況を理解することです。これは大きく次の 2 つに分けられます。
コンテナ プラットフォーム: ホスト オペレーティング システム内でコンテナ イメージをビルドして実行するためのツールです。Docker と LXD が有名な例です。
コンテナ オーケストレーション: 連携してアプリケーションを実行するコンテナをデプロイ、スケーリング、管理するためのツールです。Kubernetes はよく使用されているコンテナ オーケストレーション プラットフォームです。
詳しく見ていきましょう。
コンテナ プラットフォーム
コンテナ プラットフォームは、コンテナ自体をビルド、実行、配布する一連のツールです。最もよく知られているのは Docker で、コンテナを扱うためのエンドツーエンドのプラットフォームを提供します。また、一連のオープン標準の増加により他の選択肢も登場し、プロセスの部分ごとに異なるツールを選択できます。たとえば、Podman はコンテナを実行するさまざまな方法を提供します。Kraken はコンテナを配布するためのオープン ソースのレジストリです。
オールインワンのソリューションを選択する場合でも、さまざまなツールから選択する場合でも、次のことを行う必要があります。
コンテナ マニフェストの処理: これは構成ファイルで、コンテナのコンテンツ、コンテナが使用する必要のあるポート、必要なリソースを指定します。
イメージのビルド: デプロイ準備が整った休止中のコンテナです。
イメージの保存と配布: 通常コンテナレジストリと呼ばれる中央リポジトリで、CI/CD システムと関連付けて自動化できます。DevOps 実行者が手動で使用することもできます。
イメージの実行: コンテナ用の分離された環境を作成して実行します。これは Linux では比較的簡単です。Windows や macOS では、コンテナ イメージを作成して実行できる Linux 環境を提供する VM が必要になる場合があります。
コンテナ オーケストレーション
大規模なマイクロサービス アーキテクチャでは数千ものマイクロサービスが存在し、それぞれが 1 つ以上のコンテナで実行されていることが多くあります。このような大量のコンテナ間でデプロイ、スケーリング、やり取りの管理を手動で行うことはできません。その代わりに DevOps の実行者は、特定のコンテナのセットを必要とするリソースや、どのコンテナ同士が通信する必要があるかなどのパラメータを設定します。ただし、全てのコンテナを連携させて実行するにはオーケストレーション プラットフォームが必要です。
コンテナ自体と同様に、複数のオーケストレーション ツールが利用可能で、各ツールは少しずつ異なるアプローチを取ります。最もよく使われているのは Kubernetes で、業界の標準のコンテナ オーケストレーション ツールに最も近いツールです。Kubernetes はもともと、Google が同社の検索エンジンを動かすコンテナを管理するために構築したものです。一方、他の選択肢もあります。オープンソースでは Red Hat の Openshift Container Platform、SaaS では Azure の Kubernetes Service などがあります。
GitHub で DevOps プラクティスを構築する
GitHub は統合型のプラットフォームで、アイディアから計画、運用まで、焦点を絞ったデベロッパー エクスペリエンスと、強力なフルマネージド型の開発、自動化、テスト インフラストラクチャを組み合わせて企業を支援します。
「GitHub はコミュニケーションの障壁を取り除き、フィードバック ループを短縮して、可能な限りタスクを自動化することで、開発を加速させるという会社の長年にわたる取り組みを支援してくれています」
ViacomCBS、システム エンジニアリング担当ディレクター、Mike Artis 氏
計画から構築へ | 開発の速度を上げる |
---|---|
プロジェクトと完全に統合した優れたプロジェクト ボードとテーブルを使用して、コード ベースのすぐ隣でロードマップ計画を作成し、チームメンバーにタスクをすばやく割り当てましょう。 GitHub Issues について知る > |
コミットまでの時間を短縮しましょう。開発者の環境管理やコンテキストスイッチングをなくし、クラウドの安全なマネージド スペースにより、IT 調達とメンテナンスを簡素化しましょう。 Codespaces について知る > |
すべてを自動化 | コード作成時のセキュリティを確保 |
---------- | ---------- |
GitHub Actions で全てのソフトウェア開発ワークフローを自動化しましょう。GitHub のフルマネージド型の強力な開発、テスト、自動化インフラストラクチャにより、信頼性と安全性を高めることができます。 GitHub Actions について詳しく知る > |
ソフトウェア開発ライフサイクル全体を通じて、コード、依存関係、トークン、極秘データのセキュリティを確保し、脆弱性を自動で解決します。 GitHub でどのようにセキュリティを確保できるかを知る > |
Tags