AWSのEKSでターゲットグループのスロースタート期間を設定する
EKS で pod の起動を遅らせる方法はいくつかあります。
Kubernetes の readinessProbe などで、pod 起動時のヘルスチェックのタイミングを調整をするのも方法の 1 つですよね。
しかし今回は、pod が Ready になった際にいきなりフルフルでアクセスを送り込むのではなく、若干でもいいので緩やかにしたいという状況に遭遇しました。
istio などを使うことも考えられますが、新しく導入せずに対応を検討してみましたので紹介します。
podのリクエスト調整の調査
まず、pod の前段にいるところから調べていきましょう。
pod に近い存在で考えてみると、Kubernetes の service や node, hpa の設定が考えられます。
behavior の scaleUp で pod 自体のスケールインの制御を考えてもいいですが、複雑になりそうで大変です。
その上位となると、ロードバランサ(ALB)やノードとの間に入るターゲットグループ。
マネージドの部分に設定があると楽なので、先に ALB やターゲットグループを調べたところ、ターゲットグループの属性に「スロースタート期間」の設定がありました。
スロースタート期間
最初はロードバランシングの種類を変更したらいけるんじゃないかと期待していたのですが、このスロースタート期間がまさに理想的なものになりそうです。
デフォルトのラウンドロビンでしか利用できないので、以下の 2 つは検討から外れます。
・最小の未処理のリクエスト
・加重ランダム
スロースタート期間については、AWS のドキュメントで詳しく説明されています。
デフォルトでは、ターゲットはターゲットグループを使用して登録され初期ヘルスチェックを渡した後、すぐにリクエストの全シェアを受信し始めます。スロースタートモードを使用すると、ロードバランサーがターゲットにリクエストの全シェアを送信し始めるまでの猶予期間が設定されます。
ターゲットグループのスロースタートを有効にした後、ターゲットグループによってそのターゲットが正常と見なされると、ターゲットはスロースタートモードになります。スロースタートモードのターゲットは、設定されたスロースタート期間が経過するか、ターゲットが異常になると、スロースタートモードを終了します。ロードバランサーは、スロースタートモードのターゲットに送信できるリクエスト数を直線的に増加させます。正常なターゲットがスロースタートモードを終了すると、ロードバランサーはリクエストの全シェアを送信できます。
https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-target-groups.html#slow-start-mode
例えば、スロースタート期間を 300 秒にすると、pod が Ready になってから 300 秒でフルアクセスを受けるようになり、それまでは直線的にリクエストの受け入れ数が増加していくということですね。
これならば、時間を増やせばさらに緩やかにリクエストを送りつけられそうです。
もちろん既存の pod は忙しくなりますが、新しく起動した pod に対しては目的が果たせそうです。
スロースタート期間の設定
スロースタート期間の設定はターゲットグループの属性を編集することでも可能ですが、さすがに AWS のコンソールから設定して管理というわけにはいかないですよね。
今回は、全ターゲットグループへの一括設定と、ターゲットグループの個別設定を紹介します。
まず、「AWS Load Balancer Controller」の「Ingress annotations」の説明で、「alb.ingress.kubernetes.io/target-group-attributes」の Location が以下に対応していることが記載されています。
Ingress
Service
一括設定(Ingress)
Ingress のアノテーションで設定すると、すべてのターゲットグループに対して適用されます。
alb.ingress.kubernetes.io/target-group-attributes: slow_start.duration_seconds=300
個別設定(Kubernetes – Service)
個別に設定する場合は、Service のアノテーションで設定します。
apiVersion: "v1"
kind: "Service"
metadata:
name: hoge
annotations:
alb.ingress.kubernetes.io/target-group-attributes: slow_start.duration_seconds=300