Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Cookpad Tech Kitchen #20 Amazon ECS の安定運用 / Bui...
Search
Kohei Suzuki
November 28, 2018
Technology
1
3.1k
Cookpad Tech Kitchen #20 Amazon ECS の安定運用 / Building a steady ECS infrastructure
Cookpad Tech Kitchen #20
https://cookpad.connpass.com/event/106913/
Kohei Suzuki
November 28, 2018
Tweet
Share
More Decks by Kohei Suzuki
See All by Kohei Suzuki
東京Ruby会議12 Ruby と Rust と私 / Tokyo RubyKaigi 12 Ruby, Rust and me
eagletmt
3
4.7k
少人数でも運用できるインフラ作り / Operating infrastructure with less effort
eagletmt
1
3.1k
Cookpad Lounge #4 SRE 座談会 コンテナ中心の構成からサーバーレスへの展望 / From containers to serverless
eagletmt
0
700
クックパッドでの Webアプリケーション開発 2017 / Web application development in Cookpad 2017
eagletmt
20
10k
ECS を利用したデプロイ環境
eagletmt
12
6.8k
ActiveRecord 3.2 -> 4.1
eagletmt
3
1.9k
クックパッドにおける Rubyの活用
eagletmt
0
520
複数DBとRails
eagletmt
14
7.1k
R/W Splitting in Rails
eagletmt
2
1.5k
Other Decks in Technology
See All in Technology
認知戦の理解と、市民としての対抗策
hogehuga
0
370
株式会社ARAV 採用案内
maqui
0
350
AIエージェント就活入門 - MCPが履歴書になる未来
eltociear
0
530
kintone開発チームの紹介
cybozuinsideout
PRO
0
73k
新規案件の立ち上げ専門チームから見たAI駆動開発の始め方
shuyakinjo
0
130
フルカイテン株式会社 エンジニア向け採用資料
fullkaiten
0
8.6k
モバイルアプリ研修
recruitengineers
PRO
3
260
Goss: Faiss向けの新しい本番環境対応 Goバインディング #coefl_go_jp
bengo4com
0
1.4k
Yahoo!広告ビジネス基盤におけるバックエンド開発
lycorptech_jp
PRO
1
280
事業価値と Engineering
recruitengineers
PRO
2
230
知られざるprops命名の慣習 アクション編
uhyo
11
2.5k
退屈なことはDevinにやらせよう〜〜Devin APIを使ったVisual Regression Testの自動追加〜
kawamataryo
3
680
Featured
See All Featured
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
8
480
Balancing Empowerment & Direction
lara
2
590
The Invisible Side of Design
smashingmag
301
51k
How to Ace a Technical Interview
jacobian
279
23k
Facilitating Awesome Meetings
lara
55
6.5k
How GitHub (no longer) Works
holman
315
140k
The Pragmatic Product Professional
lauravandoore
36
6.8k
Thoughts on Productivity
jonyablonski
69
4.8k
GraphQLとの向き合い方2022年版
quramy
49
14k
A designer walks into a library…
pauljervisheath
207
24k
Bootstrapping a Software Product
garrettdimon
PRO
307
110k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
46
7.6k
Transcript
Amazon ECS の安定運用 Kohei Suzuki
アウトライン - コンテナインスタンスの管理 - スポットインスタンス対応 - コンテナインスタンスのオートスケーリング - ログ -
配送、保存、検索 - モニタリング
規模感 - ほとんどのアプリケーションが ECS 上で動いている - hako (自作ツール) を使ってデプロイやバッチジョブの起動を行っている -
ECS クラスタ数: 40 - 合計 ECS サービス数: 500 - 1日あたりの RunTask 数: 80,000
コンテナインスタンスの管理
コンテナインスタンスの管理 - オンデマンドインスタンスは AutoScaling Group - ECS クラスタと AutoScaling Group
が一対一対応 - スポットインスタンスは Spot Fleet - ECS クラスタと Spot Fleet が一対一対応 - オンデマンド・スポット比: 1:4
Fargate? - 一部では Fargate も使っているが、基本は自前管理のインスタンス - スポットインスタンスを使ったほうが安い - Fargate だと起動が遅い、起動までの時間が安定しない
- Web アプリではそこまで困らない - そこそこの頻度で起動するバッチジョブだとつらい - Fargate を使うケース - ECS クラスタ自体を操作するジョブ (ECS クラスタのオートスケーリング等 ) - 特別に大きな CPU、メモリリソースを必要とするジョブ
オンデマンドクラスタ - 全クラスタで共通の AMI から起動 (※GPU クラスタを除く) - オートスケールは自前 (後述)
- AutoScaling Group の役割 - 「desired capacity を上下するだけで ECS クラスタの増減ができる」状態にする - インスタンス障害からのオートヒール
AutoScaling Group でのサービスアウト - スケールアウトは簡単だが、スケールインをするには事前にサービスアウトして おく必要がある - lifecycle hook の
Terminating:Wait の間にコンテナインスタンスを DRAINING 状態にしてサービスアウト
スポットクラスタ - オンデマンド同様、共通の Ubuntu ベースの AMI から起動 - Spot Fleet
で管理 - こちらもオートスケールは自前 (後述) - Spot Fleet の役割 - 「target capacity を上下するだけで ECS クラスタの増減ができる」状態にする - スポット価格上昇やインスタンス障害からのオートヒール
Spot Fleet でのサービスアウト - Spot Fleet の target capacity を下げてスケールインするときも、スポット価格上
昇で terminate されるときと同じように interruption notice が通知される - interruption notice を CloudWatch Events から SQS キュー経由で受け取り、 デーモンがサービスアウト処理を行う
Spot Fleet でのサービスアウト - AutoScaling Group とは異なり、通知がきてから2分以内にサービスアウトしき る必要がある - バッチジョブは諦めて
StopTask API で止める - スポットクラスタでバッチジョブを動かすときはアプリケーション側に冪等性を要求する - DRAINING 状態にして ECS に任せるだけでは間に合わない可能性がある
Spot Fleet でのサービスアウト - 先に自前で ELB の target group から
deregister する - 先に DeregisterTargets してしまえば新規のリクエストはそのタスクにはこなくなる - DeregisterTargets し終わったら StopTask で止める - ECS や ELB に邪魔されないように deregistration_delay.timeout_seconds を一定 以上にしておく - 突然一部のタスクが停止しても問題無いようにやや過剰なキャパシティを常に 確保しておく - そうしてもスポットインスタンスのほうが安い
Spot Fleet でのサービスアウト (w/o ELB) 1. interruption notice Terminator 3.
StopTask 2. UpdateContainerInstancesState (DRAINING)
Spot Fleet でのサービスアウト (w/ ELB) 1. interruption notice Terminator 5.
StopTask 2. UpdateContainerInstancesState (DRAINING) 3. DeregisterTargets 4. DescribeTargetHealth
オートスケーリング
オートスケーリング - オンデマンドクラスタとスポットクラスタの間で戦略に差は無い - AutoScaling Group の desired capacity を調整するか、Spot
Fleet の target capacity を調整するかの違いだけ - 3種類のスケールアウトと1種類のスケールイン
スケールアウト - クラスタの CPUReservation、MemoryReservation を見て閾値を超えてたらス ケールアウト - 各 service の
desired_count、running_count、pending_count を チェックして足りてなさそうだったらスケールアウト - hako oneshot (バッチジョブの起動) がリソース不足で RunTask に失敗した らスケールアウト
スケールアウト (1) - CloudWatch に入っている CPUReservation、MemoryReservation を定期的に チェックして、閾値を超えていたらスケールアウト - スポットクラスタの場合はオンデマンドクラスタより閾値を低くしている
スケールアウト (2) - 各 service の desired_count、running_count、pending_count を定 期的にチェックして、desired_count >
running_count + pending_count となっていたらリソースが足りずにデプロイが停滞している可 能性があるので、スケールアウトする
スケールアウト (3) - hako oneshot (バッチジョブの起動) がリソース不足で RunTask に失敗した ときに
SNS トピックに通知するので、それを SQS 経由で受け取ってスケールア ウト
スケールアウト (3) AutoScaler Hako 1. RunTask (failed) 2. Publish 3.
ModifySpotFleetRequest 3. SetDesiredCapacity
スケールイン - クラスタの CPUReservation、MemoryReservation を見て閾値を下回っていた らスケールイン - スポットクラスタの場合はオンデマンドクラスタより閾値を低くしている
ログ
ログ - コンテナの stdout/stderr に出たログをどこにどう保存するか - 現在のクックパッドでは Docker の fluentd
logging driver から fluentd を経由 して Amazon S3 に保存し、Amazon Athena で簡易検索できるようにしている
CloudWatch Logs? - マネージドなログの保存、検索、閲覧サービス - しかしログの量が膨大すぎてピークタイムでは CloudWatch Logs にリアルタイ ムに入りきらない
- 入っても検索したり取り出したりするのが遅い - ログを入れるときの料金 (ingestion) だけでもかなり高価に - 閲覧できるまでのラグや検索の柔軟性をやや犠牲にして、スケーラブルで安価 な S3 をログストレージとして選択
ログ配送 Container instances service logs task logs S3 Event ecs-logs-router
fluentd aggregator
ログ配送 Container instances service logs task logs S3 Event ecs-logs-router
fluentd aggregator
ログ配送 - コンテナインスタンスのホスト側に fluentd を起動し、Docker の logging driver の設定でそこへ送信 -
各コンテナインスタンスから fluentd の集約ノードへと転送する - 集約ノードには大量のログが送信されてくる - fluentd v1.0 からは複数プロセスで処理できるようになっているので、それを利用してがんばっ て処理しきる - https://docs.fluentd.org/v1.0/articles/multi-process-workers
ログ配送 Container instances service logs task logs S3 Event ecs-logs-router
fluentd aggregator
ログ配送 - 集約ノードの fluentd が1分毎に s3://service-logs/${task_definition_family}/${container _name}/%Y/%m/%d/%Y%m%d%H%M_%{index}_%{flush_uuid}.gz に ログを出力する -
タスクを横断して、service 毎 (task definition 毎) に閲覧するためのログ
ログ配送 Container instances service logs task logs S3 Event ecs-logs-router
fluentd aggregator
ログ配送 - s3://service-logs に置かれたログを ecs-logs-router がタスク ID 毎に分 解して s3://task-logs/${task_definition_family}/${container_na
me}/${task_id}/ 以下に置く - タスク単位で閲覧するためのログ
ログ検索 - Amazon Athena で検索できるように、AWS Glue でカタログを日次で更新して いる - ${task_definition_family}_${container_name}
というテーブル名 - 日付でパーティションを切っている - 例: my-awesome-app の app コンテナの今日のログから ERROR を探す - select time, log from "my_awesome_app_app" where year = 2018 and month = 11 and day = 28 and log like '%ERROR%' order by time
モニタリング
モニタリング - CloudWatch に service 単位のメトリクスは存在しているが、タスク単位、コンテ ナ単位でのメトリクスは存在していない - したがって RunTask
で起動した場合はメトリクスが一切存在しない - アプリケーション開発者にとって、主に見たいのはアプリケーションコンテナだけ のメトリクス - サイドカーとして起動している fluentd や Envoy 等は要らない
モニタリング - cAdvisor でメトリクスを取得し、Prometheus からそれを scrape し、Grafana で 可視化することにした -
cAdvisor 自体に Prometheus 用のメトリクスを返すエンドポイントがあるので、 これが一番簡単そうだった - cAdvisor は ECS の daemon scheduling を使って各コンテナインスタンスに配 置した
モニタリング
モニタリング
まとめ
まとめ - ECS で様々なサービスを動かすためにやってることの一部を紹介した - オンデマンドインスタンス管理、スポットインスタンス対応 - オートスケーリング戦略 - ログ配送
- モニタリング - 今回話さなかったトピック - ECS API の rate limit を回避するための工夫 - コンテナインスタンス側の問題を調査するためのロギング
今後 - センシティブな値を環境変数に入れる機能がついにきたので移行したい - https://aws.amazon.com/about-aws/whats-new/2018/11/aws-launches-secrets-support-f or-amazon-elastic-container-servic/ - AutoScaling Group でスポットインスタンスを管理できるようになったので移行し
たい - https://aws.amazon.com/jp/blogs/aws/new-ec2-auto-scaling-groups-with-multiple-instan ce-types-purchase-options/