More Related Content Similar to Amazon EKS によるスマホゲームのバックエンド運用事例 (20) Amazon EKS によるスマホゲームのバックエンド運用事例3. 堀口 真司
グリー株式会社 開発本部 インフラストラクチャ部
• 家庭用の普通のゲーム → 国内MMORPG などオンラインゲーム開発、
支援、販売 → 主にアーケードゲーム基盤開発 → グリー8年目
• クラウドやゲーム系勉強会など多数講演
• 主にインフラの運用効率改善(データベース、クラウド系全部)
• 社内では AWS 2014~ GCP 2017~
• アプリ開発・設計のお手伝い
5. 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 NodesApp
Operator
Developer
Deploy
buil
d
CDN
Load
Balancer pager だけでなく
最適化や問題解決の
ために大量に収集
DB は MySQL を使い
水平垂直分割と
複数レプリカApache/PHP
負荷に応じて
スケーリング
CloudFormation などで
多くのマネージドや
サーバレスを活用
いわゆる LAMP 環境
HTML ではなく JSON
7. Auto Scale
…
Live Image
Launch
Security
Deploy
build
App Developer
Data Engineer
New Image
…
Old Image
…
Archive
Pull
Storage
IaaS にまつわる課題
Infra アプリコードのデプロイと動作確認は
アプリ開発者と共同で行うため、
全自動での更新は難しい
誰かが何か変更を加えるだけで更新が必要。
セキュリティや OS のアップデートも同じ
インフラ側が用意した環境に合わせた開発しか
できない。管理コストを抑えるため、
多くのプロジェクトで似た環境になる
ゲームは急激にトラフィックが変わるので
Auto Scale は間に合わないことが多い。
事前にイベントスケジュールなどの共有が必要
9. 「2016/07/07 Gaming Tech
Night」 より
• Amazon ECS
• Amazon API Gateway
• AWS Lambda
• Amazon DynamoDB
当時はまだ AWS Application Load
Balancer すらリリースされておらず、
コンテナをシンプルに実行できるシス
テムだけが存在した。
10. Kubernetes cluster
Ingress
HTTPS
GKE
Admin
GKE
Channel
GKE
RedisGKE
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
11. Amazon Elastic
Container Service
Amazon Elastic
Kubernetes Service
Kubernetes
Engine
Kubernetes
Engine
消費者向けサービスで
コンテナ投入
非ゲーム新事業で
Kubernetes 利用開始
ゲームでも
Kubernetes 運用
AWS 環境のゲームでも
Kubernetes 運用
2016 2020
12. もくじ
紹介
EKS 採用タイトルまでの経緯
事前調査や検討したこと
Pod ネットワークの IP アドレス割り当ての話
Kubernetes のバージョンアップグレードの話
負荷試験やリリース後に発生した課題
13. 自己紹介
名前: 加藤 健太郎
所属: グリー株式会社 開発本部 インフラストラクチャ部
仕事: 主にスマホゲームのインフラ周り全般
経歴: インフラ(7年)、うち Kubernetes (1年くらい)
17. 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
18. 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
19. ノード起動時 (1)
Pod 起動時のセットアップ
を高速化するため、ノード
起動時に Elastic Network
Interface (ENI) にセカンダリ
IP アドレスを付けられるだ
けアサインされる
20. ノード起動時 (2)
DaemonSet などが立ち上が
り、割り当て済み IP アドレ
スが増える
デフォルトでは、ENI 1個分
の空いている IP アドレスを
確保する設定なので、さら
にもう1個の ENI を割り当て
、その ENI にもセカンダリ
IP アドレスがアタッチされ
る
結果として、ENI 2個分の IP
アドレスが確保される
21. インスタンスタイプごとに確保される数
起動時に確保される 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
22. 対策
サブネットに十分な 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 クラスタと疎通可
23. 補足: 逆に小さいインスタンスはスケジューリングできる 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 を利用するため
25. 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/
26. インプレースアップグレードへの不安
EKS は公式手順にてインプレースアップグレードをサポート
EKS により管理されているアドオンも同時にアップグレードすることが推奨されている
互換性はあるはずだが、一時的に新旧2つのバージョンが混合する構成となり、サービスを動か
したままでのインプレースアップグレードに不安(特に CNI のアップグレード)
参考: Amazon EKS クラスタの Kubernetes
バージョンの更新
https://docs.aws.amazon.com/ja_jp/eks/latest/userguide/u
pdate-cluster.html
28. クラスタごと移行する方法の注意点
既存の VPC に EKS クラス
タを立てられるように
Kubernetes クラスタから
管理している AWS リソー
スが競合しないように
ALB 引き継ぎは難しいの
で、DNS レベルでの切替
が必要
ステートフルなデータはク
ラスタ外へ
29. もくじ
紹介
EKS 採用タイトルまでの経緯
事前調査や検討したこと
負荷試験やリリース後に発生した課題
ローリングアップデートで Bad gateway エラー
31. ALB Ingress Controller の構成 (1)
target-type: instance モードは、
ターゲットグループに全ワーカ
ーノードが登録され、NodePort
経由で Pod に到達 (2 hop)
32. ALB Ingress Controller の構成 (2)
target-type: ip モードは、ターゲ
ットグループには各 Pod の IP
アドレスが登録され、ALB から
直接トラフィックが直接到達す
る (1 hop)
今回は ip モードの構成を採用
33. ローリングアップデートで 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
35. Pod のサービスアウトは非同期
参考: Kubernetes: 詳解 Pods の終了
https://qiita.com/superbrothers/items/3ac78daba3560ea406b2
Pod の終了処理とター
ゲットグループから
の登録解除は非同期
なので、すぐに Pod
が終了すると間に合
わない
39. なぜ止まっていた?
ALB Ingress Controller の
Reconsile ループでは API コ
ールがたくさん!
同じ AWS アカウント内に
、複数の EKS クラスタがあ
ると、API コールのスロッ
トリングを受けやすい
40. スロットリングにより待ち時間が増加
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秒
41. 対策
本案件での対策
API コールのリトライを減らす
Pod の終了猶予が40秒なので、10~20秒程度で諦めるように
ALB Ingress Controller に引数を追加
例) --aws-max-retries=4
+α で効果がありそうな対策
preStop フックでヘルスチェックを失敗させる
42. まとめ
EKS では Pod ネットワーク用として VPC の IP アドレスが多く消費される
VPC の設計時には、あらかじめ大きいレンジを確保しておくと吉
Kubernetes の定期的なアップグレード運用が必要
頻度は多いので、実際に運用を回せるか導入前の検討が重要
● ダウンタイムのないローリングアップデートのために
Pod の終了時は preStop フックでロードバランサーから抜けるのを待つといった対応が必要
Pod の多い環境で ALB Ingress Controller を使う場合は、API リトライ回数を減らしておく
43. おわりに
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
Editor's Notes ここからは事例の話に入っていきますが、
やや deep dive 感のある形でトピックをお話していきます。
まず事前の検討が必要だったことの中から、
ネットワークの話と Kubernetes のアップグレードの話についてお話していきます。 その前に、簡単に自己紹介させていただきます。
グリー株式会社のインフラストラクチャ部の加藤と申します。
7年前に新卒でグリーに入社しまして、ずっとインフラ周りのお仕事をしております。
Kubernetes の経験としては1年程度です。 今回 EKS を導入した案件について、簡単にご紹介させていただくと、
昨年秋にリリースしたスマホゲームで、タイトル名が他社配信のため非公開なのですが、
これのバックエンド部分を EKS を使っており、
Kubernetes の上に乗せているアプリケーションは、シンプルな Web API サーバです。
中身は PHP と Apache です。 本案件では、外部からのトラフィック、Ingress の管理を AWS ALB Ingress Controller を使い、
ノードのオートスケールでは Cluster Autoscaler を使っています。 最初のトピックはネットワークについてです。
ネットワークの部分は、運用を開始してから変更するのがなかなか大変なところなので、
EKS を利用するにあたって、VPC の設計時に気をつけておく必要がある部分についてお話していきます。 Kubernetes はコンテナ間ネットワークの実現をコンテナネットワークインターフェイス CNI プラグイン に任せています。
EKS では Amazon VPC CNI プラグインによって、Pod は VPC サブネットから、 IPアドレスが割り当てられて、VPC ネイティブなネットワークがサポートされています。
Pod のネットワークは オーバーレイ ネットワーク ではないので、VPC 設計時には Pod のネットワークについても考慮が必要となります。 Pod の起動時に、IP アドレスがどのように割り当てられるのか、について説明していきます。
Pod がノードにスケジューリングされ、そのノードで Pod が立ち上がると、VPC CNI プラグインに、 Pod のネットワークのセットアップが依頼されます。
その際、VPC CNI プラグインは、ノードのセカンダリ IP アドレスから、使われていないものを選んで、Pod の IP アドレスとして割り当てます。
これにより、Pod は VPC 内で通信できるようになります。 VPC の IP アドレスというのは、 Kubernetes の外にあるリソースで、AWS の API を経由して管理されるものです。
そのため、Pod の立ち上げ時に、いちいち AWS の API を経由しないように、あらかじめノード起動時にセカンダリ IPアドレスとして、まとまった数を持たせておくという方法が取られています。
このとき、VPC CNI プラグインのデフォルトでは、そのノードの Elastic Network Interface (ENI)に、この図で言うところの eth0 に、付けられるだけ IP を付けるという挙動をします。 このとき、VPC CNI のデフォルトでは、Pod に割り当てられていない IP アドレスを ENI 1個分確保するという設定になっています。
DaemonSet などにより Pod が立ち上がると、IP アドレスが Pod にアサインされていき、
ENI 1個分の IP アドレスを確保するために、新しい ENI、この図の eth1 がノードに割り当てられます。
このとき、新しい ENI にも セカンダリ IP アドレスが付けられるだけ付けられます。
このような動きとなるため、結果として、ノード起動時は、ENI 2個分の IP アドレスが確保されるということになります。 ここで気になるのが実際のところ、ノードごとにどのくらいの IPアドレスが事前に確保されるかというところだと思います。
これはノードのインスタンスタイプによって異なり、
EC2 のサービス制限により、インスタンスタイプごとに、アタッチできる ENI の数と、 1つの ENI に付けられる IP アドレスの数が変わってきます。
本番用のワーカーノードとして多く使われるであろう、c5 と m5 ファミリーのインスタンスでは、1インスタンスごとに最低でもこの表の数だけ確保されることになります。
例えば、c5.4xlarge だと 1インスタンスあたり 60 個ということになるので、
例えば 10インスタンス立てる場合は 600個の IPアドレスが必要ということになります。 そのため、最もシンプルな対策は最初からサブネットには十分な CIDR ブロックを割り当てておくということです。
本案件では、サブネットあたり /21 の CIDR ブロックを用意していたのですが、ピーク時は足りなくなったということがありました。
ちなみに、eksctl で VPC ごと作る場合はサブネットあたり /19 で IP が約 8000 個あるので、このぐらいあればたいていは十分なのではないかと思います。
そして、運用開始してから足りないということが発覚した場合の、対応方法としては、簡単なのは VPC CNI プラグインの設定変更です。
VPC CNI プラグインには、ウォームアイピーターゲット という環境変数で、Pod に割り当てられていない IP アドレスとして、確保する数を指定できるので、
これを小さい値に指定することで、ノードごとの IP の消費を抑えられます。 ここまでは IP アドレスが多く使われるという話をしましたが、
逆に t3 のような小さいインスタンスタイプだとノードに付けられる IP が少ないため、スケジューリングできる Pod が低く制限されています。
例えば、t3.small だとスケジューリングできる Pod は 11個までです。
小さいインスタンスを使うときはこの点も注意が必要です。
次のトピックは、Kubernetes のアップグレードについてです。
前回のミートアップがクラスタアップグレードについてだったので、このトピックはカットしようか迷ったのですが、
アップグレードの話は重要なので、この発表では軽くですがご紹介させていただきます。 Kubernetes は3ヶ月毎に新バージョンがリリースされます。
EKS はそれに追随するため、3つのバージョンのサポートを基本とし、新しいバージョンを サポートしたら、古いバージョンを廃止していくというプロセスを辿ります。
アップストリームの Kubernetes が3ヶ月ごとのリリースなので、EKS が同じスピードで追随するのであれば、約9ヶ月でそのバージョンが廃止されるということになります。
そのため、3ヶ月から9ヶ月といった周期で、
定期的に新しいバージョンに移行するといった運用が必要になってきます。 具体的なバージョンアップ手順は、AWS の公式マニュアルに記載があります。公式ではインプレースアップグレードをサポートしていて、アップグレードの際は、EKS により管理されているアドオンのバージョンも上げることが推奨されています。インプレースアップグレードでは、一時的に新旧2つのバージョンが混在する構成となってしまうので、特に CNI のアップグレードをアプリケーションサービスを動かしたまま行うというのはまだ不安がありました。 そこで本案件では、クラスタレベルで Blue/Green デプロイのようにして、クラスタを入れ替えるという方法を取ることにしました。
簡単な流れとしては、同じ VPC 内に、バージョンだけが異なる、同じ構成の EKS クラスタを作って、
アプリケーションの動作確認などを行い、問題なければ、本番アプリからのトラフィックをドメインレベルで切り替えるといった流れです。 この手法の注意点としては、
まず、EKS クラスタと VPC は構成管理を分けて考えておき、既存の VPC内にクラスタを立てられるようにしておく必要があります。
また、Kubernetes のクラスタから管理している AWS リソース、この図だと Auto Scaling グループや Application Load Balancer (ALB) の部分については、
同じ AWS アカウント内にクラスタを立てたとき、別のクラスタが管理する AWS リソースを誤って操作してしまわないかという点を検討する必要があります。
また、ALB Ingress Controller に関しては、 既存の ALB を引き継ぐというのはできないので、クラスタ移行の際は DNS レベルで切り替える、といった方法を取っています。
また、無停止で移行する場合は、ステートフルなデータはクラスタ内に持たず、クラスタ外に出しておくなどが前提となります。
今回は時間の都合で、アップグレードについては軽くだけご紹介しました。
より詳細な情報は、前回のミートアップの資料や動画が非常に参考になりますので、そちらをご参照ください。 ここまで、事前の検討が必要だったネットワークとアップグレードについてご紹介してきました。
ここからは、本案件においてリリース時に発生した問題の中から、
ローリングアップデートでエラーが出てしまうという問題について、
深掘るかたちでご紹介していきます。 問題の説明の前に、ALB Ingress Controller の構成についてご説明します。
ALB Ingress Controller は2つの構成を取ることができます。
1つ目が ターゲットタイプ インスタンス モードというもので、これは ALB のターゲットグループに全ワーカーノードが登録され、ALB からのトラフィックは NodePort 経由で Pod に届くという構成です。 もう1つは、ターゲットタイプ IP モードというもので、ALB のターゲットグループには各 Pod の IPアドレスが登録され、ALB からのトラフィックは直接 Pod に届くという構成です。
本案件では、この IP モードの構成を採用しています。 ここで問題に戻りますと、発生した問題はローリングアップデートを行うと、HTTP の Bad gateway エラーが多発したというものでした。
この Bad gateway エラーというのは、ALB から見て、ターゲット、この構成では Pod が、予期しないレスポンスを返したときに発生します。
よくあるケースとしては3つあり、1つ目はALB がターゲットに接続しようとするとポートが閉じられていた場合です。
これは既に Pod が終了しているにも関わらず、ALB がリクエストを送った場合などに発生します。
2つ目は HTTP のキープアライブを利用している場合で、キープアライブタイムアウトの設定が ALB側と Pod 側で異なるときに起きます。
3つ目は、ALB から Pod を削除した際に、実行時間の長いリクエストを処理していた場合です。 今回のケースでは、
ローリングアップデート時に必ず起きていて、長期実行リクエストはなかったので、
どうやらターゲットグループから Pod が削除される前に、 Pod が終了している可能性が高いということが分かりました。 この問題は有名な話なので、ご存知の方も多いと思いますが、
Pod の終了処理と Service のエンドポイントから Pod が削除される処理は、それぞれ非同期で行われるので、先に Pod が終了してしまうということが起きるようです。
この図では、4つのコンポーネントの内、一番上が Pod の終了処理、残りの3つが ALB から Pod を削除する処理を表しています。
Pod 自体の終了処理は、 preStop フックがあればそれを実行し、その後 STOPSIGNAL を送って、各コンテナが終了するという流れです。
一方で、ALB から Pod を削除する処理は、まず Kubernetes のエンドポイントコントローラーが Pod の削除開始を検知すると、エンドポイントリソースから Pod が削除します。
次に ALB Ingress Controller はエンドポイントの変更を検知すると、ターゲットグループから Pod を登録解除します。
通常はこのタイミングで ALB からのトラフィックが Pod に流れなくなります。
各処理は非同期なので、ALB から削除される前に Pod が終了してしまえば、そのときに Pod にルーティングされていたリクエストは Bad gateway のエラーになってしまうということでした。 そこで本案件では、Pod の終了処理を大きく延ばすことで対応しました。
具体的には、preStop フックの中で 40秒 sleep しています。
これにより、Pod が ALB から抜けるまで、十分な時間を確保することができるようになり、
ローリングアップデート時に必ず起きていた Bad gateway のエラーは一旦解消しました。
が、ここで一旦は解決したかのように見えたのですが、本番運用を開始して,、大きく Pod 数が増えたとき、ローリングアップデートでまた同じエラーが再発しました。 問題が起きたときに ALB Ingress Controller のログなどを見ますと、どうもローリングアップデートの最中、1,2分程度 ALB Ingress Controller が止まっていたようでした。
Pod 側で 40秒 sleep したとしても、ALB Ingress Controller が、
分単位で遅れてしまうならば間に合わないので、原因を調べる必要がありました。 先に原因としては、API のスロットリングによるものでした。ALB Ingress Controller は ALB の生成から管理まで行うので、図でごちゃごちゃ書いているように、数多く Describe系の API コールによって、
正しい状態になっているか、Reconsile ループで確認しています。
ローリングアップデート時は、Pod の増減により エンドポイント リソースの変更が行われるので、そのたびに、ALB Ingress Controller の Reconsile ループが走り、どうしても API コールが多くなってしまい、スロットリングされやすいという問題があるようです。
この問題は特に、同じ AWS アカウント内に、複数の EKS クラスタがある場合に起きやすいようです。 AWS の API コールは送りすぎるとスロットリングされますが、その際は一定時間待ってからリトライします。
リトライしてもまたスロットリングすると、次のリトライまでの待ち時間は、累進的に増やしていくという処理が、 AWS API の クライアント SDK に、組み込まれています。
現在の ALB Ingress Controller はデフォルトで10回までリトライするという設定のため、スロットリングが連続で7回連続して起きると、分単位の待ち時間が発生します。
これにより Pod を ALB から削除するという処理が遅れる原因となっておりました。
対策としては、ALB Ingress Controller に API コールを何回までリトライするかという設定があるので、それを減らすことで抑制効果があります。
本案件では20秒程度で諦めるように、4回までリトライする設定にしています。
暫定対策ではありますが、これで一旦収束しました。
また、一般的な対策としては、Pod の preStop フックで、
ReadinessProbeやターゲットグループからのヘルスチェックを失敗させるとより安全になるようです。 簡単にですが、まとめに移ります。
導入前に検討が必要だったこととして、
EKS では、Pod ネットワーク用として VPC の IP アドレスが多く使われることについて説明しました。
そのため、VPC の設計時には、あらかじめ大きい IP レンジを確保しておけると安心できます。
また、Kubernetes はリリースの周期が短いので、定期的なバージョンアップグレードの運用を回せるか、事前に検討しておくことが重要です。
クラスタごと移行する方法を取る場合、クラスタを入れ替えやすい構成を取るなどが必要になりますので、導入前に検討しておくことをおすすめします。
また、ローリングアップデートをダウンタイムなく実行できるようにするために、
Pod の終了時は preStop フックなどでロードバランサーから抜けるのを待つといった対応が必要という話をしました。
また、ある程度 Pod が多い環境では、 ALB Ingress Controller の API リトライ回数を減らしておくと安定します。 最後になりますが、
AWS のコンテナ系サービスの、今後のアップデートについては、ロードマップが公開されています。
今回ご紹介したネットワークやアップグレードに関する課題も、将来的には解消・軽減されそうなアップデートが予定されていますので、ぜひこちらも合わせてご参照ください。
今回の発表は以上となります。ご静聴ありがとうございました。