Slide 1

Slide 1 text

Amazon EKS による スマホゲームの バックエンド運⽤事例 グリー株式会社 インフラストラクチャ部 堀⼝真司 / 加藤健太郎 Elastic Kubernetes Service

Slide 2

Slide 2 text

もくじ –紹介 –EKS 採⽤タイトルまでの経緯 –事前調査や検討したこと –負荷試験やリリース後に発⽣した課題

Slide 3

Slide 3 text

堀⼝ 真司 グリー株式会社 開発本部 インフラストラクチャ部 • 家庭⽤の普通のゲーム → 国内MMORPG などオンラインゲーム開発、 ⽀援、販売 → 主にアーケードゲーム基盤開発 → グリー8年⽬ • クラウドやゲーム系勉強会など多数講演 • 主にインフラの運⽤効率改善(データベース、クラウド系全部) • 社内では AWS 2014〜 GCP 2017〜 • アプリ開発・設計のお⼿伝い

Slide 4

Slide 4 text

チームについて – 運⽤ツール開発、インフラ設計 – ⼦会社もサポート – ゲームが多め – 全体で数⼗のサービス – ⽐較的似たような技術スタック – ゲームは特に統⼀感が強め – ゲームでないものは様々

Slide 5

Slide 5 text

Cloud Backend DB Replica Auto Scale … push VM Image … DB Master Launch Admin Serverless Asset ・Pager ・Chat ・Mail ・Logging ・Monitoring DB Replica … DB Master ・Redis Nodes ・Memcache Nodes App Operator Developer Deploy buil d CDN Load Balancer pager だけでなく 最適化や問題解決の ために⼤量に収集 DB は MySQL を使い ⽔平垂直分割と 複数レプリカ Apache/PHP 負荷に応じて スケーリング CloudFormation などで 多くのマネージドや サーバレスを活⽤ いわゆる LAMP 環境 HTML ではなく JSON

Slide 6

Slide 6 text

Auto Scale … Live Image Launch Security Deploy build App Developer Data Engineer New Image … Old Image … Archive Pull Storage VM イメージと Auto Scale の運⽤ Infra cookbook で管理 ほとんど⾃動 各々の役割を持っ た⼈たちがそれぞ れ独⽴して構成を 修正できる アプリのコードは 別途デプロイ

Slide 7

Slide 7 text

Auto Scale … Live Image Launch Security Deploy build App Developer Data Engineer New Image … Old Image … Archive Pull Storage IaaS にまつわる課題 Infra アプリコードのデプロイと動作確認は アプリ開発者と共同で⾏うため、 全⾃動での更新は難しい 誰かが何か変更を加えるだけで更新が必要。 セキュリティや OS のアップデートも同じ インフラ側が⽤意した環境に合わせた開発しか できない。管理コストを抑えるため、 多くのプロジェクトで似た環境になる ゲームは急激にトラフィックが変わるので Auto Scale は間に合わないことが多い。 事前にイベントスケジュールなどの共有が必要

Slide 8

Slide 8 text

App Docker コンテナ化によるねらい • イメージのフルビルド回避 • 開発環境の多様化 • インフラ部の負担削減 • AWS 以外のクラウド対応 nodejs ruby dns App nodejs ruby dns monitoring VM

Slide 9

Slide 9 text

「2016/07/07 Gaming Tech Night」 より • Amazon ECS • Amazon API Gateway • AWS Lambda • Amazon DynamoDB 当時はまだ AWS Application Load Balancer すらリリースされておらず、 コンテナをシンプルに実⾏できるシス テムだけが存在した。

Slide 10

Slide 10 text

Kubernetes cluster Ingress HTTPS GKE Admin GKE Channel GKE Redis GKE Web GKE Certificate Manager Cloud DNS reality.wrightflyer.net Identity Aware Proxy GKE Jenkins GKE something GKE Comment GKE Comment Monitor GKE Comment Summarizer User Cloud SQL Live Cloud Datastore Amazon CloudFront AWS Lambda App Engine Kubernetes cluster GKE Encoder GKE Distributor Cloud Filestore Ingress HTTPS Kubernetes cluster GKE Metadata GKE Metadata GKE Redis GKE Redis RTMP HLS WS WS • 技術選定が⾃由な新事業案件 • ゲームよりは複雑な要件 • 40 svc 〜 • 300 pods 〜 • 数⼗万 msg/seq 〜 Operator App Media Cloud SQL

Slide 11

Slide 11 text

Amazon Elastic Container Service Amazon Elastic Kubernetes Service Kubernetes Engine Kubernetes Engine 消費者向けサービスで コンテナ投⼊ ⾮ゲーム新事業で Kubernetes 利⽤開始 ゲームでも Kubernetes 運⽤ AWS 環境のゲームでも Kubernetes 運⽤ 2016 2020

Slide 12

Slide 12 text

もくじ ● 紹介 ● EKS 採用タイトルまでの経緯 ● 事前調査や検討したこと ○ Pod ネットワークの IP アドレス割り当ての話 ○ Kubernetes のバージョンアップグレードの話 ● 負荷試験やリリース後に発生した課題

Slide 13

Slide 13 text

自己紹介 ● 名前: 加藤 健太郎 ● 所属: グリー株式会社 開発本部 インフラストラクチャ部 ● 仕事: 主にスマホゲームのインフラ周り全般 ● 経歴: インフラ(7年)、うち Kubernetes (1年くらい)

Slide 14

Slide 14 text

案件概要 ● 2019年秋リリースのスマホゲームのバックエンド ● シンプルな Web API サーバ (PHP / Apache)

Slide 15

Slide 15 text

利用している Kubernetes アドオン ● 外部トラフィックの管理 ○ AWS ALB Ingress Controller ● ノードのオートスケール ○ Cluster Autoscaler

Slide 16

Slide 16 text

Pod ネットワークの IP 割り当てについて

Slide 17

Slide 17 text

EKS における Pod のネットワーク ● Kubernetes はコンテナ間ネット ワークの実現を Container Network Interface (CNI) プラグイ ンに任せている ● EKS では Amazon VPC CNI プラグ インにより、Pod は VPC サブネ ットから IP アドレスが割り当 てられ、VPC ネイティブなネッ トワーキングがサポートされ る ● Pod のネットワークは overlay ではないので、VPC 設計時に考 慮が必要 ポッドネットワーキング(CNI) https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/pod-networking.html

Slide 18

Slide 18 text

Pod の起動時 ● Pod がスケジューリング されると、そのノードの セカンダリ IP アドレスか ら未使用のものが割り当 てられる 参考: Advanced network resource management on Amazon EKS https://d1.awsstatic.com/events/reinvent/2019/REPEAT_1_Advanced_network_resource_management_on_Amaz on_EKS_CON411-R1.pdf

Slide 19

Slide 19 text

ノード起動時 (1) ● Pod 起動時のセットアップ を高速化するため、ノード 起動時に Elastic Network Interface (ENI) にセカンダリ IP アドレスを付けられるだ けアサインされる

Slide 20

Slide 20 text

ノード起動時 (2) ● DaemonSet などが立ち上が り、割り当て済み IP アドレ スが増える ● デフォルトでは、ENI 1個分 の空いている IP アドレスを 確保する設定なので、さら にもう1個の ENI を割り当て 、その ENI にもセカンダリ IP アドレスがアタッチされ る ● 結果として、ENI 2個分の IP アドレスが確保される

Slide 21

Slide 21 text

インスタンスタイプごとに確保される数 ● 起動時に確保される IP アドレスは ENI 2個分で、Pod 数が少ない場合でもサブネットの IP アドレ スは多く消費されることがある インスタンスタイプ 起動時に確保される IP アドレス数 c5.large 20 c5.xlarge c5.2xlarge 30 c5.4xlarge c5.9xlarge 60 参考: インスタンスタイプごとの ENI あたりの IP ア ドレス数 https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/usi ng-eni.html#AvailableIpPerENI インスタンスタイプ 起動時に確保される IP アドレス数 m5.large 20 m5.xlarge m5.2xlarge 30 m5.4xlarge m5.8xlarge 60

Slide 22

Slide 22 text

対策 ● サブネットに十分な CIDR ブロックを割り当てる ○ 本案件では、サブネットあたり /21 の CIDR ブロック(IPアドレス約2000個)を用意したが足りなくなった • このときの規模は 200 Pod、c5.4xlarge で 65 インスタンス程度 ○ なお eksctl で VPC を作る場合、サブネットあたり /19 の CIDR (IPアドレス約8000個) ● 運用開始後に足りなくなった場合 ○ Amazon VPC CNI プラグインの設定変更 ○ 常に確保する未アサインの IP アドレス数を WARM_IP_TARGET 環境変数で設定する ○ Pod の resource request/limit を調整して、Pod 数を減らす ○ VPC にセカンダリの CIDR ブロックを足して、新しいサブネットを作成する • 適切なルートテーブルとセキュリティグループが設定されていれば、既存 EKS クラスタと疎通可

Slide 23

Slide 23 text

補足: 逆に小さいインスタンスはスケジューリングできる Pod 数が少ない ● 小さいインスタンスは、付けられるセカンダリ IP アドレス数が少ないため、それに合 わせてスケジューリングできる最大 Pod 数も小さく設定されている 参考: インスタンスタイプごとの 最大 Pod 数 https://github.com/awslabs/amazon-eks-ami/blob/master/files/eni-max- pods.txt インスタンス タイプ セカンダリ IP アドレスの最大数 スケジューリング できる Pod 数 t3.small 9 11 t3.medium 15 17 t3.large 33 35 ※ +2 なのは、DaemonSet の aws-node と kube-proxy が hostNetwork: true で ノードの Primary IP を利用するため

Slide 24

Slide 24 text

Kubernetes の バージョン アップグレードについて

Slide 25

Slide 25 text

EKS のライフサイクルサポート ● Kubernetes は約3ヶ月おきに新バージョンリリース ● EKS は3つバージョンをサポート、廃止アナウンスから2ヶ月後に廃止 (強制アップグレード) Kubernetes バージョン Kubernetes リリース日 EKS サポート開 始日 EKS での廃止 アナウンス EKS での廃止 1.10 2018/03 2018/06 2019/05 2019/07 1.11 2018/06 2018/12 2019/09 2019/11 1.12 2018/09 2019/03 2020/03 2020/05 1.13 2018/12 2019/06 (2020/06 ?) ? 1.14 2019/03 2019/09 ? ? 1.15 2019/06 2020/03 ? ? 1.16 2019/09 (2020/06 ?) ? ? 参考: Amazon EKS バー ジョンライフサイクルの更 新 https://aws.amazon.com /jp/blogs/news/updates- to-amazon-eks-version- lifecycle/

Slide 26

Slide 26 text

インプレースアップグレードへの不安 ● EKS は公式手順にてインプレースアップグレードをサポート ● EKS により管理されているアドオンも同時にアップグレードすることが推奨されている ● 互換性はあるはずだが、一時的に新旧2つのバージョンが混合する構成となり、サービスを動か したままでのインプレースアップグレードに不安(特に CNI のアップグレード) 参考: Amazon EKS クラスタの Kubernetes バージョンの更新 https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/u pdate-cluster.html

Slide 27

Slide 27 text

クラスタごと入れ替える流れ ● クラスタレベルで Blue/Green デプロイの ようにして、新バージョ ンのクラスタに移行する ● 隣に新規クラスタを 同じ構成で作って動 作検証 ● 問題なければ、本番 アプリからの向き先 も新クラスタにドメ インレベルで切替

Slide 28

Slide 28 text

クラスタごと移行する方法の注意点 ● 既存の VPC に EKS クラス タを立てられるように ● Kubernetes クラスタから 管理している AWS リソー スが競合しないように ● ALB 引き継ぎは難しいの で、DNS レベルでの切替 が必要 ● ステートフルなデータはク ラスタ外へ

Slide 29

Slide 29 text

もくじ ● 紹介 ● EKS 採用タイトルまでの経緯 ● 事前調査や検討したこと ● 負荷試験やリリース後に発生した課題 ○ ローリングアップデートで Bad gateway エラー

Slide 30

Slide 30 text

ローリングアップデートで Bad gateway エラー (1)

Slide 31

Slide 31 text

ALB Ingress Controller の構成 (1) ● target-type: instance モードは、 ターゲットグループに全ワーカ ーノードが登録され、NodePort 経由で Pod に到達 (2 hop)

Slide 32

Slide 32 text

ALB Ingress Controller の構成 (2) ● target-type: ip モードは、ターゲ ットグループには各 Pod の IP アドレスが登録され、ALB から 直接トラフィックが直接到達す る (1 hop) ● 今回は ip モードの構成を採用

Slide 33

Slide 33 text

ローリングアップデートで Bad gateway エラーが多発 ● Bad gateway (HTTP 502) って? ○ ALB から見て、ターゲットが予期しないレスポンスを返したときに発生 ● ターゲットに接続しようとすると TCP RST などが返ってきた ● ターゲットへリクエストを送ろうとした ら、ターゲットから接続が閉じられた ● 長期実行リクエストがあり、ターゲットの 登録解除の遅延時間内に完了しなかった 参考: Application Load Balancer のトラブルシューティング https://docs.aws.amazon.com/ja_jp/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html

Slide 34

Slide 34 text

ローリングアップデートで Bad gateway エラーが多発 ● ローリングアップデート時 に起きているので、ターゲ ットグループから抜ける前 に Pod が終了して、ノード が TCP RST を返している可 能性が高い

Slide 35

Slide 35 text

Pod のサービスアウトは非同期 参考: Kubernetes: 詳解 Pods の終了 https://qiita.com/superbrothers/items/3ac78daba3560ea406b2 ● Pod の終了処理とター ゲットグループから の登録解除は非同期 なので、すぐに Pod が終了すると間に合 わない

Slide 36

Slide 36 text

本案件での対策 ● Pod の終了処理で sleep を行なって、タ ーゲットグループか ら登録解除されるま で十分な時間を待機 する

Slide 37

Slide 37 text

ローリングアップデートで Bad gateway エラー (2)

Slide 38

Slide 38 text

Pod 数が増えるとデプロイ時の Bad gateway エラーが再発 ● 40秒 sleep しても再発

Slide 39

Slide 39 text

なぜ止まっていた? ● ALB Ingress Controller の Reconsile ループでは API コ ールがたくさん! ● 同じ AWS アカウント内に 、複数の EKS クラスタがあ ると、API コールのスロッ トリングを受けやすい

Slide 40

Slide 40 text

スロットリングにより待ち時間が増加 ● AWS API コールは送りすぎるとスロットリングされ、一定時間待ってからリトライする ● 連続してスロットリングすると、リトライの待ち時間は累進的に増える ● ALB Ingress Controller はデフォルトで10回までリトライする設定のため、スロットリングが7回連 続して起こると分単位の待ち時間が発生 例) 連続スロットリングした場合に、Sleep する時間の例 ※ AWS でのエラーの再試行とエクスポネンシャルバックオフ https://docs.aws.amazon.com/ja_jp/general/latest/gr/api-retries.html リトライ回数 1回目 2回目 3回目 4回目 5回目 6回目 7回目 リトライ待ち時間 1秒 1秒 2秒 7秒 15秒 30秒 61秒 累計待ち時間 1秒 2秒 4秒 11秒 26秒 56秒 117秒

Slide 41

Slide 41 text

対策 ● 本案件での対策 ○ API コールのリトライを減らす ■ Pod の終了猶予が40秒なので、10~20秒程度で諦めるように ■ ALB Ingress Controller に引数を追加 ● 例) --aws-max-retries=4 ● +α で効果がありそうな対策 ○ preStop フックでヘルスチェックを失敗させる

Slide 42

Slide 42 text

まとめ ● EKS では Pod ネットワーク用として VPC の IP アドレスが多く消費される • VPC の設計時には、あらかじめ大きいレンジを確保しておくと吉 ● Kubernetes の定期的なアップグレード運用が必要 ● 頻度は多いので、実際に運用を回せるか導入前の検討が重要 ● ダウンタイムのないローリングアップデートのために • Pod の終了時は preStop フックでロードバランサーから抜けるのを待つといった対応が必要 • Pod の多い環境で ALB Ingress Controller を使う場合は、API リトライ回数を減らしておく

Slide 43

Slide 43 text

おわりに ● AWS のコンテナ関連の今後のアップデートは Containers Roadmap で公開されている • https://github.com/aws/containers-roadmap/projects/1 ● 今回ご紹介した課題感も将来的には解消・軽減されそうなので期待 • [EKS]: Next Generation AWS VPC CNI Plugin #398: https://github.com/aws/containers-roadmap/issues/398 • [EKS]: One-click Full Cluster Upgrade #600: https://github.com/aws/containers-roadmap/issues/600