ちょっと話題の記事

【セッションレポート】 第1回 AWS Fargate かんたんデプロイ選手権 【#AWSDevDay】

2019.10.03

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

本記事はDevDay Day1のセッションレポートとなります。
資料についてもすでに公開済みですので合わせてそちらもご確認ください。

セッション概要

AWSのオフィシャルツールを筆頭に、各種OSSを使用したFargateへのコンテナデプロイを考察する。

登壇者

原 康紘 様(アマゾン ウェブ サービス ジャパン株式会社)

セッションの対象と目的

  • Fargateの利用を検討している方
    • デプロイツールの特徴を知りたい方
  • デプロイメントやパイプラインの構築、改善を行いたい方

AWS Fargateとは

  • Dockerコンテナをデプロイする際にツールがないとEC2インスタンスに対してSSH接続してDockerの構築が必要になる
  • この問題を解決するためにECSがサービスとして登場した
    • EC2インスタンス群にDockerコンテナを自動的に構築してくれる
    • EC2インスタンス上で動いているので、OSが動いておりその上でDocker AgentやECS Agent(ECS使用のため)が動いている
      • OSやエージェント類へのパッチ当てや更新、脆弱性対応が必要になる
      • 実行中のコンテナ数に基づく最適なリソース使用率を保つために、EC2インスタンス数のスケーリングが必要になる
      • 結果としてコンテナで楽になるはずがEC2インスタンスのことも考える必要が出るため多重で管理する必要が出てきた
  • 開発者はコードを書いてデプロイしてアプリケーションを作っていく
    • EC2の管理自体はアプリケーションの競争には影響を行わないが手間となる
  • EC2インスタンスとコンテナの多重管理を解消するツールとしてFargateがある
    • Fargateでは完全マネージドなコンテナツールである
    • EC2インスタンスのプロビジョン、スケール、管理が必要なくなる
      • コンテナだけを意識することができる
    • EC2レベルでの制御であるVPCネットワーキング、ELB、IAM、CloudWatchがFargateに使用できる
      • VPC flowlogsなどの機能をそのまま使用できる

Fargateのデプロイ方法

Fargateについての前提知識を揃えたのでデプロイ方法を確認する

1. Task Definitionの定義

  • アプリケーションの実行に必要なコンテナ群を定義する
    • CPU
    • メモリ
    • 使用するコンテナイメージ
    • そのほか...

2. Clusterを作成する

  • アイソレーションの境界定義
  • IAM パーミッション境界定義

3. Task DefinitionからTaskを実行する

  • クラスタに Taskを実行する
    • ECSの「Fargate 起動タイプ」を指定する

4. Servicを作成する

  • 常駐タスクとしてTaskを起動したい場合に作成する
    • 複数タスクの実行状態を維持する
    • ELBと連携を行う
    • unhealthyとなったタスクの自動置き換え

Fargate CLIを使用したデプロイ

  • Fargateを利用するためにはTask Definitionが必要になる
    • Json形式で記述量が少し多いので記述が大変
  • Fargateを簡単に利用するためのコマンドラインツールの1つ
  • turnerlabsがフォークしたFargate CLIもある
    • 運用などを考えたものとなっており挙動が異なる

Fargate CLIによるTaskの実行方法

  1. デフォルトVPCにポート80版を解放したセキュリティグループを作る
  2. Taskを下記コマンドで実行する
$ fargate task run web \
  --image nginx:latest \
  --security-group-id ${SG_ID}

Fargate CLIによるTaskの停止

$ fargate task stop wb

Fargate CLIによるServiceの作成

$ fargate service create web \
  --image ngc-svc:latest \
  --security-group-id ${SG_ID}

Fargate CLIによるServiceの作成

# サービスを0にスケールインする
$ fargate service scale ngx-svc 0

# サービスの削除
$ fargate service destroy ngx-svc

ローカルにあるDockerfileをビルドしてか常駐サービスとして動かす

  1. Dockerfileを用意する
  2. コマンドの実行
$ fargate service create myapp \
  --security-group-id ${SG_ID}

Fargate CLIの中身で行なっていること

  • AWSアカウントにデフォルトで存在するリソースを使用している
    • VPC、サブネット、サブネットとルートテーブルの関連付けが不要
  • セキュリティーグループの作成
    • ユーザで作成するしかないので手動で行う
  • Fargate CLIが自動で作成する内容
    • ECR リポジトリ
    • ECS クラスタ
    • ECSがECRからイメージをPullするなどに必要なポリシーを持ったIAMロールの作成
    • ECS タスク定義
    • ECS サービス定義
    • オプションによってはELBの作成も自動で行える

Fargate CLIのpros cons

  • pros
    • 各種必要リソースが自動生成されるので概念理解や各リソース定義の中身を勉強できる
      • AWSドキュメントは非常に詳細に記述されるのでハードルが高い場合に確認がしやすい
      • --verboseオプションをつけることで内部で何をしているかの確認もできる
  • Cons
    • 本番環境へのデプロイにはあまり使えない
      • 抽象化されているのでFargate CLIのバージョンアップでの後方互換生が保てない可能性がある
    • パイプラインへの組み込みが難しい

AWSでの環境構築

  • 実際はECS以外のリソース(ALB、Aurora...)がある中でどのようにデプロイをするかを考える必要がある
  • ECSサービス更新時にTaskが正常に起動しなかった場合にALB側でどのように処理するかなどの処理も考える必要がある

AWSサービスの考え方

  • AWSサービスはMVP(Minimum Viable Product)で実装してサービスインさせる
  • そのあとにカスタマーからのレビューやユースケースを受けて後方互換を保って機能追加を必要十分に行う
  • ユースケースを広くカバーするためにAPIを公開してAPIが密にならないようにして繋ぎ合わせて様々なユースケースに合わせられるようにしている

Awesome ECS

  • リポジトリ: awesome-ecs
    • ECSを始めるときに見るとよいドキュメント群やツール群をのせたリポジトリ
    • AWSサービスの考え方からわかるようにユースケースに合わせて様々なツールが出来上がる
  • 一部ツールに絞って紹介を下記で行う

AWS CLI

  • リポジトリ: aws-cli
  • pros
    • AWSの新サービスリリース時やサービスアップデートタイミングで必ずそれらに対応している
    • AWS APIの呼び出しパラメータをほぼ全て利用できる
  • cons
    • CI/CDパイプラインの実装がシェル芸になってしまう
    • リソースの依存関係をコマンドの実行順に反映する必要がある
    • ロールバックを想定したスクリプトを描こうとすると複雑化する
    • 自動化との親和性が低い

ECS CLI

  • リポジトリ: amazon-ecs-cli
  • pros
    • Docker Compose定義ファイルを利用したECSサービスの作成と更新に対応している
    • ECS固有の機能(Parameter StoreやFileLensなど)をサポートしている
    • ローカルでの開発が容易になる
  • cons
    • ネットワークやロードバランサー、Fargateサービスなどのリソースについては別ツールで作成する必要がある

ECS Deploy

  • リポジトリ: ecs-deploy
  • pros
    • 1つのシェルスクリプトの中でAWS APIをコールしているだけなので理解しやすい
    • ロールバックなどについても考慮されている
    • コミュニティで作成されているので自前のツールよりは安心、安全に使用できる
  • cons
    • ネットワークやロードバランサー、Fargateサービスなどのリソースについては別ツールで作成する必要がある
    • シェルスクリプトであるので魔改造しやすい

AWS CloudFormation/Terraform

  • リポジトリ: Terraform
  • ドキュメント: CloudFormation
  • pros
    • 単体で全てのAWSリソースを用意できる
    • 定義ファイルをバージョン管理システム管理下に置くことで変更履歴の確認ができる
    • 予定される変更差分を確認できる
    • AWSリソースの依存関係も定義できるのでAWS CLIみたいに実行順序を気にする必要がない
    • 更新できないリソースの場合は新規作成してから更新できる
  • cons
    • 使いこなすためには定義するAWSリソースについて十分な理解が必要になる
    • 最新のAPIパラメータのサポートまでに時間がかかることもある
    • VPCやDBとFargate taskのようにライフサイクルが異なるリソースの管理方法が辛くなる

Ecspresso

  • リポジトリ: ecspresso
  • pros
    • 非常に薄いレイヤで作られたAWS APIラッパーであるため作り込みが少なくてすむ
    • すでに作成しているTask Definitionを後からCI/CDパイプランに載せられる
  • cons
    • ネットワークやロードバランサー、Fargateサービスなどのリソースについては別ツールで作成する必要がある

AWS CDK

  • リポジトリ: aws-cdk
  • pros
    • コードでインフラがかける
    • ユニットテストがJestなどで行える
    • 抽象度が高く多くのパラメータを省略できる
    • バックエンドはCloudFormation
  • cons
    • 抽象度が高いのでユースケース似合わない場合は自前でStackを定義する必要がある

そのほか

  • ECS Task Definitionの補完機能がVSCodeでリリースされた

まとめ

  • どのツールを使用するか
    • 動いているところが確認したい
      • Fargate CLI
    • 運用も見据える場合
      • 単一のツールで記述する
        • AWS CLI、ClouFormation、Terraform、AWS CDK
      • Fargateへのデプロイ + 別リソースは別ツールで行う
        • ecs-deoloy、ecspresso、AWS CDK +上記のツール