エムスリーテックブログ

エムスリー(m3)のエンジニア・開発メンバーによる技術ブログです

AIチームのGameDayでNode Poolを吹き飛ばした話

こんにちは、AI・機械学習チーム(AIチーム)の農見(@rookzeno)です。みなさんAWS GameDayというものをご存知でしょうか。AWS GameDayとはゲーム化されたリスクのない環境で現実世界の問題を解決するためのスキルを学ぶ演習です。

今回はそれをAIチーム内でやってみようということで、開発環境でわざと障害を起こして、それを担当者以外が解決できるかというGameDayをやりました。そして開発環境のGoogle Kubernetes Engine(GKE)のNode Pool*1を吹き飛ばしました😇

Node Poolが吹き飛ぶと、APIやバッチが全て落ちるのでおしまいです。

なぜGameDayを行ったのか

AIチームではマイクロサービスを少人数で沢山作るという方針でプロダクトを作っており*2、レビューはしてるものの担当プロダクト以外の障害対応は少し手間がかかるというのが現状です。

そこで担当者が休みの時に障害が起こるとヤバいプロダクトで擬似的な障害対応をして、担当プロダクト以外でも障害対応力を上げていこうということでGameDayを行いました。

GameDayの目的

実際にありそうな障害を再現し、担当者以外が対応することで次の効果を期待しました。

  • チーム全体のシステムの理解度を上げる
  • 落ちたら困るAPIの復旧などの暗黙知をチームに広げる

GameDayで盛り上がった後の飲み会

GameDayの流れ

  1. まずは障害を起こすプロダクトを何にするかを決めます。担当者が休みの時に障害が起こるとヤバいプロダクトを優先して選択しました
  2. プロダクトが決まったら、障害を起こす側(攻撃者)と障害対応する側(防衛者)に分かれます。攻撃者はプロダクトに詳しい担当者にやってもらいました
  3. GameDay当日、攻撃者は障害を起こし、防衛者は障害対応するバトルが始まる

攻撃者と防衛者のペアを3チーム作ってバトルしたのですが、今回は僕が参加したGoogle Cloudに関するバトルの顛末をメインで紹介します。

CronJobが動いてない事件

障害:CronJobが動いてないという監視アラートが大量に鳴る

ここではこの障害に対してやったことと想定解の2つを書いていきます。

やったこと

  1. 影響が出そうな他部署に現状の報告(忘れがち) ◯
  2. なぜ動いてないのか探るためCronJobの詳細を見に行く ◯
  3. Pod errors: Unschedulableで動いてないと気付く ◯
  4. GKEのクラスタのNode Poolの上限が普段より少ないものがあることに気付く ◯
  5. いつも通りにするためローカルでterraform applyする △
  6. 全Node Pool吹き飛ばす😇 ×

途中までいい感じだったのにどうして、、、

どうしてこうなってしまったか

最新のmasterのTerraformを使わなかったから。

# node_pool must be replaced
+ enabled = true # forces replacement
Plan: 50 to add, 0 to change, 50 to destroy.

古いmasterを使ってしまったため上記のような沢山の警告が出てる中applyしてしまい全Node Poolを吹き飛ばしました。弁明しておくと、普段はCIでterraform applyしているので、こういうことは起きないです。前述のように普段はCI/CDで安心安全に動かしていたのですが、障害対応というなれない中焦っていたこともあり、ローカルでapplyする際にremoteのmasterをpullすることを失念して事故を起こしてしまいました。焦りは事故を生むので注意する必要があります。皆さんは安易なdestoryはやめましょう。

ちなみにNode Poolを再作成してる間、当然他チームのAPIもアクセスできなくなりました。GameDayでは攻撃者以外からも障害を起こされることがあるので注意しましょう。まあでも、意外とNode Poolを全部再作成しても復旧は早かったです。良かった。古いmasterから最新のmasterにも直しました。

想定解

【シナリオ】 急速に増えるJobにNode Poolの設定値が耐えられず、Nodeに乗り切らないJobが大量発生し始めた

【攻撃者の実際の設定】 GKEのクラスタの1つのNode Poolの上限を減らした

AIチームでは2021年から2024年でCronJob数が88から300に増えています。このペースで加速していくと、近い将来Node Poolの上限が足りなくなるということが想定されるためこの課題にしました。

1. コミュニケーションが最初

監視アラートが鳴っているものを見て、コミュニケーションを取るべきステークホルダーを確認する。ステークホルダーに現状と今後の対応をきちんと説明する。

2. Podを調べる
kubectl get po -A --sort-by=.metadata.creationTimestamp

で、Pod一覧を見ることができる。その中で動いてなさそうなものを1個ピックアップして調べる。

kubectl get po -o yaml test

そうするとUnschedulableでNodeが変なことが分かる。さらにNodeSelectorを見ると、どのNodeが選ばれてるかがわかる。

3. Node Poolの上限を増やす

Terraformか、Google CloudのコンソールポチポチでNode Poolの上限を増やすことができる。しかし今回はTerraformだけではなく、緊急時はポチポチの対応も大事ということで以下の設定でTerraformでは出来ないようにしていた。

  lifecycle {
    ignore_changes = [autoscaling[0].max_node_count]
  }

しかし、防衛側はforces replacementしたので関係なく直ってしまったのだった。

他チームの課題についても軽く

問い合わせ「届いてないメールがあるけど大丈夫?」

送信者リストのCSVファイルを用意してもらって、それに送信するシステムがあるのですが、そのCSVファイルが壊れていたという話です。稀によくあるので注意しなければなりません。

ogakl@example.com ×
ogaki@example.com ◯

iとlが違います。ただ、これ安易に直してバッチを再実行すると送った人に何回も送ってしまうという罠がありました。このチームは同じ人に3回送ってしまい、GameDay用の仮想ユーザから「三回も来たんだが」と怒られてました。

成果報告会

最後には各チームどのように課題をこなしたかと想定解の発表会を行いました。他チームもちゃんとミスはしているようなので安心しました。この発表会でミスしやすいところや関わりの浅いプロダクトの知見をチーム内で共有できたので良かったです。

感想

Node Poolを吹き飛ばしてしまう大失敗をしてしまいましたが、普段触ってない部分に詳しくなれるのでGameDayは有意義でした。企業内GameDayは楽しいのでみんなやろう!

We’re hiring !

AI・機械学習チームではイベント好きなエンジニアを募集しています。少しでも興味がある方は、次のURLからカジュアル面談をご応募ください!

エンジニア採用ページ

jobs.m3.com

AI・機械学習チーム紹介資料

speakerdeck.com

*1:Node PoolとはGoogle Kubernetes Engine(GKE)のクラスタ内において、Nodeをグルーピングして管理するための仕組みです。AIチームではstandard-node-poolやhighmem-node-poolなどを用意しています。

*2:属人性が上がるが、開発効率が上がる方法を選んでいる