ECSを理解する(第1回)

2020.06.26 Cloud

はじめに

こんにちは。BTCクラウドCoEの松波です。
テーマはAWS ECS/Fargateです。今回は初回なので、コンテナとECSについて簡単に解説していきたいと思います。

コンテナについて

本コラムを書くにあたり「コンテナ」の定義について調べてみました。コンテナの業界標準策定を目的とした機関であるOpen Container Initiative(以下OCI)によると、コンテナは「分離とリソース制限を構成する実行プロセスのための環境」となってます。[1]
これだけ読むと仮想マシンのことのようにも読み取れますが、一般的に仮想マシンはホストOSの仮想化ソフトウェア上でゲストOSが動き、その際ホストOSとゲストOSは異なるOSとすることができます。
それに対し、コンテナの場合はホストOSのカーネルを共有し、コンテナを稼働させる常駐プロセスとカーネルの機能によってリソースを分離する機能となってます。
仮想マシンの方がOSが分かれているため分離度が高く、コンテナは逆にOSが分かれていないためオーバーヘッドが少ないという特長がよく謳われており、VM vs Containerといった比較・説明サイトもWebで検索するとたくさん見つかります。
ただ、実際には仮想マシンとコンテナは必ずしも競合する技術ではなく、例えばAWS ECSでは仮想マシン上でDockerコンテナを動かすことを前提としています。
なぜでしょうか?
一つはパブリッククラウドではセキュリティ上、他企業のコンテナのデータを参照できるということは決して許容できず、それに相応した高い分離度が求められているため、コンテナ単体よりセキュアな仮想マシンでの分離を行っているというのが理由として挙げられるのではないかと考えられます。
そしてVM vs Containerの文脈とは別に、アプリケーションのパッケージング・配布が容易にできるようになっていることがDockerコンテナの利点であり、Dockerが仮想マシンと併用されている理由と考えられます。

ECS/Fargateについて

ECSは現在Elastic Container Serviceと表記されているのを見ますが、元々はEC2 Container Serviceという名称で、コンテナをEC2上で実行するサービスでした。
EC2をホストとするため、マルチAZ構成にする場合はEC2の配置などを考慮する必要があり、またEC2に対して課金されるためリソースの有効活用という点では無駄な部分も生じがちでした。
そのような課題を解決したのがFargateです。
FargateはECSの起動タイプの一つです。Dockerコンテナを実行する点で従来のECSと同じですが、Docker エンジンの下のレイヤーがEC2ではなくなっており、microVMと呼ばれる必要最小限にデバイスや機能が絞られた仮想マシンになってます。

FargateとFireCracker

Fargateで起動するmicroVMはEC2と比べてどこが違うのでしょうか?
一番の違いは、EC2がユーザーが管理する対象なのに対し、FargateのmicroVMは運用上管理・意識する必要がないという点です。
この謳い文句はサーバーレス・Lambdaの利点を語るときによく聞く話ですが、それもそのはずFargateとLambdaを実現している基盤技術にはどちらもFirecrackerという仮想マシンモニターが利用されてます。また、Firecrackerができるまでは、EC2をホストとしていた点も共通してます。
FirecrackerはAWS中心で開発が進められていますが、OSSとして公開されてます。
Firecrackerのサイト[2]を見ると、前述のVMの長所(分離度の高さ)を維持しつつ、短所(オーバーヘッド)を改善するという点が特長としてあげられてます。逆にいうと、AWSはコンテナ技術だけでは十分な分離レベルを得られないと考えていることがわかります。
また、AWSのブログ[3]では、microVM 1つあたりメモリ5MB分のオーバーヘッドしか生じないと謳われており、EC2の場合とは比較できないものの、確かにオーバーヘッドが小さいことがわかります。
仮想マシン管理がここまでミニマルになると、仮想マシン自体でアプリケーションをパッケージングするようにしても良さそうにも思えますが、その辺りはDocker Hubでのイメージ共有やOCIでコンテナイメージの標準化などを進めてきたDockerにまだ分があるということなのでしょう、多分。
これは完全に余談ですが、FirecrackerはKata、firecracker-containerd等、Dockerコンテナ以外のコンテナにも対応しているため、Docker以外のコンテナも今後AWSのサービスに取りこまれる可能性もあるのかもしれません。このあたりは今後の動向が楽しみですね。

ECSについて

コンテナとVMの話は終わりにして、ECSの仕様について触れていきます。
ECSの主な構成として、コンテナ、タスク定義、サービス、およびクラスターがあります。
関連サービスとしてはDockerイメージを格納するECRや、Webアプリケーションコンテナと関連付けられるALBなどが挙げられます。
ECSの構成を表した図として、以前AWS管理コンソールでは下のような図が記載されていました。(今見たら見つけられませんでした…)

コンテナ定義はECRやDocker Hubなどに登録されているDockerイメージとなります。

タスク定義は主にDockerイメージと、リソース情報などを紐づける定義です。
どのバージョンのアプリケーションをvCPU 1個、メモリ 2GiBで起動する、といった具合です。
この定義に基づき、EC2もしくはFargate上でインスタンス化されたコンテナ(群)がタスクです。

サービスはどのタスク定義のタスクをいくつ起動するか、起動する先のネットワーク設定やELB、およびEC2起動型かFargateかといった構成を管理しています。

クラスターがECSとして定義する最も大きな単位であり、上図のとおりクラスター内にサービスやタスクが含まれる構成となります。
ちなみにEC2起動型の場合はEC2のインスタンスタイプなどを設定することになりますが、Fargateの場合はVPCとCloudWatch Insightsの有効・無効程度しか設定項目としてはありません。

上記のようなコンポーネントによって、コンテナのオーケストレーションを行っている点がECSの特長です。
他のコンテナオーケストレーションでは使われてない用語も含まれているかと思いますので、これら用語や関係を理解することが、ECSの理解度を上げるうえで重要となります。
とは言え、ELB+EC2+Auto Scalingなどの構成をAWSで構築したことのある人にとっては敷居は低く、比較的シンプルに運用できるサービスのように思います。

終わりに

今回はコンテナおよびECSの基本的な概念について記載しました。
次回はECSを実際に利用するときの細かい点について触れていきたいと思います。

[1] https://github.com/opencontainers/runtime-spec/blob/master/glossary.md#container

[2] https://firecracker-microvm.github.io/

[3] https://aws.amazon.com/jp/blogs/aws/firecracker-lightweight-virtualization-for-serverless-computing/