Kubernetes と HPA と VPA と ClusterAutoscaler

はじめに

この記事は、CyberAgent 20新卒 エンジニア Advent Calendar 2019の15日目の記事です。

adventar.org

自己紹介

AI事業本部の SIA で内定者アルバイトをしています、げんば (GB) といいます。

インターネットでは gurapomu という名前で活動しています。Twitter やっていますが技術的なことはほぼつぶやかないのでご注意ください。

目次

  • Kubernetes とは
  • PodAutoscale
  • HPA と VPA の併用
    • HPA external metrics and VPA (予定)
  • VPA と ClusterAutoscaler の併用

Kubernetes とは

みなさんご存知でしょうし細かい説明は省略します。一言でいうと Google がつくったコンテナオーケストレーターです。「クバネティス」とか「クーベネティス」とかいろいろな読まれ方をしています。名称が長いので k8s という略称があります。k と s の間が8文字であることに由来しているようです。自分自身はずっと「けーはちえす」と言っていましたがあんまりこう言ってる人はいなさそうです。海外では「k-eights」という読まれ方は結構されているようです。1

名前すら初めて聞いたぞ、という方には申し訳ありませんがここからの内容は少しは Kubernetes いじったことあるぞ、といった人以上を対象としたお話になります。

Pod Scaling

今回の主題は pod の autoscaling についてです。Kubernetes では HPA と VPA2 という2種類の scale 方法が用意されています。それぞれについて軽く説明しておきたいと思います。

HPA (Horizontal Pod Autoscaler)

horizontal は和訳すると水平という意味ですので水平にポッドをスケールする機能ということになります。水平スケールとはスケールアウトのことを指し、pod 自体の数を増減することで調整を行うという機能ということです。

VPA (Vertical Pod Autoscaler)

vertical は和訳すると垂直という意味です。ですので VPA は 垂直スケール、すなわちポッド自体の大きさを変更することによって調整を行う機能になります。水平と垂直の覚え方に関しては諸説ありますが自分としてはどれも納得が行っていないので読者の課題とします。

f:id:gurapomu:20191204180809p:plain

HPA と VPA の併用

それでは実際にこれらを導入してみます。VPA コンポーネントについてはそこそこ日本語記事がありますのでそちらを参照されるといいかと思います。

以下のyamlが実際にデプロイしたマニフェストです。公式の github にあるマニフェストを参考に HPA を追加で定義したものになります。

autoscaler/hamster.yaml at master · kubernetes/autoscaler · GitHub

---
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
  name: hamster-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: hamster
  minReplicas: 1
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      targetAverageUtilization: 50
---
apiVersion: "autoscaling.k8s.io/v1beta2"
kind: VerticalPodAutoscaler
metadata:
  name: hamster-vpa
spec:
  targetRef:
    apiVersion: "apps/v1"
    kind: Deployment
    name: hamster
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.5
        ports:
        - containerPort: 80

デプロイしたポッドでは nginx が立ちあがります。

こちらに何らかの方法で負荷をかけていきます。今回の実験環境では LOCUST による負荷テストを行いました。

結果

負荷テストを行った結果、先に HPA が機能し十分にスケールされ VPA が機能しないという減少が起こりました。HPA によってポッドが 20 個まで増加した結果、個々のポッドの負荷は大きくならずにスケールアップの必要性がないと判断されるというロジックです。

VPA の README.md を読むとこんなことが書いてあります。

Vertical Pod Autoscaler should not be used with the Horizontal Pod Autoscaler (HPA) on CPU or memory at this moment. However, you can use VPA with HPA on custom and external metrics.

github.com

そもそも、VPA と HPA を標準で使うべきではなかったみたいです。但し書きとして HPA で外部メトリクスを用いれば良いと書いてあったので、今後検証を行い追記したいと考えています。

VPA と ClusterAutoscaler の併用

今度は ClusterAutoscaler と併用してみる実験です。ClusterAutoscaler については深くは触れませんが簡単にいうと、Kubernetes のノード自体をスケールアウトさせようという機能になります。これによりリソース不足でデプロイできないポッドが発生すると新しいノードがクラスタに参入し、新たにポッドがデプロイできるようになるというメリットが得られます。

クラスタに ClusterAutoscaler を導入し、先程のマニフェストから HPA リソースを削除したものをデプロイし、LOCUST によって負荷をかけました。

結果

結果は以下のとおりです。時間の経過によりノードが作成されて徐々に RPS が上昇していることがわかります。

f:id:gurapomu:20191216141713p:plain

蛇足

蛇足にはなりますが、VPA と ClusterAutoscaler の併用にはうまく動作しないエッジケースが存在します。しかしそれを説明するためには本記事では前提となる VPA の仕組みの解説が足りていないため読者の課題とします。

おわりに

投稿が遅れてしまい申し訳ありません。風邪で稼働できずに予定していた内容も網羅できていないため今後随時追記を行っていく予定です 個々までお読みいただきありがとうございました。


  1. 要出典

  2. 現在アルファ版につき絶賛機能開発中のようです。