$30 off During Our Annual Pro Sale. View Details »

2021-06-cloud-native-reg-event

 2021-06-cloud-native-reg-event

発表タイトル:
MackerelにおけるEC2からFargate移行の軌跡とFargateのメリットデメリットについて

イベント名:
そろそろマネージド、クラウドネイティブで行こう!
コンテナサービスへの移行祭り

https://pages.awscloud.com/JAPAN-event-OE-20210617-Cloud-native-reg-event.html

masayoshi

June 17, 2021
Tweet

More Decks by masayoshi

Other Decks in Technology

Transcript

  1. 2021.06.18
    株式会社はてな
    Mackerelチーム リードSRE
    古川 雅大
    MackerelにおけるEC2からFargate移行
    の軌跡と
    Fargateのメリットデメリットについて

    View Slide

  2. - 名前: 古川 雅大 ( id:masayoshi Twitter: @yoyogidesaiz )
    - 所属: 株式会社はてな
    - MackerelチームのリードSRE (Site Reliability Engineer)
    - 趣味
    - ネットワーク、サーバーをいじること
    - 格闘ゲーム
    自己紹介

    View Slide

  3. Mackerelとは

    View Slide

  4. クラウド運用を簡単にはじめられる
    SaaS型サーバー監視サービス
    Mackerelの特徴
    ● システムの運用・監視を簡単にはじめられます
    ● クラウド時代に最適な監視モデルをもとに素早く導入できます
    ● 日本語ドキュメントやサポートによって成長を後押しします
    4

    View Slide

  5. システムの運用・監視を簡単にはじめられます
    ➔ 導入はガイドにしたがってコマンドを実行するだけ
    ➔ エージェントが死活監視とメトリック取得を自動で開始
    ➔ 直感的なUIでサービスの状況を可視化
    ➔ 監視をはじめる敷居が下がり、チームで取り組めます
    5

    View Slide

  6. - 対象
    - EC2やVM環境からFargate(ECS)を目指す人向けに事例紹介
    - ECSに関わることが中心 (コンテナ化自体の話は省略)
    - 構成
    - Mackerelのインフラ構成の変遷
    - 移行前の課題と移行の目的
    - 移行時、移行後で困った点
    - 移行時の工夫
    - 移行してよかったこと
    - これから移行する人へ
    - 付録
    今日話すこと
    * Dockerfileの書き方とか工夫など

    View Slide

  7. Mackerelのインフラ構成の変遷

    View Slide

  8. Mackerelのインフラ構成の変遷
    On-premises Cloud First Cloud Native
    2014 2017 2019
    2015 2016 2018 2020 2021
    ・Compute
    VM
    Xen Hypervisor
    ・Time Series Database
    ioMemory
    Graphite
    ・Relational Database
    PostgreSQL
    ・Compute
    VM
    EC2
    ・Time Series Database
    Redis
    DynamoDB
    S3
    ・Relational Database
    RDS(PostgreSQL)
    ・Compute
    Container
    ECS
    ・Time Series Database
    ElastiCache
    DynamoDB
    S3
    ・Relational Database
    RDS(PostgreSQL)

    View Slide

  9. - On-premisesのときのTSDB(Graphite)
    - Mackerelを支える時系列データベース技術
    オンプレ => AWS EC2移行(公開資料)
    https://blog.yuuk.io/entry/high-performance-graphite
    - Cloud First(AWS移行後)のTSDB(diamond)
    - 時系列データベースという概念をクラウドの技で再構築する
    -
    - AWSで実現した Mackerel 時系列データ1分粒度長期保存の裏側
    -
    - On-premisesからAWS移行のお話
    - Mackerel インフラ基盤 AWS 移行の舞台裏
    -
    - Mackerel をオンプレミスから AWS に移してからの1年半を振り返る
    https://speakerdeck.com/kizkoh/mackerel-inhuraji-pan-aws-yi-xing-falsewu-tai-li
    https://blog.astj.space/entry/2018/02/06/175902
    https://blog.yuuk.io/entry/the-rebuild-of-tsdb-on-cloud
    https://blog.astj.space/entry/2019/03/07/110234

    View Slide

  10. - アプリケーションサーバーをEC2からECS Fargateに移行
    - Scala アプリケーション1つ
    - go アプリケーション6つ
    - 実行環境はEC2だったが、BuildはDockerで実施 (Dockerfile化済み)
    - 移行した台数はEC2 100台以上
    - 50台以上のRedis Cluster on EC2をElastiCacheに移行
    - 参考
    - 「Mackerel の時系列データベースにおける Redis Cluster の利用と Amazon ElastiCache への移行について」
    - https://speakerdeck.com/astj/aws-purpose-built-databases-week
    EC2からECS Fargate移行

    View Slide

  11. 移行前の課題と移行の目的

    View Slide

  12. - コンテナ運用知見の獲得 (Mackerelチーム特有の課題)
    - EC2運用の課題の解決 (一般的な課題)
    MackerelチームのFargate移行の目的

    View Slide

  13. - Mackerel SREチームのミッション
    - SLOに基づいたサービス運用
    - インフラ運用をドッグフーディングできる環境を開発チームに提供
    - ミッションに基づいた目的設定
    - コンテナ運用環境でMackerelをSLOに基づいて安定運用すること
    - 特にk8sとECS
    - 「コンテナ運用をすること」自体がプロダクトに貢献
    - 「運用が楽になること」が目的ではない
    コンテナ運用知見の獲得
    * 多くのサービスではコンテナ運用は手段であり、目的になることはほとんどないため、Mackerelチーム特有の課題

    View Slide

  14. - デプロイがAMIを生成する方式ではなかった
    - 1回作ったEC2に、アプリケーションをデプロイする方式 (インプレース)
    - EC2はchefの実行や、社内ホスト名やDNS登録などをするため
    社内共通スクリプトで構築していた
    - オンプレ環境のレガシー基盤に引きづられていた
    - Auto Scaling Groupを活用出来ていなかった
    - そのため、回復性の課題が存在した
    - 1台落ちたら人間が起動し直していた
    - EC2メンテナンスなどの対応が必要 (月1回以上の頻度)
    - AZ障害時にAZの移動に時間がかかっていた
    - EC2の構築のたびにchefを実行
    EC2運用の課題

    View Slide

  15. クラウドネイティブ技術は、
    パブリッククラウド、プライベートクラウド、ハイブリッドクラウドなどの
    近代的でダイナミックな環境において、
    スケーラブルなアプリケーションを構築および実行するための能力を
    組織にもたらします。
    CloudNative
    CNCF Cloud Native Definition v1.0 https://github.com/cncf/toc/blob/main/DEFINITION.md (2021/06/08)

    View Slide

  16. - 回復性
    - サーバーの自動復旧
    - オートスケール
    - 管理性
    - 可観測性
    CloudNative ~ダイナミックな環境~
    CNCF Cloud Native Definition v1.0 https://github.com/cncf/toc/blob/main/DEFINITION.md (2021/06/08)
    これらの手法により、回復性、管理力、および可観測性のある疎結合システムが実
    現します。

    View Slide

  17. - EC2 Image Builder + AutoScaling Group
    - コンテナ運用知見の獲得にはつながらない
    - 検討時(2019/8) にはEC2 Image Builderもなかった
    - EKS (Fargate)
    - 検討時(2019/8) にはEKS on Fargateはなかった
    - EKS (EC2)
    - k8s自体の学習コストやk8sクラスター更新頻度の高さで不採用
    - ECS (EC2)
    - Fargateで実現が難しければ採用
    - ECS (Fargate)
    - 必要な要件を満たしており移行コストが一番下げられるので採用
    - 社内でも運用実績があり、メンバーの学習コストが抑えられる
    AWSで実現するダイナミックな環境

    View Slide

  18. - 当初はk8sに移行する予定だった
    - k8s運用のドッグフーディング + CloudNativeが目的
    - 検討当時(2018夏)はEKSの東京リージョンがなかった
    - EC2上にk8sを自前で構築
    - 本番環境は数ヶ月チャレンジしたが撤退した
    - 学習コスト、更新頻度などでSLOを満たすことが難しかった
    - 「SLOを満たす & コンテナ運用のドッグフーディング」
    - AWSのコンテナサービスを活用してリトライ
    - 参考資料
    - Blog
    - 発表資料
    - 記事
    (参考)k8s化にチャレンジして出直し
    https://developer.hatenastaff.com/entry/leading-kubernetes-at-hatena
    https://speakerdeck.com/hayajo/kubernetes-meetup-tokyo-number-22
    https://www.atmarkit.co.jp/ait/articles/1911/08/news009.html
    * 当時MackerelチームのSREは1人だった

    View Slide

  19. - 社内での運用実績や運用負荷を考慮し選択
    - 自分たちがコンテナ運用環境を始めることを重視
    - CodeDeployによるBlue/Green Deployを選択
    - 最初はCFnによるローリングデプロイだった
    - Terraformの採用
    - 他のクラウドサービスの利用
    - 当時CFnがCodeDeploy Blue/Greenに非対応だった
    - module化が容易
    - 参考: terraform周りの話
    ECS Fargateへの移行
    https://speakerdeck.com/heleeen/our-best-practice

    View Slide

  20. 移行時、移行後で困った点

    View Slide

  21. - Fargate移行に関しての大きな困りごとはなかった
    - 移行コスト、難易度が低かった
    - 特にgoのアプリケーションは何事もなく移行完了
    - JVM周りの注意点や困り事
    - JVMのウォームアップ
    - JVMとECS TaskDefinitionとcpu.shares
    - JVMが利用するCPU数の設定に関する問題 (詳細は付録を参照)
    - Fargate環境における困り事
    - デバッグが難しい
    - platform側で発生する問題
    移行時、移行後に困った点
    * 本発表は Java 11 を前提にしてお話しています

    View Slide

  22. - JVMは起動時に遅い
    - クラスのロードなど
    - ECSはALBのHealthCheckがUnhealthyだとタスク(コンテナ)を終了する
    - 起動時に遅い => 一瞬Unhealthyになる => 再起動 のクラッシュループ
    - Deploy時やコンテナの異常終了時に発生しうる
    - ALBに投入される前にウォームアップを完了する必要がある
    JVMのウォームアップ

    View Slide

  23. - warmupコンテナ
    - dependsOnを利用し、appコンテナのHealthy状態を依存関係にしておく
    - いくつかのwarmupスクリプトをappコンテナに対して実行
    - warmup中はAppをメンテナンスモードにしておく
    - warmupが終わったら終了
    - Appコンテナ
    - HealthCheckのstartPeriodをwarmupの実行時間以上にしておく
    - その後HealthCheckが通ったら起動フェーズ終了
    - ALBに投入
    - ECS Service
    - HealthCheckGracePeriodSecondsも併せて検討
    - RUNNING 状態になった後のヘルスチェックを無視できる
    JVMのウォームアップ ~解決策~
    * k8sの場合はこちらが参考になります https://techblog.zozo.com/entry/zozomat-jvm-warmup
    * warmup以外にもタスク起動時の初期化でやりたい処理は同じ作戦が使える

    View Slide

  24. containerDefinitions:
    - name: app
    essential: true
    healthCheck:
    command:
    - CMD-SHELL
    - curl -L -s -o /dev/null http://localhost:8000/healthcheck || exit 1
    interval: 5
    retries: 10
    startPeriod: 60
    timeout: 5
    - name: warmup
    dependsOn:
    - condition: HEALTHY
    containerName: app
    entryPoint:
    - /opt/bin/warmup.sh
    JVMのウォームアップ ~解決策~
    * dependsOnとhealthCheckの組み合わせで初期化

    View Slide

  25. - 先程のwarmupや、cpu.sharesのリソース動作確認
    - その他にもJVMのHeapdump取りたいなど
    - EC2と比べてリモート接続や特権制御により難しい
    - Fargateのデメリット
    - 解決策
    - JVMはJMXのリモート接続でモニタリング
    - SSHできるサイドカーを用意してデバッグ作業
    - 現在はPlatform Version 1.4.0でECS execによるデバッグが可能
    - サポートの活用
    - SAなどへの相談やサポート問い合わせ
    デバッグが難しい

    View Slide

  26. - マネージドサービスもplatform側の問題やエラーもある
    - 不具合の起きないシステム、サービスはない
    - 致命的な問題は遭遇していない
    - 解決策
    - サポートの活用
    - ユーザーだけの調査には限界がある
    - SA, TAMなどへの相談やサポート問い合わせ
    - 特にスペシャリストへの相談は非常に役立つ
    - ビジネス、エンタープライズサポートへの加入をお薦め
    platform側で発生する問題

    View Slide

  27. - 特定の条件でplatform側でエラーが発生する事象
    - サポートが1ヶ月程度かけて調査してくれた
    - その間、我々は他のタスクに集中できる (調査工数の削減)
    - 現在も不明なエラー事象に遭遇している
    - platform側の問題なのか、設定やコード上の問題など原因の切り分け中
    - SAの方と相談、サポートへの調査や再現を依頼
    - マネージドサービスはOSSのようにコードを読めない、直せない
    - 代わりにサポートやスペシャリストと相談できる
    - マネージドサービスを利用するなら併せてサポートプランも検討
    platform側で発生する問題

    View Slide

  28. 移行時の工夫

    View Slide

  29. - terraform moduleの活用
    - Weighted Routingを活用したEC2とECSの同時稼働
    - SLOによる本番投入や切り戻し基準の設定
    移行時の工夫

    View Slide

  30. - module化
    - ECSクラスタ、ECS Serviceの作成
    - CodePipeline, CodeDeployのCI/CDパイプライン
    - 後述するデプロイ時に起動するlambdaなど
    - goとscala合わせて7つ移設
    - すべて同じmoduleで構築できたため構築、管理工数削減
    - 詳細はこちら
    - 「Mackerel におけるTerraform 運用 / Our (Best?) Practice」
    - https://speakerdeck.com/heleeen/our-best-practice
    terraform moduleの活用

    View Slide

  31. - DNSでやる方法
    - ECS,EC2のALBエンドポイントをRoute53でDNSラウンドロビン
    - Route53の機能でできるので実装が容易
    - 前段のクライアントの数が少ないと
    %の低い振り分けが難しい
    - 4台の場合1台のキャッシュに乗ると、短期的に見ると
    25%のトラフィックが来てしまうことが
    ある
    - Weighted Routingでやる方法
    - ECS, EC2のTargetGroupのWeightを変更することによって振り分け
    - 振り分けの%を正確にできる(1%とかも可能)
    - AWS側での機能がないのでlambdaで作り込みが必要
    - B/GだとTargetGroupがデプロイのたびに変わる
    - B/Gの制約でECSのTargetGroupをEC2のALBにつけられない
    EC2とECSの同時稼働

    View Slide

  32. View Slide

  33. - SLOを基準に判断
    - staging環境でSLOを満たしていたら本番投入OK
    - エラーレート1%以上 レイテンシ 99%ile 200ms 以上
    ならECS weightを0にして切り戻す
    - 「正常に動いている」とはどういうことを指すのかSLOで表現
    - 本番投入時のスプリントはSLOを再検討
    - 移設時などはSLOを下げるなど、スプリントで話し合うことで移設担当者の
    精神的負荷を軽減できる
    - 移設タイミングでSLOが十分に余っていることを確認する
    - SLOが余っているなら積極的に投入していく
    SLOによる本番投入や切り戻し基準の設定

    View Slide

  34. - SLOで判断するということはSLIの実装が必要
    - ALBのステータスコードの割合、レイテンシなどはすぐ可視化できる
    - MackerelのAWSインテグレーション機能でメトリックを取得し、式グラフで可
    視化、監視できる
    - MackerelでのALBの式監視の例はこちら
    - CloudWatch Logs Insightsでログ集計するlambdaを作成
    - ログ数をカウントしMackerelにサービスメトリックとして投稿
    - SLIの実装は大切だが、最初は実装難易度の高いものにしないほうが良い
    - いつまで経っても移行が終わらなくなってしまう
    - 運用は育てていくものなので、移行後にSLI/SLOを継続的に改善する
    SLIの実装
    https://mackerel.io/ja/blog/entry/2020/12/12/000000

    View Slide

  35. MackerelのSLO(可用性)ダッシュボードの例
    ※ 数字ははめ込み加工なので実際の Mackerelの可用性とは異なります

    View Slide

  36. 移行してよかったこと

    View Slide

  37. - EC2インスタンス管理から解放
    - コンテナ運用知見の獲得
    - CI/CDがB/Gになり、リリースフローが改善
    移行してよかったこと

    View Slide

  38. - EC2 メンテナンスから解放
    - 月1回程度のEC2メンテナンスがほぼ0件に
    - Fargateもホスト側のメンテナンスがあるが勝手に起動
    - 回復性
    - タスク落ちても勝手に起動してくれる
    - warmupも対応したので対応が不要
    - AZ障害のとき、CodeDeployでsubnet指定をしてデプロイするだけ
    - 管理性
    - 台数増加が楽になった
    - ホストOSのバージョンアップやchefメンテナンスが不要
    - 特にホストOSの脆弱性対応など
    EC2インスタンス管理から解放
    * EC2 AutoScaling Groupでも実現可能な項目もある

    View Slide

  39. - メリット
    - CloudNativeな環境を容易に手に入れられる
    - 特に回復性
    - AutoScaling Groupのキャパシティプランニングや構築より容易
    - k8sと比べて学習コストや、クラスターのバージョンアップなどが容易
    - デメリット
    - デバッグが難しい (デバッグが簡単にならない)
    - 自前の基盤を用意したとしてもFargateよりデバッグが容易になるとは限らない
    - サポートを活用することでカバーは可能
    - ECS execなど、今後もデバッグが容易になる機能が追加されると思われる
    Fargateのメリット、デメリット
    * 充実したエコシステムを利用したCI/CDなどk8sはk8sでメリットも多い
    移行コストを抑えながら、CloudNative移行ならFargate(ECS)がお薦め!

    View Slide

  40. これから移行に挑戦する方へ

    View Slide

  41. - 移行の目的や判断基準をチーム内で共有する
    - SREの文化があるならSLOなどを活用
    - マネージドサービスから検討し、だめなら自前で
    - ECSで行くなら Fargate > ECS on EC2
    - k8sで行くなら Fargate for EKS > EKS
    - コンテナ化が難しいならEC2 AutoScaling Group
    - CloudNative実現にはかなり作り込みが必要
    - サポートプランも併せて検討
    - 移行時の相談やマネージドサービス利用時の不具合や障害で活用
    - 移行後も運用は続く
    - 移行時にすべての問題を解決する必要はない
    - 「移行タイミングはいい機会だからあれもこれも」は要注意!
    これから移行に挑戦する方へ
    * コンテナの前にlambdaなどサーバーレスも検討できると最高!

    View Slide

  42. (付録) 時間の関係で省略した内容

    View Slide

  43. - containerDefinitionsでcpuを指定しないと0になる
    - Linuxではcpu.sharesの最低値が2なので2になる
    - JVMとしてはプロセッサカウント1になる
    - ceil(min(cpuset-cpus, cpu-shares/1024, cpus))
    - ceil(2/1024) = 1 (processor)
    - taskdefで4096でもcontainerdefで0だと1024しか使えない
    - 解決策
    - -XX:ActiveProcessorCountで明示的に設定
    - JVM側でコンテナ対応のための変更が入る可能性がある
    - autodetectやデフォルト値の算出方法が変わる可能性あり
    JVMとECSとcpu.shares
    * https://github.com/aws/amazon-ecs-agent/issues/1735

    View Slide

  44. - JVM自体が一種のコンテナ
    - コンテナ(JVM) on コンテナ(Docker) 的な感じになる
    - task全体のリソース制御
    - Container毎のリソース制御(cgroup)
    - JVMのリソース制御
    - warmup周りやイメージサイズなど起動時の問題
    - その他にも
    - Xms, Xmx, InitialRAMPercentage, MaxRAMPercentage など
    JVMのリソース管理
    * https://speakerdeck.com/hhiroshell/jvm-on-kubernetes

    View Slide

  45. - ユーザへのアラート通知や外形監視機能の接続元IPアドレス
    - ユーザーがfirewallなどの設定に利用
    - 移行前の構成
    - EC2にEIPをつけていた
    - ECSタスクに直接グローバルIPを付与することは出来ない
    - 解決策
    - Subnetを別に作成しNatGatewayにEIPを付与
    - NatGatewayが増えたのでコストは増えた
    グローバルIPの固定
    * https://support.mackerel.io/hc/ja/articles/360039701332-Webhook通知や外形監視など-Mackerelからの通知元IPアドレスは-

    View Slide

  46. - 同じECS Serviceでもタスクがデプロイされるホストが異なることが
    ある
    - CPUが違ったり、ネットワークインターフェースが違ったり
    - 2020/6ではPlatform Version 1.4.0内でも3種類ぐらい確認
    - 同じvCPU指定でもパフォーマンスはタスクによって異なる
    - 大きくは異ならないようにしていると思われる
    - t3, m5相当?
    - C5などのEC2から移行する場合は1Coreあたりの処理性能に注意
    - パフォーマンスのテストするときも注意
    Fargateのホスト

    View Slide

  47. - 全部同じECS Serviceですが
    - CPUは3種類
    - ネットワークインターフェースの作り方は2種類
    - 最近はeth0に 169.254.172.2 をつけるようになった
    Fargateのホスト

    View Slide