dely engineering blog

レシピ動画サービス「kurashiru」を運営するdelyのテックブログ

kurashiruとECSとデプロイ

はじめに

本記事はdely Advent Calendar 2018の18日目の記事です。

Qiita : dely Advent Calendar 2018 - Qiita
Adventar : dely Advent Calendar 2018 - Adventar

昨日は弊社iOSエンジニアの堀口(@takaoh717)が「エンジニアがCSと上手く連携するためのコミュニケーション」をタイトルに記事を書きましたので是非読んでみてください。

tech.dely.jp

こんにちは!delyでSREをしている井上です。 本記事では現在kurashiruで運用しているECSとデプロイについてご紹介したいと思います。

delyではインフラにメインでAWSを利用しており、kurashiruのインフラは主にECSで構築されています。直近の半年では、より高速にデプロイが完了できるようにDockerのbuildを非同期で行ったり、コンテナインスタンスのCPUとメモリが効率的に使えるようにタスクの定義情報の最適化を行ったりなどいくつかの改善を行いましたが、現状のフェーズにおいては安定して運用できているので今回紹介したいと思います!

EC2とECSについて

イメージが伝わりやすくなるようにかなり簡略化していますが下記のような構成になっています。

f:id:gomesuit:20181216224515p:plain

コンテナインスタンス

コンテナインスタンスはオンデマンドインスタンスとスポットインスタンスを併用することでコストを抑えています。

オンデマンドインスタンスのオートスケールはオートスケーリンググループを利用して行っており、スポットフリートのキャパシティはオンデマンドインスタンスの数に応じて増減するようにLambdaを使って制御しています。

また、スポットインスタンスは中断される可能性があるため、中断のイベントをCloudWatchで拾ってLambdaで該当のコンテナインスタンスをドレイン状態にするという制御を行っています。

docs.aws.amazon.com

ちなみにデータプレーンにEC2ではなくFargateを使うという選択肢もありますが、下記の理由から本格的な導入は行っていない状況です。

  • EC2と比較して料金が割高
  • 起動が遅い(Dockerのレイヤキャッシュが効かない)
  • CPU・メモリが柔軟に設定出来ない

特にコスト面はスポットと比較するとかなり割高になってしまうので、現状だと全てをFargateに乗り換えるという選択は厳しいです・・・

Fargateにもスポットの対応が待ち望まれますね!

f:id:gomesuit:20181218102145p:plain:w300

ECS

ECSにおいては、WEBやAPIといったドメイン単位でターゲットグループを分けて構築しています。 また、ターゲットグループ毎にred, yellow, greenの3つでサービスを分けていて、タスク定義は同一のものを設定しています。

3つのサービスのうちgreenだけはオートスケール設定を行っていて、トラフィックに応じてタスク数が増減するようにしています。
また3つに分けることによって、デプロイ時に新バージョンをred -> yellow -> greenといったように段階的な反映を可能としており、red、yellowに反映させた状態でエラーの有無やログの確認を行い、問題がなければgreenに反映するという運用を行っています。

デプロイについて

フロー

こちらもイメージが伝わりやすいようにSNSなどは省略して記載しています。

f:id:gomesuit:20181216232229p:plain

CodePipeline

デプロイは内部的にはCodePipelineを使って制御しています。

サービスredのデプロイはCodePipelineからECSに直接デプロイする機能を使っていますが、サービスyellow、greenはLambdaを使ってデプロイしています。3つのサービス全てに対してCodePipelineのECSデプロイ機能を利用した場合、タスク定義のバージョンが3つのサービスで一つずつずれてしまいます。そのためサービスredのタスク定義のバージョンと同じバージョンでデプロイするためにyellow、greenのデプロイはLambdaを使っています。

また各サービス(red, yellow, green)のデプロイの直前にCodePipelineの承認アクションを設定しています。これによって開発者がそれぞれのサービスにデプロイするタイミングをコントロール出来るようにしています。

Slackを利用したデプロイ

デプロイは開発者がSlackのChatBotから行っています。 Slackを利用したデプロイの流れ(例)を紹介します。

開発者がSlackのチャンネルにおいて下記のように送信すると、

f:id:gomesuit:20181218095146p:plain:w250

サービスredのデプロイ開始待ちになります。
デプロイを開始するタイミングをコントロールできるようにSlackのボタンでCodePipelineの承認アクションを制御しています。

f:id:gomesuit:20181218095227p:plain:w500

Approveをクリックすると、

f:id:gomesuit:20181218095315p:plain:w410

サービスredのデプロイが開始されます。

f:id:gomesuit:20181218095459p:plain:w500

サービスredのデプロイが完了するとサービスyellowのデプロイ開始待ちになります。
このタイミングで新バージョンでのエラーや怪しいログが発生していないか確認します。 確認後、Approveをクリックすると、

f:id:gomesuit:20181218095538p:plain:w410

サービスyellowのデプロイが開始されます。

f:id:gomesuit:20181218095609p:plain:w500

サービスyellowのデプロイが完了するとサービスgreenのデプロイ開始待ちになります。
Approveをクリックすると、

f:id:gomesuit:20181218095631p:plain:w410

サービスgreenのデプロイが開始されます。

f:id:gomesuit:20181218095759p:plain:w450

デプロイが正常終了するとデプロイ完了の通知が届きます。

さいごに

簡単にはなりますがkurashiruで運用しているECSとデプロイについてご紹介しました。オーケストレーションツールはKubernetes一強ですが、現段階はECSで運用しています。組織やプロダクトの成長に伴って、インフラは何を求められ、提供できるのかを考え今後オーケストレーションツールに何を採用するのかを見極めていきたいと思っています。

ちなみに先日行われたAWS re:Invent 2018ではたくさんの機能追加や新しいサービスが紹介されました。その中でも今回紹介した構成の中で利用できそうなものがあったので抽出してみました!

  • CodePipelineがソースをECRに対応

aws.amazon.com

  • オートスケーリンググループ内でオンデマンドインスタンスとスポットインスタンスを混在させられる

aws.amazon.com

  • CodeDeployがECS対応

aws.amazon.com

まだ手がつけられていないので、時間を見つけて検証し、より使いやすいデプロイ環境にしていこうと思っています!

明日は新米slackBot整備士のjoe (@joooee0000) が「サーバーレス+Go言語で作るインタラクティブな哲学slackBot」というタイトルで投稿します!お楽しみに!