Horizontal Pod Autoscaler

Kubernetes Advent Calendar 2016。投稿が遅れてしまいましたが、コンテナを本番サービスで利用する場合にすごく便利ではないかなと思われる Horizontal Pod Autoscaler について紹介します。

Horizontal Pod Autoscalerとは

f:id:akubicharm:20161216145111p:plain

Horizontal Pod Autoscaler(HPA)はPodに割り当てられた CPU の使用率にしたがって、Pod の数を増減させる仕組みです。この仕組みを使うと Pod として動かしているアプリケーションが高負荷になった場合に、スケールアウトして負荷分散が可能になります。 デフォルトでは 30 秒ごとに負荷状況がチェックされ、スケールアウト/ダウンが実行されます。

ここまでで想像ができるかもしれませんが、CPU の使用率にしたがってPodを増減させるということは、CPU のメトリクスを収集する機能が実装されていなければいけません。Kubernetes では Heapster を使って CPU の使用を収集します。

OpenShift でのメトリクス収集とHPAの仕組み

メトリクス収集の仕組み

OpenShiftでは、Heapsterを使ったメトリクスの収集に加えて、Hawkular MetricsCassandra を利用してメトリクスの蓄積と可視化を行っています。 Heapster, Hawkular Metrics, Cassandra もそれぞれコンテナとして OpenShift 上で実行されます。

f:id:akubicharm:20161216144645p:plain

メトリクス収集の仕組みを有効にしておくと、OpenShift 管理コンソールではCPU, Memory, Network IO の状況を図のような折れ線グラフで参照することが可能になります。 f:id:akubicharm:20161216144634p:plain

HPA の仕組み

OpenShift は Kubernetes を活用した Container 型のアプリケーションプラットフォームですので、HPA の仕組みも Kubernetes の HPA と同様です。

HPA が Heapster から CPU の利用状況を、Replication Controller から稼働中のレプリカ数を取得します。CPU の使用率が閾値を超えている場合にはレプリカ数を増やし、CPU の使用率が閾値を下回った場合にはレプリカ数を減らします。また、レプリカ数が変更された場合には、 Replication Controller のステータスもアップデートされます。

f:id:akubicharm:20161216144639p:plain

OpenShift では、CPU、Memory のリソース割り当ては、Pod のデプロイ方式を定義した Deployment Config で行います。例えば、CPU の割り当てが 50m 〜 100m、メモリの割り当てが 100Mi 〜 200Mi の場合には、Deployment Config は次のようになります。

        resources:
          limits:
            cpu: 100m
            memory: 200Mi
          requests:
            cpu: 50m
            memory: 100Mi

レプリカ数を 1 〜 4 個、CPU 使用率の閾値を 80% とした場合、HPA は次のようになります。

spec:
  maxReplicas: 4
  minReplicas: 1
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: DeploymentConfig
    name: php
  targetCPUUtilizationPercentage: 80

OpenShift での設定

OpenShift でメトリクス収集を有効にする場合は、Heapster, Hawkular Metrics, Cassandra をそれぞれデプロイするのではなく、Metrics Deployer という、Metrics収集プラグインをセットアップするためのコンテナに環境設定を任せてしまうことができます。

設定方法を紹介する前に、ちょっとはまったことを...

今回は OpenShift Origin で環境構築をしたので、Kubernetes と Heapster のバージョンの組み合わせには注意が必要でした。

Metrics Deployer は Docker Hub から origin-metrics-deloyer のコンテナイメージ(docker.io/openshift/origin-metrics-deployer)を Pull してきて利用するのですが、latest のイメージだと、Kubernetes と Heapster のAPIバージョンが不一致となってしまい、Metrics 収集機能はりようできるけれでも HPA がちゃんと動作しませんでした。正しい組み合わせは、

Kubernetes Heapster
ver 1.3 ver 1.1
ver 1.4 ver 1.2

Kubernetes 1.3 で heapster 1.2 を使った場合には、ログ(journal)に以下のように unmarshall できないというエラーメセージが出ていました。

W1214 05:04:48.140190  112006 horizontal.go:99] Failed to reconcile hello: failed to compute desired number of replicas based on CPU utilization for DeploymentConfig/test/hello: failed to get CPU utilization: failed to get CPU consumption and request: failed to unmarshall heapster response: json: cannot unmarshal object into Go value of type []v1alpha1.PodMetrics

メトリクスプラグインの設定

OpenShift Originのインストールは https://docs.openshift.org/latest/install_config/install/advanced_install.html に従って実施します。

メトリクス収集機能は openshift-infra というProjectにデプロイします。

Project : Kubernetes の Namespace を拡張した概念

1. Metrics URL の追加

OpenShift の Master サーバの定義ファイル /etc/origin/master/master-config.yamlに metricsPublicURL を追加します。 Hawkular のコンテナも他のアプリケーションと同様に OpenShift にデプロイされるので、他のアプリケーションと同様に OpenShift の Route 経由でアクセス可能な URL を指定します。

assetConfig:
  < 中 略 >
  metricsPublicURL: "https://hawkular-metrics.192.168.1.1.xip.io/hawkular/metrics"
  < 中 略 >
routingConfig:
  subdomain:  "192.168.1.1.xip.io"

2. Service Account の作成

Metrics 収集のデプロイと実行に必要な Service Accountを作成します。

oc project openshift-infra
oc create -f - <<API
apiVersion: v1
kind: ServiceAccount
metadata:
  name: metrics-deployer
secrets:
- name: metrics-deployer
API

3. ポリシーの設定

先ほど作成した metrics-deployer、heapster, hawkular 用の Service Account に権限を付与します。

Metrics Deployer 用の Service Account に、openshift-infra プロジェクトの edit 権限を付与します。

oadm policy add-role-to-user \
    edit system:serviceaccount:openshift-infra:metrics-deployer

Heapster 用の Service Account に、cluster-reader 権限を付与します。

oadm policy add-cluster-role-to-user \
    cluster-reader system:serviceaccount:openshift-infra:heapster

Hawkular 用の Service Account に openshift-infra プロジェクトの view 権限を付与します。

oadm policy add-role-to-user view \
        system:serviceaccount:openshift-infra:hawkular \
        -n openshift-infra

4. metrics-deployer の secrets を作成

oc secrets new metrics-deployer nothing=/dev/null -n openshift-infra

5. metrics-deployer の準備

kubernetes v1.3 を使っている場合には、heapster の最新版を使ってしまうと、API バージョンが不整合になってしまいます。 そこで、既存のテンプレートを少し修正して利用します。

まず、既存のテンプレートを使って metrics-deployer をデプロイするための yaml ファイルを生成します。ここでは、簡易的にデプロイするために永続化ストレージを使わないオプション USE_PERSISTENT_STORAGE=false もつけておきます。

oc get templates -n openshift
oc process metrics-deployer-template -v HAWKULAR_METRICS_HOSTNAME=hawkular-metrics.192.168.1.1.xip.io -v USE_PERSISTENT_STORAGE=false -n openshift > metrics.yaml

Template : OpenShift にアプリケーションをデプロイするための雛形。OpenShift の Cluster 全体で利用するものは openshift プロジェクトに保持されている。

6. YAML ファイルの編集

生成された metrics.yaml ファイルを編集します。 IMAGE_VERSION を latest から v1.3.1 に変更します。

{
    "name": "IMAGE_VERSION",
    "value": "v1.3.1"
},

利用する metrics-deployer の Image Tag を latest から v1.3.1 に変更します。

"image": "openshift/origin-metrics-deployer:v1.3.1",

7. Metrics プラグインのデプロイ

編集した YAML ファイルを利用して、metrics-deployer をデプロイします。

oc create -f metric.yaml

あとは、気長に待ちましょう。。。

8. アプリケーションの設定

https://github.com/akubicharm/OpenShiftv3HandsOn/blob/master/3.3/autoscale/autoscale.md を参考に、やってみてください。

HPA で CPU の使用率を見ていくと、こんな風に使用率が表示されます。

oc get hpa -n test -w
NAME      REFERENCE              TARGET    CURRENT   MINPODS   MAXPODS   AGE
php       DeploymentConfig/php   10%       0%        1         4         21h

NAME      REFERENCE              TARGET    CURRENT   MINPODS   MAXPODS   AGE
php       DeploymentConfig/php   10%       168%      1         4         21h
php       DeploymentConfig/php   10%       168%      1         4         21h
php       DeploymentConfig/php   10%       700%      1         4         21h
php       DeploymentConfig/php   10%       700%      1         4         21h

終わりに

HPA のような仕組みで簡単にアプリケーションをスケールアウトできるのは、Container & Kubernetes だからこそですね。HPA を設定しておけば、急なアクセス過多になった場合でも滞りなくサービスを持続することができますので、運用の利便性も高くなりますので、ぜひ、試してみてください。