Upgrade to Pro — share decks privately, control downloads, hide ads and more …

クラウドネイティブなバッチ基盤の品質を再定義し、治安を取り戻した話

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

 クラウドネイティブなバッチ基盤の品質を再定義し、治安を取り戻した話

Avatar for Hikaru Sasamoto

Hikaru Sasamoto

December 14, 2023
Tweet

More Decks by Hikaru Sasamoto

Other Decks in Technology

Transcript

  1. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    クラウドネイティブな バッチ基盤の品質を再定義し、 治安を取り戻した話 SRELOUNGE #16 2023年12月14日
  2. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    About Me Hikaru Sasamoto (@hisamouna34) - 株式会社エウレカ - 2022年に入社 - SRE & Data Management チームに所属 - 最近は dbt と格闘する日々
  3. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    Agenda • 会社説明 • 本セッション対象の方/について/話さないこと • ペアーズにおけるバッチ運用 • バッチ基盤の課題 • 解決編 ◦ バッチの品質を再定義 ◦ istio-proxy の起動失敗の解消 ◦ 異常終了している処理の修正 ◦ ownership, severity の定義 • まとめ
  4. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    本セッションの対象の方 • バッチ基盤を運用している方 (特に AWS) • バッチ基盤を kubernetes 環境で構築している または 運用に興味がある方 • 異常終了している処理が放置されている現状に困っている方 • 処理のオーナーシップがふわふわしている状態に苦労している方
  5. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    本セッションについて SRE チームとして、システムの信頼性向上に日々努めている。 ペアーズの Web アプリケーションに関しては、適切な SLO を設定し、信頼性を損なうことなく運用できている。 しかし、バッチ処理に関しては、 SRE のプラクティスが実践できていない状態だった。 このセッションはその状態からいかに信頼性を向上させていったかの取り組みを話すものです。
  6. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    本セッションで話さないこと • バッチ基盤の詳細 ◦ こちらは JAWS FESTA 2023 で話しているのでご参照ください
  7. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    ペアーズにおけるバッチ運用 • バッチで行っていること ◦ 例) プッシュ通知、審査処理、Elasticsearch のドキュメント更新 など • バッチの種類: 332 ◦ ペアーズは3カ国(日本/台湾/韓国) 展開していて、それぞれのリージョンごとにバッチがあるので、実質 ×3 • 基盤の構築・監視は SRE チームが行っている • 新規バッチ作成は開発チームが行う
  8. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチ基盤のアーキテクチャ プラットフォーム: EKS on EC2 / CD: Argo CD バッチは3種類に分けられる batch • 実行タイミング : cronによる定期スケジュール • CronJob リソースで運用 batch-iterator • 実行タイミング: ループ処理 • Deployment リソースで運用 batch-worker • 実行タイミング : SQS のキューイング • SQS の subscribe と pod の作成に KEDA を利用
  9. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチ運用の課題 • 終了ステータスがめちゃくちゃ ◦ なんか分からないけど異常終了しているバッチがある ◦ 偽陽性が出てしまうので、Podの終了ステータスでのアラートを作れない ◦ 問い合わせがあって初めて問題に気づくことも • クリティカルでないエラーログが出力されがち • バッチが失敗した時の緊急度が分からない • 運用面でオーナーチームがオーナーシップを発揮できていない ◦ 問題があった時に誰が取り組むのかが宙ぶらりん
  10. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    EKSへの移行が完了し、やるなら今しかない • 前々から、開発チームも SRE チームも現状が健全ではないと理解はしていた • 移行を終えて、ある程度仕様が分かっている今がチャンス まずは、あるべき姿から考える
  11. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    解決編 • バッチ処理を見直す ◦ バッチ処理で大事なこと • バッチの品質を再定義 ◦ 対応する必要があるアイテムの洗い出し • 異常終了している処理の修正 ◦ サイドカーコンテナの起動が不安定なのを修正 ◦ 正常終了時は、exit 0で終わるようにコード修正 • 平定 • 品質の向上を目指す ◦ バッチの重要度を3段階で定義 ◦ アラート作成に動き出す ◦ モニタリング環境の整備
  12. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチ処理を見直す • 多くのブログを参考にさせていただきました ◦ バッチ処理プラクティス (https://www.yamarkz.com/blog/implementation-practices-for-batch-processing) ◦ バッチ処理の採用と設計を考えてみよう (https://engineering.mercari.com/blog/entry/2019-02-27-112650/) ◦ バッチ処理実装時に考慮すべき事項 (https://engineering.mercari.com/blog/entry/20220422-89e520371b/) • チームで輪読
  13. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチ処理で大事なこと • バッチ処理で大事なこと ◦ 冪等性 ▪ つまり、リトライ可能である ◦ 可観測性 ▪ 処理の進行・完了状態を把握できる。メトリクス・ログ・トレースの3方向で確認できると良い ◦ 整合性 ▪ 多重起動可能かは分かっていて欲しい ◦ 期待されるスループット・許容される処理時間が分かっていること など...
  14. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチの品質を再定義 • 開発チームと SRE チームで議論して、あるべき姿を再定義
  15. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    対応する必要があるアイテムの洗い出し • 現実的に、今クォーターでできることを整理 ◦ まずは、工数短くて効果が出るところから • アイテム ◦ 正常終了時は、exit 0で終わるようにコード修正 (無駄に異常終了しているバッチの修正) ◦ モニタリング環境の拡充 ◦ 異常終了時は、アラートを発火するように整備 ◦ アラート発火時にオーナシップを発揮(強制)できるような仕組みづくり • 兎にも角にも、異常終了を直さないことには始まらない
  16. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    サイドカーコンテナの起動が不安定なのを修正 • インフラ起因で異常終了しているケースもあった • バッチ Pod には バッチコンテナと別に istio-proxy が動いている • istio-proxy の起動に失敗してバッチ処理が異常終了するケースが多々あった • 対応したこと ◦ 適切なリソース割り当て ( cpu が不足していると起動速度に影響する) ◦ istio-proxy -> バッチコンテナの起動順になるように設定 (holdApplicationUntilProxyStarts: true) ▪ https://istio.io/latest/docs/reference/config/istio.mesh.v1alpha1/#ProxyConfig ◦ istio-proxy 起動に60秒以上かかるケースがちょくちょくあり(根本的な原因発覚には至っていない)、istio-proxy の起動完了を待たずにバッチコンテナが起動してしまうので、バッチコンテナの起動スクリプトでistio-proxy ( http://localhost:15021/healthz/ready) へリクエストし、正常なレスポンスが返ってくるまで待機
  17. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    正常終了時は、exit 0で終わるようにコード修正 • 直近1ヶ月で異常終了しているまたは エラーログが出力されていたバッチを洗い出し (約40バッチ) • なぜエラーが起こっていたかを調査し対応方針を検討し、愚直にエラーを修正 • エラー事例 ◦ 外部 API へのリクエストが接続エラーやタイムアウト ▪ リトライで解決しそうなエラーの場合はリトライするように修正 ◦ デッドロック発生 ▪ 異なるバッチで処理のバッティングがあったので修正 ◦ ログレベルが不適切 ▪ ログレベルの調整
  18. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    平定後も品質を維持するために • オーナーシップの発揮ができるような仕組みづくり • 目指すべき姿 ◦ アラートが発火した時に、 ▪ バッチのオーナーチームが検知してトリアージできる状態 ▪ 対象バッチの重要度が分かる。即時対応しないといけないか?後からの対応でも問題ないか?
  19. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチの重要度を3段階で定義 • critical ◦ アラート発生時の対応: 当日即時対応 ◦ アラートチャンネル: critical channel • high ◦ アラート発生時の対応: 1週間以内に対応 ◦ アラートチャンネル: critical channel だが、頻繁に通知されるようであれば一時的に mute にする • medium ◦ アラート発生時の対応: 手が空いた時に対応。頻繁に異常終了しているのを見つけたら、オーナーチームに連絡 ◦ アラートチャンネル: warning channel
  20. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    オーナー、重要度をどこにいつ書くか • バッチの k8s マニフェストは CUE で書いている。 #CUEでキュッと • 開発者が書きやすいように、記載必要な設定のみを1ファイルにまとめている • 開発者がバッチ作成時に、同ファイルにオーナー、重要度の記載をするようにした ◦ owner, severity は 記載を required にして欠損を許容しない // バッチ処理 { name: "batch-sample", owner: "owner-team", commands: "batch_sample", severity: "high" },
  21. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    Kubernetes 内でどうやって表現されるか • owner, severity は Pod の annotations と containers.env にレンダリングされる annotations: owner: owner-team severity: high containers: - name: batch-sample env: - name: BATCH_OWNER value: owner-team - name: BATCH_SEVERITY value: high metadata: annotations: { "owner": val.owner "severity": val.severity } env: [ { name: "BATCH_OWNER" value: val.owner }, { name: "BATCH_SEVERITY" value: val.severity }, ] CUE YAML ( k8s manifest)
  22. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    アラート作成に動き出す • はじめは、Pod の異常終了をアラート発火の条件にしようとした • アラート発火時のトリアージはオーナーチーム(≒バッチを開発したチーム)だが、 • インフラ起因の異常終了があった場合、インフラの面倒を見ている SRE チームが取るべきと判断 • Pod の異常終了だとアプリ起因かインフラ起因かが分からない • 別の指標をアラートのトリガーにすることに
  23. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    バッチ処理内でエラー情報を出す • 処理の中で異常終了を示し、それをモニタリング環境でピックアップできれば良さそう • 元々、Datadog APM の Traces に処理が異常だったことを示す情報が入っていたので活用することに ◦ (dd-trace-go (https://github.com/DataDog/dd-trace-go) を利用してます) ◦ 前述の通り環境変数に仕込んだ severity, owner をタグとしてメタ情報をセット span := tracer.StartSpan("batch.task", tracer.ResourceName(opName)) span.SetTag("owner", os.Getenv("BATCH_OWNER")) span.SetTag("severity", os.Getenv("BATCH_SEVERITY"))
  24. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    Terraform で アラート作成 query = "trace-analytics(\"@severity:critical\") > 0 • Datadog Monitor を利用 • severity ごとにクエリを作る • アラートのメッセージにオーナーチームとメンションが飛ぶように slack_group_id をセット バッチのオーナーチーム (<!subteam^{{span.attributes.slack_group_id}}|@{{span.attributes.owner}}>) は対応フローに沿って対応してください
  25. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    Datadog Dashboard でも見れるように • Datadog Agent の環境変数 DD_KUBERNETES_POD_ANNOTATIONS_AS_TAGS を設定することで、Pod の Annotation 情報を Datadog Metrics の Tag として利用できる env: - name: DD_KUBERNETES_POD_ANNOTATIONS_AS_TAGS value: '{"owner": "owner", "severity": "severity"}'
  26. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    モニタリング環境の整備 • バッチ基盤で見るべき観点 ◦ 異常終了しているかどうか ◦ 処理内の異常終了と Pod の異常終了の2観点のメトリクスを出すことで事象の切り分けがしやすい • CPU・メモリ使用率 ◦ 大量のバッチの使用率を1 Widget で出すと値が潰れてしまう ◦ 下限値(例えば、CPU 使用率85%)以上のみ表示するようにする • Node ごとの 起動 Pods 数 ◦ 偏りがないか。遊びが生まれている Node がないか
  27. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    アラートを整備してから • はじめは、アラート見てください活動をしていたが、 • 次第にオーナーチームが自発的にアラートのトリアージしてくれるように • バッチの世界に平和が訪れた
  28. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    これからの話 • テストの拡充 ◦ 特定条件でないと処理が行われないケースの場合、開発環境での検証が難しい • 実行時間の監視 ◦ レイテンシ SLO のような立て付けにしたい • ドキュメントの整備 ◦ バッチごとに、アラートが鳴った時の対応フローが明記されていると対応がしやすい
  29. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    今後、Kubernetes に入るアップデートの活用 • sidecar containers ◦ https://kubernetes.io/docs/concepts/workloads/pods/init-containers/#api-for-sidecar-containers • Pod Failure Policy ◦ https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-failure-policy • Pod Replacement Policy ◦ https://kubernetes.io/docs/concepts/workloads/controllers/job/#pod-replacement-policy
  30. CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy

    We’re hiring! ペアーズではエンジニアを積極採用中!
 カジュアル面談もお待ちしております!
 (X: @hisamouna34)