コンテナ化とAWSへの移動について

コンテナ化およびAWSへのコンテナ移行について軽くに記載した記事です。
2023.10.24

こんにちは クラスメソッドのスジェです。
既存のオンプレミス環境からクラウドへの移行を計画しながら既存環境のコンテナ化も検討する場合があります。
その内容について私が勉強した内容を記録しました。

コンテナ化とは?

定義

コンテナ化は、アプリケーションのコードを、あらゆるインフラストラクチャで実行するために必要なすべてのファイルとライブラリにバンドルするソフトウェアデプロイプロセスです。従来、コンピュータでアプリケーションを実行するには、マシンのオペレーティングシステムに合ったバージョンをインストールする必要がありました。
例えば、Windows マシンには Windows バージョンのソフトウェアパッケージをインストールする必要がありました。しかし、コンテナ化を使用することで、あらゆるタイプのデバイスやオペレーティングシステムで実行される単一のソフトウェアパッケージ (コンテナ) を作成できます。
コンテナ化とは?(AWS)

サービスを運用するために必要な依存性を含めて独立に動けるようパッケージング(イメージ化)することを「コンテナ化」と呼びます。

メリット

「デプロイの負担を軽減し楽になる」のが主なメリットです。
詳細を見てみます。

簡単なデプロイ(=ポータビリティ)
実行に必要な依存性を含めてデプロイするため、アプリケーションを実行させるために他の機能などをインストールする必要がありません。
それでコンテナのイメージだけビルドし管理すればいいです。

拡張性および軽量化
コンテナを実行させるためにサーバを起動するより小さいリソースで十分です。簡単なデプロイというメリットと合わせて必要に応じて複数のサービスが運用できるよう拡張することができます。

耐障害性
実行されるコンテナはお互いに影響を与えません。1 そのため、複数のコンテナを実行させたら一部のコンテナが止まったと言っても他コンテナの実行には影響がありません。

俊敏性
全コンテナに変更事項があても、デプロイしたイメージだけ変更すれば既存のコンテナにも迅速に変更が適用できます。2
迅速に変更ができるため、テスト後本番に適用するサイクルも加速することができます。

コンテナ化が適切なシステム

既存環境が下記説明にあたる環境だったりもしくは変更する予定でしたら、コンテナ化を検討してみた方がいいと思います。

マイクロサービスアーキテクチャ(MSA)とCI/CD

マイクロサービス(またはマイクロサービス・アーキテクチャー)は、クラウドネイティブのアーキテクチャー・アプローチであり、単一のアプリケーションが、疎結合かつ独立してデプロイ可能な多数の小さなコンポーネントまたはサービスで構成されています。
マイクロサービスとは?(IBM)

アプリケーションを機能ごとに分離することでお互いの依存性が少ない(疎結合、loose coupling)アーキテクチャです。
コンテナ化のように各機能ごとにデプロイすることができるため必要に応じて特定の機能を増加させるなどコンテナ化に適切です。

MSAを運用しながらコードで環境を管理するCI/CDを導入するケースも多いです。
これによってコンテナの管理および改善を迅速にすることも可能です。

モノリシックアーキテクチャの場合はコンテナ化よりも仮想マシン (VM、Virtual Machine、バーチャルマシン)で運用する方がもっと適切な可能性があります。

頻繁にリリースするシステム

システムの変更やデプロイが頻繁なサービス(環境)ではコンテナ化のメリットである俊敏性を十分活用できます。
ですがシステム的な変化がほとんどないシステムでしたら入れた時間に比べてコンテナ化の効率が低い可能性もあります。

クラウドへマイグレーションを予定しているシステム

必要に応じてコンテナの増減させる際、必要な分だけリソースを使うためにはシステムをクラウド環境から運用したほうが良いです。
例えばEC2(サーバー)からコンテナを運用している場合、通常には1台のEC2だけを運用し、より多いサーバーリソースが必要になるとEC2を追加してコンテナを増やすことができます。必要リソースが減少する場合はEC2を削除して不要なコストが発生しないようにすることも可能です。

コンテナ化の確認事項

コンテナ化の効率を上げるためにはいくつか確認項目があります。

コンテナオーケストレータの利用

コンテナ数が増えると当然管理難易度も上がります。
複数のコンテナを管理するように役に立つツールがコンテナオーケストレータ(コンテナオーケストレーションツール)と呼びます。
ツールの一つとしてKuebernates, DockerSwarmなどがあります。

システムのマイクロサービス(MSA)化できるのか?

上記の説明の通りにサービスのMSA化ができればコンテナ化に適切だと言えます。
現代的なアプリケーション開発のベストプラクティスである The Twelve-Factor Appに従ってアプリケーションを開発した場合はアプリケーションのMSA化もより簡単にできます。
The Twelve-Factor Appは下記の通りです。

  1. コードベース:バージョン管理されている1つのコードベースと複数のデプロイ
  2. 依存関係:依存関係を明示的に宣言し分離する
  3. 設定:設定を環境変数(environment)に格納する
  4. バックエンドサービス:バックエンドサービスをアタッチされたリソースとして扱う
  5. ビルド、リリース、実行:ビルド、リリース、実行の3つのステージを厳密に分離する
  6. プロセス:アプリケーションを1つもしくは複数のステートレスなプロセスとして実行する
  7. ポートバインディング:ポートバインディングを通してサービスを公開する
  8. 並行性(Concurrency):プロセスモデルによってスケールアウトする
  9. 廃棄容易性(Disposability):高速な起動とグレースフルシャットダウン(graceful shutdown)で堅牢性を最大化する
  10. 開発/本番一致:開発、ステージング、本番環境をできるだけ一致させた状態を保つ
  11. ログ;ログをイベントストリームとして扱う
  12. 管理(Admin)プロセス:Admin/Maintenanceタスクを1回限りのプロセスとして実行する

この中で6. プロセス、9. 廃棄容易性、11. ログについてもうちょっと気にした方が良いです。

ステートレス(stateless)なコンテナ
コンテナに永久データやセッション情報などがある場合、安全なコンテナの終了が難しくなります。
そのためコンテナ内には保存が必要なデータやセッション情報を保存しない方が良いです。そのようなデータは外部の保存先を利用しましょう。

早めに起動して、終了できるコンテナ
アプリケーションコンテナはいつでもエンドユーザーに影響を与えずに安全な終了ができるよう実装しましょう

ストリムで処理するログ
コンテナ内からログをファイルに処理して外部に保存する場合、コンテナが急に終了されたらログが消失される可能性があります。
そのためイベントなど必要なログはストリムとして外部に保存しましょう。

コンテナ1個当たり1個のプロセス(アプリケーション)

1個のコンテナでは1個のプロセスを実行させるのを推奨しています。

VMなら1個のVMでWeb、AP、DBなど複数のプロセス(アプリケーション)を実行しても構いませんが、 コンテナでは複数のプロセスを実行することを推奨していません。代わりにプロセスごとに複数のコンテナを起動させます。

コンテナの安全な作動の保証

悪意的な攻撃を防ぐために本番環境から実行されるコンテナイメージは追加パッケージのインストールが不要なものを利用して、攻撃を受けるポイントを最小限にした方がいいです。
アプリケーションをコンテナ化する際のベースイメージは必要ランタイムと依存性だけインストールされているdistolessのような軽くて安全なイメージを採用しましょう。

また、コンテナから安全な起動が保証できなかったり、コンテナから運用できないライセンスなどを使用しているシステムは検討が必要です。既存システムをコンテナ化する場合はシステムで必要にする製品およびオープンソースソフトウェアのライセンスがコンテナを支援しているのか確認しましょう。

コンテナイメージに機密情報を保存しない

コンテナイメージには認証情報などの機密情報は保存しないように注意してください。代わりに認証情報などが必要なら環境変数などを通じてアプリケーションに伝えた方が望ましいです。

ベストプラクティスに従った Dockerfile の作成

Dockerfile はベストプラクティスに従って作成しましょう。

Dockerfile がベストプラクティスなのか確認するツールもあります。

AWSへのコンテナ化

既存オンプレミスもしくはEC2から運用しているサービスをAWSへマイグレーションする過程についてみてみます。
大まかな流れが記載されていて、コンテナの作成方法など詳細な情報は別途調査が必要です。

既存サービスのコンテナ化

既存のサービスをコンテナ化するためには対象コンポーネントを特定する必要があります。
オンプレミスやEC2で提供しているコンテナ化されてないサービスは複数のコンポーネントが一緒に運用されています。
ですが上記説明の通りに1個のコンテナ当たり1個のプロセス運用を達成するためにコンポーネントを分離してそれぞれコンテナ化する必要がります。
イメージのように1個のサーバーで運用されている複数のプロセスがそれぞれのコンテナ化の対象になります。

各コンテナをイメージ化してイメージレジストリ(コンテナレジストリ)に保存します。
それから必要な分のレジストリからイメージをインポートしてコンテナを作成する流れです。

AWSサービスの選定

AWSでコンテナを運用するためにいろんなサービスを提供しています。

コンテナ・オーケストレーション・サービス
コンテナのデプロイ、スケジューリング、スケーリングなど運用中のコンテナを管理するためにサポートするサービスです。
ECSとEKSがオーケストレーションサービスでEKSはKubernatesで管理する場合に採用するサービスです。

イメージレジストリサービス
コンテナのイメージを保存するサービスです。
AWSではECRというレジストリサービスを提供しています。

サーバーホスティングサービス
コンテナをホスティングするために必要なサーバーを提供するサービス(コンピューティングサービス)です。
EC2は使用するサーバーの管理をユーザーが担当するサービスで、FargateはAWSがサーバーを管理するサーバーレスコンピューティングサービスです。

AWSやコンテナの運用に慣れてない場合はECS、ECR、Fargateの組み合わせが管理する箇所が少ないためお勧めです。

ECSを使用する場合、この3つの概念を理化するとそこまで難しくないと思います。

  • Task(作業)定義
    • アプリケーションを構成する1つ以上のコンテナグループを定義
  • Service(サービス)定義
    • 一定のタスクを維持して、状況に応じてスケジューリング・スケーリングするように定義
  • Cluster(クラスタ)
    • タスクとサービスを結んだ論理的なグループ

つまり、

  • 複数のコンテナグループ + コンテナに関する定義 = Task 定義
  • 複数のコンテナグループの数を管理する設定 = Service 定義

です。

一部の機能の代わりにAWSサービスを導入

普段、サービスを運用するためにロギングやモニタリングツールやプログラムを導入する場合が多いです。 コンテナ化をする際にはそのようなプログラムもコンポーネント対象になります。
場合によってはそのようなプログラムをAWSから提供しているサービスに代替することで、管理箇所を減らすことができます。

例えばロギングはCloudWatchを導入しますとログを長期間保存したり調査することができます。
モニタリングは CloudWatch Insight を導入しますといろんなメトリクスを Insight コンソールから確認できますし、アラート設定などの活用もできます。

お望みの機能をAWSから提供しているのか確認するためには簡単に「 AWS {必要機能}」を英語で検索してみましょう。

まとめ

既に運用しているサービスをコンテナ化する場合は現在のアプリケーションの構成からいろんなポイントを検討してみる必要があります。
運用中のサービスがコンテナ化に適切ではなくてもVM から運用するという選択肢もあります。
特にコンテナ化を進めながらAWS などのコンテナ化も可能でしたら、より効率的なサービスの運用ができます。

最後まで読んでいただきありがとうございました。
内容のフィードバックおよびタイプミスなどは must01940 gmail までお願いします。

参考資料

コンテナ化とは?(AWS)
コンテナ化とは(RedHat)
コンテナ化とは(nutanix)
AWS에서 어떤 컨테이너 서비스를 이용해야 하나요?(AWS)
コンテナイメージを設計する際の推奨事項(isid tech blog)
コンテナ導入のポイント(Fujits)
ところで、コンテナ化ってどうすればいいの?(AWS, pdf)
アプリケーションをコンテナ化!検討すべきポイントとは?(sandi)


  1. コンテナを実行するサーバーで複数のコンテナを運用することでリソースを全部消耗してリソース不足になったりなど外部的な原因ではなくコンテナ自体の影響に限った話です。 
  2. 確実には展開したイメージを利用して既存のコンテナをアップデートする流れです