Usual Software Engineer

よくあるソフトウェアエンジニアのブログ

ゼロから始める AWS Fargate 概要編

Java アプリケーションを AWS Fargate 上で動かすという案件に取り組んだので、その知見をまとめておこうと思います。 サンプルコードを用意するのが時間がかかりそうだったので、もう 5 月も終わりということで概要編の記事として済ませることにしましたw

最近では、各種クラウドプラットフォームで Docker コンテナを動かすサービスが提供されています。 ただ Docker コンテナを動かしたいというだけであれば、自分のマシンのローカルで docker run して動かすのと同じぐらいの簡単さが欲しいわけですが、 実際にプロダクションレベルのアプリケーションを動かすとなると、 スケーラビリティやロギング、モニタリングなど考慮しなければいけないことがたくさん あります。 そういったアプリケーションに付随する必要なことに関しては、チュートリアルを触っただけではなかなか感触が得られませんよね。

この記事では、 AWS Fargate を使ってアプリケーションを動作させる場合に何が必要になり、どのような方法で行うのかを紹介します。 一つ補足しておきますと、”ちょっと触れたいだけなんだけど”という人には情報が多すぎるかもしれませんし、”大規模サービスを展開したい”という人には情報が不足しているかもしれません。同じ方法で大規模サービスを展開することができるような気がしますが、試したことはないので何か問題があるかもしれません。

前置きはこのぐらいにして、AWS Fargate の概要に入ります。

AWS Fargate とは

aws.amazon.com

現在では Kubernetes がコンテナオーケストレーションツールとしてデファクトスタンダードになりつつあり、各種クラウドプラットフォームで Kubernetes のマネージドサービスもリリースされていますが、 Fargate はそれ (AWS だと EKS) よりも早くリリースされたコンテナサービスです。 AWS のコンテナサービスと言えば ECS でしたが、 Fargate も ECS のうちの 1 つのタイプとして捉えることができます。 自分たちでクラスタ自体の管理が必要だったのが ECS であり、 Fargate はその管理が不要になった フルマネージドなコンテナサービス です。 つまり Fargate の場合はその上で動くコンテナのみに注力すれば良いので、スケーリングなどインフラのことは基本的に気にせず楽することができます。

料金に関しても、

AWS Fargate では、前払いは発生せず、使用しているリソースに対してのみ料金が発生します。コンテナ化されたアプリケーションで消費される vCPU およびメモリリソースの量に対する料金が発生します。

となっているので、必要な時にだけアプリケーションを動作させてリソースを割り当てる、そうでない時は停止して料金を削減する、といった用途にも合うと思います。 サーバーレスをやりたくて Function なら AWS Lambda 、 Container なら Fargate という感じでしょうか。

Fargate 上のコンテナはどう動くのか

まずちょっとだけ触れてみるというのが目的であれば、こちらのドキュメントを見つつ Getting Started を実行するのが良いです。

Fargate を使用した Amazon ECS の使用開始 - Amazon Elastic Container Service

たまに日本語の方のドキュメントだと情報が古い場合があるので、何かハマった時は英語の方を読んでみてください。

”Fargate 上のコンテナはどう動くのか”についてですが、少なくとも以下の図だけは意識しておく必要があります。定義は ECS と同じになります。

f:id:innossh:20190531184035p:plain

逆に言うとこれだけ頭に入れておけばコンテナが動かせますw Kubernetes を知っている方は なんて簡単なんだ!! と思うかもしれません。比べてはいけない気もしますが。

一番内側の四角から軽く説明しますと、

  • Container definition
    • 実際に動かすコンテナの定義。下記の Task definition の中に複数のコンテナを定義できる。サイドカーコンテナ的な使い方も可能
  • Task definition
    • タスクの定義。下記の Service に複数のタスクを定義できる。タスクごとにサポートする起動タイプ (Fargate or EC2) や IAM role 、 CPU や メモリの制限を指定できる。
  • Service
    • サービスの定義。サービスごとに起動タイプやネットワーク設定、ロードバランシングなどを設定できる。
  • Cluster
    • クラスタそのもの。複数のサービスを実行することができる。クラスタ名を設定するだけで作成が可能。

のようになります。タスク定義にはバージョンが割り振られるので、コンテナやタスクの設定が変更された場合は新しいバージョンのタスク定義が作られ、サービスはあるバージョンのタスク定義を参照してクラスタ上で動作する、といった形になります。

図としては単純ですが、実際に動かしてみないとちょっとわかりづらいかもしれませんね。

Fargate の構築と管理

Fargate のクラスタの構築、そしてその上で動くアプリケーションの管理ですが、個人の意見として Terraform + ECS CLI で行うことを推奨します。

まず Terraform に関しては、それに限らないのですが、社内やチームで使用している既存のツールで他の AWS のリソースと同様に管理できるのが嬉しいと思うので、僕の場合は Terraform 一択という感じでした。

その上で動くアプリケーションも AWS のリソースではあるので、同じく Terraform で管理することもできますが、 アプリケーションの再起動などを考えると、例えば クラスタとコンテナ定義ではライフサイクルが異なっている ように思います。 また Terraform でアプリケーションを管理する場合タスク定義などは基本的に JSON で記述する必要がありますが、正直 JSON で設定を書いて管理したくありませんw

Kubernetes では似たような Pod の定義を YAML で書きますが、 Fargate の JSON の記述を覚えたところで有用ではない気がします。 そこで利用できるのが ECS CLI です。 ECS CLI を使用すれば、 Docker Compose の YAML + α でアプリケーションの作成、起動、停止などをコマンドラインで実行できます。

Docker Compose ファイル構文の使用 - Amazon Elastic Container Service

Docker Compose を使用してローカルで動作確認を行い、そのままシームレスに Fargate 上でもアプリケーションを動かす ことができるわけですね。素晴らしい。 ただ実際は ecs-params.yml に Fargate 用の設定をそこそこ書かなければいけないことと、 ECS CLI が最新の Fargate の設定についていけてないせいで使えないオプションなどもあるので、完璧というわけではありません。メリット・デメリットを考慮してツールを利用しましょう。

Fargate のアプリケーションに必要なこと

なんとなく Fargate 上でアプリケーションを動かすイメージがついたところで、実際にプロダクションレベルのアプリケーションを動作させた場合に必要なことをザッと眺めてみましょう。

  • 準備
    • Docker イメージのビルド
    • Docker イメージの push
  • デプロイ
    • 自動デプロイや Blue/Green デプロイメントを行う場合は CodePipeline, CodeBuild, CodeDeploy を利用
    • 手動の場合は前述の ECS CLI
  • 実行
    • 機密情報: Secrets Manager を利用
    • 他の AWS リソースへのアクセス制御: IAM role, Security group で管理
    • オートスケーリング: Service Auto Scaling を利用
    • ロギング: CloudWatch Logs を利用
    • モニタリング: CloudWatch Metrics, CloudWatch Metric Filter, CloudWatch Alarm を利用

ザッと書いただけでやること多すぎなようで、これでも漏れがある気がしていますが、一つポイントとしてはモニタリングの部分でしょうか。 Fargate のクラスタ自体のメトリクスはある程度用意されていますが、実際に一番モニタリングしたいのはアプリケーションが正常に動作しているのか、という点ですよね。

そこで使用するのが CloudWatch Metric Filter です。これは CloudWatch Logs のログをフィルタしてカスタムメトリクスとして登録することができるものです。細かいところを言うと機能的な物足りなさはあるものの、これによって例えばログ内の ERROR という文字列を拾ってアプリケーションがエラーログを吐いた時に CloudWatch Alarm によって通知を受け取ることができるわけです。

コンテナのヘルスチェックとはレイヤーの違う、動作しているアプリケーションがどういった状態なのかというのを、 ログを介してマネージドサービスのみで監視できる のは、こういったコンテナサービスを利用する場合に必須となる機能ではないかな、と感じました。だいぶ前に書いた記事にも通ずるものがありますね。

innossh.hatenablog.com

さてリストに書いた全部を説明はできないので省略しますが、実は Docker の基本に関しても AWS の公式ドキュメントに載っていたりするので、 ECS の章を全体的に理解するだけでもかなりの知識が得られるような気がします。

Amazon ECS における Docker の基本 - Amazon Elastic Container Service

本当にゼロから始める場合は難しいこともあるかもしれませんが、チュートリアルに沿って手を動かしつつドキュメントを読むだけでもコンテナサービスの理解度が増すと思います。

...

概要としては以上になります。おそらく実際の設定などを見ないと伝わりにくい部分も多いですよね。 次回は Terraform などのサンプルコードを用意して実際にアプリケーションを動かしてみましょう。 6 月中に書くぞw

Docker/Kubernetes 実践コンテナ開発入門

Docker/Kubernetes 実践コンテナ開発入門