MTI Engineer Blog

エムティーアイ エンジニアブログ

AWS ECSとFargateの組み合わせが素晴らしい件

若者言葉を無理に使って白い目で見られるDockerおじさんの西川です。 re:Inventで発表されたFargateはECSをいじる者としてはとても気になります。

aws.amazon.com

ECSクラスタを構成するクラスタインスタンス(ECS用語ではコンテナインスタンス)の管理から全く開放されるのです!
マジヤバくね?(こういうところですね)

ということで、AWSサポートから情報を頂きつつ、手を動かして試してみました。

前提知識:そもそもECSが何をするものなのか

Dockerが何か、ECSが何かというところはこちらの記事を参考にしていただけると良いかと思います。

Fargateは何をしてくれて、私は何をしなくて良いのか

  • コンピューティングリソースを提供してくれます
    • CPUパワー
    • メモリー
  • コンテナを動かすためのコンテナインスタンス(DockerホストとしてのEC2インスタンス)の管理は必要ありません
    • OSのパッチ当て、アップデート
    • Dockerのバージョン、ECS-Agentのバージョン管理
    • AutoScaleの設定
    • EC2インスタンス使用料の課金

素晴らしい! サーバーたちのことは忘れてコンテナ(というかECSタスク)のことだけ考えれば良くなります。

  • ECSタスクにどのVPC,サブネットを関連付けるか
  • ECSタスクにどんなIAM Roleを関連付けるか
  • ECSタスクにどれくらいリソース(CPU,メモリ)を割り振るか

試しに作ってみた

ECSタスクにVPC,サブネットを関連付ける=先日出たAWSVPCネットワークモードと理解して、下記のようなお試しの構成をしてみました。

f:id:nishikawa_sh:20171206135820p:plain

  • Node.js 8.x + Express 4.x + Sequelize で AuroraDBからSELECTした結果を返すだけのAPI
  • 上記をDockerコンテナ化して、FargateなECSクラスタ上でサービス化
  • internet-facngなNLB(ALBでも良いのですが、NLBを触ってみたかっただけです)でバランシング

http://fargate-test-b74f9598f2bc6f5e.elb.us-east-1.amazonaws.com/ で、

{"title":"Express Sample","body":[{"col1":"record1"},{"col1":"record2"},{"col1":"record3"}]}

こんなJSONが返ってくるだけの単純なものです。 大したものでもないですが、一応ソースコードはコチラにあります。 github.com

気になっていたところ

普通のEC2インスタンスを使ったECSクラスタでAWSVPCネットワークモードを使う場合には、「タスクに関連付けたVPC, サブネットのネットワーク内に、そのタスクが稼働するコンテナインスタンスが居る必要がある」という制約がありましたが「Fargateはその辺がどうなっているのだろう」と言うところです。

  • Fargateとは言え裏側はEC2インスタンスがプールされていてAmazonさんがタスク実行時にそれを貸し出してくれるのだろう
  • だとしたらVPC外のEC2インスタンスからVPC内のRDSにアクセスできるのか?

Fargateはまだus-east-1限定なので、us-east-1にVPCを作って、AuroraDBを置いてやってみました。

結果的には意図通り

無事に、Fargateに配置したECSタスクさんが、VPC内のプライベートサブネットに居るAuroraDBにアクセスしてSELECT結果を返すことが出来ました!

謎テクでDockerホストのネットワークと、ECSタスクのネットワークが見事に分離されています。

作り方

fargateなECSクラスタを作るのはとても簡単です。

f:id:nishikawa_sh:20171206142719p:plain

Powerd by AWS Fargate を選んでクラスタを作るだけです。

一方のTaskDefinitionは少し変わっています。

Launch TypeとしてFargateを選択して、 f:id:nishikawa_sh:20171206143135p:plain

タスクがFargateに要求するリソース量を指定します。 f:id:nishikawa_sh:20171206143140p:plain

タスク内の各コンテナの使うリソース量合計<ここで指定したタスクのリソース量 の関係である必要があります。

そして、タスクの実行時に関連付けるVPC、サブネットを指定します。 f:id:nishikawa_sh:20171206143910p:plain

いつもはCloudFormationで記述するのですが、今回は検証ということで温かみのある手作業で構築しました。

感想

良いところ
  • とにかくEC2インスタンスを気にしない
  • クラスタを作るのが簡単
微妙なところ

特にないのですが「強いて言うなら」ですよ、

  • タスクの起動がインスタンスを使う場合に比べて多少遅い
    • ENIのアタッチに時間がかかる?
    • docker pull のキャッシュが効かずに毎回 pull しているから?
  • ホストのディスクに何かを置いてVolume Mountするような使い方は出来ない
  • ECS-Agentのログが見られないのでタスクが起動しないときの原因追求は手を焼きそう
  • 常時起動のサービスはEC2インスタンスでクラスタを構成する場合に比べて割高かも

これは使えるぞ。早く東京リージョンにもほしい!

おまけ

さっそくFargateのAdventカレンダーが出来ているので、今年も残すところあと25日これで楽しみましょう。

qiita.com