Docker Compose For ECSでプロビジョンドスループットの高額請求に驚いた話
みなさんこんにちは、テスト自動化アーキテクトの森川です
ECSで高額請求を初めて体験したので、これはシェアせねばと筆を取りました。どなたかのクラウドライフの助けになれば幸いです
Docker Compose CLI for ECSで業務アプリをECS化
EC2で試験運用している社内の業務アプリをECS化するためにリサーチしておりましてAWSのco-pilotやecspresso、terraformも視野に入れつつ
Docker Compose CLI for AWSでECS環境をFargeteで構築してみることにしました。
Docker公式ドキュメントを見ながら
・docker compose cliのインストール
・docker contextの作成と切り替え
・docker-compose.ymlを作成
を経てチュートリアル的なお試し環境を構築してみました。
パラメータを試すために何度かcompose up / downを繰り返して、その日は課題を整理して終わります。
ある朝、AWSの請求額が見たことのない数字に・・・
「$1.5Kって。。。1500ドル?って17~18万円?」
プロビジョンドスループットは7.2ドル(MB/秒-月)
あわてて明細を見ると問題はElastic File System(EFS)の「Provisioned Throughput」にありました。
この7.2ドルの単位「MiBps-Mo(「MB/秒-月)」はAWS公式サイトによると
高額請求で胃がキューッとなっている私にはとても理解できる文章ではありません。(っていうかパッと分かる人いる?)
AWS公式サイトには請求例が載せられていて「例3」がそれにあたります。
・ストレージ月額料金 (上記の計算結果を参照してください): 40.00 USD
・デフォルトのスループット (MB/秒-時間) = (74,400 GB-時間/20 GB-時間) * 1 MB/秒-時間 = 3,720 MB/秒-時間
・プロビジョンドスループットの合計 (MB/秒-時間) = 10 MB/秒 x 31 x 24 時 間/日 = 7,440 MB/秒-時間
・課金されるプロビジョンドスループットの合計 (MB/秒-時間) = 7,440 MB/ 秒-時間 – 3,720 MB/秒-時間 = 3,720 MB/秒-時間
・課金されるプロビジョンドスループットの合計 (MB/秒-月) = 3,720 MB/秒- 時間 / (31 日間/月 x 24 時間/日) = 5 MB-月
・プロビジョンドスループット月額料金 = 5 MB/秒-月 x 6.00 = 30.00 USD
・合計月額料金 = ストレージ月額料金 + スループット月額料金 = 40.00 USD + 30.00 USD = 70.00 USD
※ AWS公式サイトより引用
細かいところは要約すると利用期間は数日だったので月の平均スループットが200MiB/秒とみなされて、
それで「7.2ドル × 約200MiB/秒 ≒ 1500ドル」となっていました。
このままのペースだと月額で1024MiB/秒つまり7000ドル/月ほどになるとか・・・
あわててすぐにEFSボリュームを削除しました。
原因調査/悪いのは自分だった
「どうしてこうなった」 ということで検証します。
■ 原因: 明示的にスループットモードと、プロビジョニングの最大値を指定していた
問題はコンテナのVolumeを定義するVolumesセクションでした
ECSのタスクをFargateでホストする場合は、データボリュームはEFSを使用するかな、ということで指定の公式サイトの記載例に従ってVolumesセクションを書きました。
# docker-compose.yml
volumes:
my-volume:
driver_opts:
backup_policy: ENABLED
lifecycle_policy: AFTER_14_DAYS
performance_mode: maxIO
throughput_mode: provisioned 👈 コレと
provisioned_throughput: 1024 👈 コレで約1500ドルのコンボ
volumes | ECS integration composefile examples - Docker Documentation
よく見ると throughput_mode: provisionedとなっています。
これ、明らかにプロビジョニングなスループットモード設定です。
そしてスループット (MB/秒-時間)はバーン!と最大値の「1024」になっています。
driver_optsはファイルシステムの初期状態を設定する親パラメータでDocker公式にはその詳細は記載がありませんが、EFSのCreateFileSystemのリファレンスが該当情報のようです(関連性は確かではない)
CreateFileSystem - Amazon Elastic File System
こちらによるとthroughput_modeのデフォルト値は「bursting」です。
そしてprovisioned_throughputのデフォルトは最小値の「1.0」とのこと。
なんとまぁ
余計な設定をしなければプロビジョンドスループットモード&最大スループットには、ならなかったと。
私が悪いです、これは完全に。
★本日の気をつけたいこと★
throughput_modeは意図的にプロビジョニングさせたい場合でなければ、デフォルトまたはburstingにしましょう
同様にprovisioned_throughputは、デフォルト設定または最小値「1.0」にしましょう
# docker-compose.yml
volumes:
my-volume:
driver_opts:
throughput_mode: bursting 👈 デフォルトでも良い
provisioned_throughput: 1.0 👈 デフォルトでも良い
※ 他の幾つかの紹介記事でも記載例が「provisioned & 1024」コンボになっているのを見かけました。
気になりますが、心の中にそっとしまっておきます。
このあとデフォルト設定でクラスタを起動して、作成されたボリュームのEFSスループットモードが「バーストモード」となっていることを確認しました
防止策
対策を考えてみました。
■事前にチェックする
まずサービス利用前にクリティカルな請求金額になり得る料金設定を見ておきたいです。
今回だと「プロビジョンドスループット(MB/秒-月)」この単位が単純な時間掛けではなく「秒」を含むこと、他のEFSの料金と比べて単価が高いことに留意すべきでした。
■パラメータ設定
今回のDocker Compose For CLIのようにAWS公式のリファレンスが無い場合はベストエフォートにはなってしまいますがCLIで設定ファイルを書くときのパラメータには注意しておきたいです。
「throughput_mode」、「provisioned_throughput」というパラメータ名から、上述のプロビジョンドスループットの課金体系との紐づきを想像して進めるべきです。
■監視
抜本的な解決にはならないとはいえ、EFSのメトリクス監視と料金の監視はやっておきたいです。
AWS の予想請求額をモニタリングする請求アラームの作成 - Amazon CloudWatch
ClouldWatchのダッシュボードでEFSのメトリクス「BurstCreditBalance」や「PermittedThroughput」等を監視するとよさそうです。
Amazon EFS の Amazon CloudWatch メトリクス - Amazon Elastic File System
本記事のような明らかなミスの事例はさておき、クラウドのコスト調整はなかなか難しいところがあると思います。
プロジェクト内にかぎらず部署間やチーム間で知見を共有して取り組めると理想的ですね。
最後に
今回、初めてクラウドの意図しない高額請求というのを体験しました。
酔ってECサイトで高額商品を誤ポチするよりもはるかに胃に悪いです。
そしてそれを赤裸々に記事化するのもさらに胃に悪いです。
とはいえ技術検証や調査時にうっかり発生しやすい事象でもあると思うので
事前の安全対策は必須だなとお腹を擦りながら独りごちております。
駄文にお付き合いいただき多謝でございます。(執筆時間3.5H)
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/