せっかくKubernetesを運用するなら、いい感じに自動スケールさせたい!
GKE Autopilotモードとは
Google CloudでKubernetesを運用したい場合、GKE Standard/Autopilotクラスタの選択肢があります。大きな違いは、ノード(データプレーン)がGoogleマネージドであるかどうかです。
Autopilotでは、ノードのバージョンアップやスケーリング設定は自動で行われます。Podがスケールアウトする時は、既存のノードに新しいPodを起動するための容量がない場合に新しいノードが自動で作成されます。
しかしながら、新しいノードの起動には1~2分ほどかかるため、急激なトラフィック増加には素早く対応できない場合もあります。
GKE Autopilotでのリソースリクエスト
Kubernetesでは、ワークロードに指定できるPodリソースの上限/下限を設定する事ができます。
(未設定の場合はAutopilotだとデフォルト値になります。)
Pod仕様のリソースにrequests
(下限)と limits
(上限)を以下のように設定します。
resources: limits: cpu: 1000m memory: 4Gi requests: cpu: 250m memory: 1Gi
これにより、トラフィック増加の際にはlimits
で指定された値までバーストして、ワークロード負荷に対応しやすくなります。
HPAでPodをスケールさせる
Horizontal Pod Autoscaler(HPA)はワークロードのCPUやメモリ消費量等に基づいて、自動的にPod数を水平方向にスケールさせるKubernetesの機能です。
例えば以下の例ですと、Podを指定した上でCPU使用率50%を閾値としてPod数を最小1〜最大5個まで自動スケールする、といった設定になります。
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: php-dynamic-content-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: php-dynamic-content minReplicas: 1 maxReplicas: 5 targetCPUUtilizationPercentage: 50
ちなみに、Pod数の増減ではなく、個々のPodのリソース値を自動更新(= 垂直スケール)するVertical Pod Autoscaler(VPA)という機能もありますが、基本的には急激なトラフィック増に対処する場合はHPAの利用が推奨されています。
Balloon Podによる高速スケーリング
先述の通り、新しいのノードの起動には少し時間がかかります。なので急激なトラフィック増に備える場合、あらかじめノード数を増やしておきたいというのが真っ先に思いつく事かと思います。
しかしながら、Autopilotモードですとノードのスケールは自動で行われるので、ノード数を手動で指定して増やしておく事ができません…
ここで、登場するのがBalloon Podというテクニックになります。
名前の通り「風船」のように優先度が低くて即時に壊れるダミーのBalloon Podを作成する事で余剰ノードを事前に用意しておきます。これによりトラフィックが急増した際には、Ballon Podを追い出す事でノードのスケールを待つ事なく、Podを秒単位で高速にスケールする事が可能となります。
置き換えられる前提のPodリソースの例
apiVersion: apps/v1 kind: Deployment metadata: name: balloon-deploy spec: replicas: 5 selector: matchLabels: app: balloon template: metadata: labels: app: balloon spec: priorityClassName: balloon-priority terminationGracePeriodSeconds: 0 containers: - name: busybox image: busybox:latest command: ["sleep"] args: ["infinity"] resources: requests: cpu: 500m memory: 2Gi
特に稼働はさせないのでcommand: ["sleep"]
としておき、terminationGracePeriodSeconds
を短くして、即座に削除されるようにしております。
Balloon Podの優先度設定の例
apiVersion: scheduling.k8s.io/v1 kind: PriorityClass metadata: name: balloon-priority value: -10 preemptionPolicy: Never globalDefault: false description: "Balloon pod priority."
デフォルトの優先度は0
なので、優先度を-10
と低く設定しております。
Kubernetesの仕様として、リソースの競合が発生するときは優先度を見て、低いものを犠牲にし、高いものの稼働を確保する振る舞いになっています。
まとめ
今回はGKE Autopilotで自動スケールさせる方法をいくつか紹介しました。
うまく自動スケールさせる事で、トラフィック増加に素早く対応しつつ、不要リソースを削除してコスト削減も狙っていけそうです!
色々設定が可能な分、どれを選択するか悩ましい所もありますが、いい感じに設定していきたいですね。