CA MOBILE TECH BLOG

株式会社シーエー・モバイルのエンジニア・デザイナーの活動を綴るブログです

株式会社シーエー・モバイルの技術広報による、
技術に特化したブログです。
エンジニアとデザイナーの活動や思想を綴ってゆきます。

【 AWS移管物語-下- 】サービス移管プロジェクトで ECS を導入した話

f:id:cam-engineer:20180305181002p:plain

目次

  1. はじめに
  2. 背景
  3. Amazon Elastic Container Service(ECS) とは
  4. 導入
  5. おわりに

はじめに

はじめまして Y.S です。

約2ヶ月間でサービスの移管を行うというプロジェクトに配属になり、私は主にシステムアーキテクチャの設計とそのセットアップを担当しました。そのなかで、今回は Amazon Elastic Container Service(ECS) を導入するために使用した技術のお話を紹介させて頂きます。

背景

ECS を選んだ理由は以下の要件をみたすためです。

  • ローカル環境でもプロダクション環境と同じようにテストをしたい
  • PHP を使用したシステムのため Apache などの web サーバが必要で、OS を簡単にバージョンアップできるようにしたい
  • インスタンスを管理して Ansible でオーケストレーションするようなことはなるべくしたくない
  • データセンターからの脱却を図っている時期で、クラウド環境への移行を実施する必要がある

構成

様々な検討事項の結果、以下の構成となりました。

f:id:cam-engineer:20180305222145p:plain

Amazon Elastic Container Service(ECS) とは

以下の紹介ページをご確認ください。

  • Amazon Elastic Container Service

aws.amazon.com

簡単に説明しますと以下となります。

  • ECS で使用する EC2 インスタンスからなる ECS クラスターがある
  • ECS クラスター上にサービスがある
  • ECS クラスター内の EC2 インスタンス上で ECS のエージェントが起動している
  • ECS エージェントが、ユーザが指定したコンテナを、ユーザが指定したルールに従い起動し、サービスを提供する

導入

ECS 導入にあたり、以下の点を検討する必要がありました。

  • コンテナ
  • ローカル環境
  • ログ
  • オートスケール
  • 監視
  • CI / リリース

コンテナ

以下の点を考慮し、ソースコードを実行する際の OS は AmazonLinux を使用することにしました。

  • プロダクション環境は AWS 上で実行する
  • AWS で管理しているパッケージを使用できるなど、AWS の恩恵を受けることができる
  • Alpine や Ubuntu は慣れていない人が多い

amazonlinux のコンテナは以下のものを使用しています。

その他、PHP 以外で静的ファイル生成のみに使用するコンテナや golang のようなバイナリのみになるコンテナ場合は Alpine や scratch イメージを使用しています。Alpine や scratch イメージについては以下を参照してください。

ローカル環境

docker-compose を使用し、各種必要なコンテナを起動します。 docker compose は compose ファイルにサービス運用に必要なコンテナをまとめて記載しておくことができるため、管理しやすいのが利点です。

ローカル PC 上のソースコードをコンテナと共有するため、compose ファイルには volumes の設定でソースコードなどを指定します。そうすることでローカル PC 上で編集したソースコードがコンテナ上に即時反映されます。

ログ

ログは stdout と stderr で出力して ECS コンテナや ECS インスタンス内には残さないようにしました。ECS で起動するコンテナは awslogs に対応していますが、GCP の BigQuery や Amazon S3 に直接保存させるため、Fluentd を選択しました。

/etc/ecs/ecs.config には ECS_AVAILABLE_LOGGING_DRIVERS=["json-file","awslogs","fluentd"] を記述しています。

Fluentd を調べると、以下のスライドにて集約パターンが2つあることが確認でき、それぞれ特性がありました。

通信が切断した際の確認のしやすさから、 2-level aggregation を選択しました。Fluentd の Aggregator の前にはロードバランサーを置いて負荷分散しています。ECS インスタンス内で、各種コンテナから最初にログを受け取る collector として起動している Fluentd は ECS インスタンスが起動した直後に起動するようになっています。

今なら以下の資料が参考になります。

Web サーバが必要ない言語では直接 stdout / stderr に出力可能ですが、PHP の場合 Apache などの Web サーバが必要なため、以下を参考にして stdout / stderr に出力するように設定しました。

オートスケール

ECS コンテナのオートスケールは CPU の使用率をトリガーにしています。

ECS インスタンスのオートスケールは ECS クラスターの MemoryReservation メトリクスをトリガーにしています。

  • Amazon Elastic Container Service / チュートリアル: CloudWatch アラームを使用したコンテナインスタンスのスケーリング
    docs.aws.amazon.com

監視

監視は Datadog を使用しました。採用理由として以下があります。

  • タグで管理が可能
  • AWS インテグレーションで CloudWatch のメトリクスでアラート設定が可能
  • Datadog のエージェント (dd-agent) がコンテナで提供されている
  • AutoDiscovery で動的ポートで起動しているコンテナも監視可能
  • グラフのみやすさ

以下ドキュメントです。ECS インスタンスが起動した直後に dd-agent を自動で起動させる設定も含まれており、前述した Fluentd の collector を自動で起動させる設定は、こちらを利用しました。

アラートの設定は

CI / リリース

当時は時間がなかったため、スクリプトを書き、jenkins を使用し CI とリリースを実行していました。

当時のスクリプトでは、docker-compose スタイルのコマンドを使用して、Amazon ECS タスクを管理できる ecs-cli compose コマンドを使用していました。

しかしながら、汎用性に欠けるのとローカルにコマンド実行結果のキャッシュが作成され、サービスの更新ができない場合がある(キャッシュの削除で対応可能)などの弊害があったため、後に aws-cli へ変更しました。

さらに現在では新しいサービスでは jenkins の代わりに wercker を使用してます。当時 wercker を選択した理由は以下です。

  • コンテナベースで CI が可能だった
  • 実行するコンテナは ECR にアップロードしている自作のコンテナを指定できた
  • 他の CI サービスにはない ECS / ECR のインテグレーションがあった
  • steps と言われる特定の動作を自動化したタスクが数多く有り、使用することが可能だった
  • steps を自身で作成することも可能だった

  • Amazon ECS and ECR
    devcenter.wercker.com

現時点では CircleCi 2.0 で同じようなことが可能のようです

おわりに

2ヶ月という短い期間でしたが、はじめての ECS でも問題は発生せず移管が完了しました。現在では多くのプロジェクトで ECS が利用されており、CloudFormation を利用することで簡単にセットアップできるようになっております。

最後に ECS のトラブルシューティングの際に役立つドキュメントを以下に記します。