コンテナ開発は本当に必要でしょうか。どのような状況下で役に立つのか、開発現場で起こりやすい問題とコンテナ仮想化による解決方法についてご紹介します。
コンテナ開発の必要性
開発現場での問題
新規でシステムを開発する際、搭載する機能やインターフェス、連携する外部サービス、想定利用ユーザ数は限定的になることが大半ですので、シンプルなインフラ構成で構築されることが多いです。そのほとんどはWEBサーバー、アプリケーションサーバー、DBサーバーのみの3層構成で事足りるケースも多いでしょう。また新規のシステム開発では、プロジェクトチームの体制も少人数で構成され、開発環境の整備にほとんど困ることはないはずです。
しかしながら、アプリケーションに実装される機能が追加されるにつれて、コードは複雑性を増していきます。また、想定利用ユーザ数が増加すると、各サーバーの増強や性能拡張が必要になり、運用維持コストが増加します。開発メンバーが増えるたびに環境構築作業が必要になり、既存の開発環境と同等の環境を準備することも徐々に大変さを増していきます。大半の開発現場では、システムの成長につれて、次のようなことに頭を悩まされることになります。
(1)開発速度の低下
モノシリックアーキテクチャでシステムの成長が続くと、1つの機能を追加・修正する際の影響範囲が広くなり、テストを行うための工数が増大します。データベース構成を1つ変更するにしても、搭載済みの各種機能について影響確認を行う必要があります。機能が増えるたびにソースコード確認やテストの工数が増加し、結果として開発速度は低下することになります。
(2)開発環境維持コストの増加
新しく加わった開発者のために構築された環境が、既存の開発環境や本番環境と一部異なっていたというケースを耳にします。また、クラウド上の検証環境や本番環境上には最新のアップデートが適用されているものの、開発者のローカル開発環境は適用されていなかった、というようなトラブルもプロジェクトの規模が拡大すると、起こり得ることでしょう。このような状態で開発を進めてしまうと、環境差異を招く可能性が高まります。また、ローカル開発環境下で仮想マシンを使用するケースでは、リソースが大量に消費され、実行速度が遅いなど、作業速度の低下を招きます。
(3)インフラ環境の運用コスト増加
各サーバーの台数が増えるとOS、ミドルウェアのアップデートやアプリケーションのデプロイに要する時間が長くなります。また、新旧サーバー間で細かい違いがある場合にはプロビジョニングツールを使った場合も状態に細かな差異が出ることがあります。細かなソフトウェアのバージョン違いがシステムに影響を及ぼすことも考えられるため、差分確認などの作業が必要になります。割り当てるリソースの管理もサーバーが増えると手間のかかる作業です。
これらの問題は、コンテナ仮想化により解決できる可能性があります。
コンテナ仮想化とは
コンテナ仮想化は1つのOS上に独立したサーバーのようにアプリケーションの動作環境を構築する技術です。ホストOSの提供する機能によって、隔離された実行環境で標準化されたプロセスを実行させることができます。代表的なソフトウェアにはDocker(ドッカ-)というものがあります。似た技術に「仮想マシン」がありますが、こちらは仮想マシン上でOSカーネルが動作し、その上でアプリケーションが動作します。つまり、仮想マシンごとにOSを動かすため、その分のリソースが必要になり、システムの起動にも時間がかかります。その点、コンテナであれば起動もスピーディでリソースを有効活用することができるので、マイクロサービスアーキテクチャを採用した開発や、軽量なローカル開発環境の構築に有効利用できます。
システム開発・アプリ開発の発注ならGeNEE
コンテナ仮想化による解決策
(1)開発速度の低下に対するアプローチ
モノシリックな構成をマイクロサービス化することを検討すべきです。各機能を異なるサービスとして分離し、機能間の依存関係を減らすことで、開発速度の向上が期待できます。ドメインごとにサービス分割やデータベース分割を検討する必要があり、規模の大きなシステムほど簡単ではないので、最初は分離する対象を限定化し、最適化を目指すのがよいでしょう。マイクロサービスの各サービスを、可搬性や互換性に優れているコンテナで実現することでデプロイやリソース拡張が効率化できます。
(2)開発環境維持コストに対するアプローチ
Dockerを利用した開発環境を利用することで解決可能です。複数の開発環境構築もDockerfileを使うことでシンプルに自動化でき、それぞれの環境差異を気にする必要がなく、開発作業の品質向上が期待できます。仮想マシンと比較して軽量なため迅速に起動できます。そのため、開発環境の破棄や再作成も低コストで実施可能です。
(3)インフラ環境の運用コストに対するアプローチ
前述しました通り、本番環境下であっても同じコンテナイメージから生成されるコンテナであれば、OSやミドルウェアのバージョンは同じであるため、サーバーごとの差異を確認する必要はなくなります。また、軽量なコンテナを利用するためデプロイ時間も短縮されます。デプロイ頻度が多いシステムでは開発ライフサイクルが短縮され、より一層オペレーション効率化が期待できます。Dockerで作成した複数のコンテナを、それぞれ何台ずつ起動するか、どのようにスケールアウトするか、アップデートを行うか、など自動化するツールを使用することで更に運用業務も効率化できます。このようなツールはコンテナオーケストレーションツールと呼ばれ、代表的なものにKubernetes があります。
AWSのコンテナサービス
ローカル開発環境につきましてはDockerを使用することで、お手軽にコンテナを利用することが可能です。クラウド上の環境についてもベンダー各社にて多数のマネージドサービスが提供されています。ここでは、AWSで提供されているコンテナサービスを紹介します。
コンテナ・オーケストレーション
(1)Amazon ECS
フルマネージドコンテナオーケストレーションサービスです。AWS専用のサービスであるため、他のAWSサービスとの連携がスムーズに行えるというメリットがあります。EKSと比較してESCクラスタ自体に料金がかからないため、EKSと比較して安価に運用することが可能です。対象のデータプレーンはEC2とFargate の2つです。
(2)Amazon EKS
AWSマネージドなKubernetesベースのコンテナ管理プラットフォームです。オープンソースのKubernetesをほとんどそのままAWS上で利用することができます。Kubernetesのコミュニティが非常に広大で機能がとても豊富なので、必要なツールを選んで導入することができます。機能が豊富な分、アップデートに伴うバージョンアップの頻度も多く、ECSと比較して学習コストは高いと言えます。また、Kubernetes がオープンソースなのでAWS以外のプラットフォームやオンプレミスでも運用が可能な点もECSとは異なります。対象のデータプレーンはECSと同様にEC2とFargateです。
コンピューティング・オプション
(1)EC2
おなじみのAmazonが提供する「仮想サーバサービス」です。こちらはインフラエンジニアの方でAWSを触ったことがある人でしたらある程度理解があるかと思います。
(2)Fargate
コンテナワークロードの起動にEC2にかわって利用できるサービスです。EC2の運用で必要なセキュリティパッチの適用、サーバースケーリング、セキュリティ設定などをAWSに任せることができます。メンテナンスコストが取り除かれ、アプリケーション開発に集中することができます。また、ECS、EKSのどちらのコンテナとしても利用可能です。EC2と比較してトータルコストを考えると、コンテナ用のデータプレーンとしてはFargateを使用するのがよいかもしれません。
コンテナをサポートするサービス
(1)AWS ECR
AWSが提供するフルマネージドコンテナレジストリサービスです。作成したコンテナイメージをECRにプッシュする ことで、各種管理ツールからコンテナイメージをプルできるようになります。オーケストレーション(ECS、EKS)を使用する場合に必須のサービスです。Amazon Inspector 脆弱性管理サービスを使用してコンテナイメージ内の脆弱性を検査することが可能です。GitHub、GitHub Actionsを利用することで、コードの改修やDockerfileの更新→コンテナイメージのビルド→ビルドしたイメージをECRにプッシュからデプロイといった一連の処理を自動化できます。
(2)AWS App Mesh
オープンソースの Envoy プロキシを使用して、サービスのコンテナに出入りするすべてのトラフィックを管理するマネージドサービスです。通信のリトライやタイムアウト、ログの取得、通信の暗号化などを管理します。
(3)AWS App Runner
コンテナをデプロイするとAWSのリソースの多くがユーザーから隠蔽された状態で提供されます。VPCやセキュリティグループ、ALB、Fargateなどの設定を気にせずに、アプリケーション開発に集中することができます。できる機能は制限されますが、スピーディな環境構築を求める際には有用なサービスと言えるでしょう。