GKEでPodとNodeをAutoscaling する

# はじめに

この記事は、**Google Cloud Platform(2) Advent Calendar 2016** 3日目の記事です。昨日は、strskさんのGKEに関する内容でした。ネタ被りしてないかドキドキです。
今日はGKE上で HPA (Horizonal Pod Autocaling) とさらに Cluster Autoscalerを設定する方法を紹介したいと思います。
ここでは、GKEが何であるかとかPodが何であるかなどは説明しません。

# HPA

HPAはCPU使用率(GKE1.4では、alhpaサポートとしてほかのメトリクスも設定できるようです)にしたがって、Pod数を増減させます。PodのCPU使用率平均を定期的に確認し(デフォルトでは30秒ごと)、設定した閾値とCPU使用率平均を比較し続けます。HPAを設定するためには、Deployment, Replication Controller,Replica Setが必要です。これを利用してCPU負荷によりPodの数を増減させることが可能です。

## 設定方法

### 新規設定
例えば Deployment `nginx` に対して、CPU使用率50%閾値で最小1Podから最大10PodまでAutoscalingする設定するコマンドは下記です。

```shell-session
$ kubectl autoscale deployment nginx --cpu-percent=50 --min=1 --max=10
deployment "nginx" autoscaled
```

また、Replication Controller `foo` に対して、CPU使用率80%閾値で最小2Podから最大5PodまでAutoscalingするように設定する場合は下記のようになります。

```shell-session
$ kubectl autoscale rc foo --min=2 --max=5 --cpu-percent=80
replication controller "foo" autoscaled
```

### 現状確認
現在のHPAの状態は `kubectl get hpa` を利用し以下のように確認できます。

```shell-session
$ kubectl get hpa
NAME      REFERENCE           TARGET    CURRENT   MINPODS   MAXPODS   AGE
nginx     Deployment/nginx    50%       2%        1         10        3s
```

Autocaling 対象の deploymentなどもPod数が増減した場合は確認できます

```shell-session
$ kubectl get deploy nginx
NAME      DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
nginx     1         1         1            1           224d
```

### 変更

閾値やPod数の上限下限を変更するときは、 `kubectl edit hpa` を利用し以下のようにします。

```shell-session
$ kubectl edit hpa nginx
```

コマンドを実行すると、設定されているeditorが立ち上がりますので、そこで編集します

```yaml
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  creationTimestamp: 2016-11-24T02:30:45Z
  name: nginx
  namespace: default
  resourceVersion: "17624901"
  selfLink: /apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/nginx
  uid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
spec:
  maxReplicas: 5 <= ここ
  minReplicas: 1 <= ここ
  scaleTargetRef:
    apiVersion: extensions/v1beta1
    kind: Deployment
    name: nginx
  targetCPUUtilizationPercentage: 25 <= ここ
status:
  currentCPUUtilizationPercentage: 1
  currentReplicas: 1
  desiredReplicas: 1
```

```shell-session
$ kubectl edit hpa
horizontalpodautoscaler "nginx" edited
```

### 削除

HPA設定を削除するときは、 `kubectl delete hpa` を利用します。

```shell-session
$ kubectl delete hpa nginx
horizontalpodautoscaler "nginx" deleted
```

# Cluster Autoscaler

次に、Nodeの Autoscaling を設定します。
挙動としては空きリソースがなくHPAがPodを配置できなくなったときにNodeを増やそうとします。逆に、あるNodeに余裕が出てきてそのNode上の全Podを他のNodeへ移すことができるときにそのNodeは削除されます。
新規Nodeを起動してさらにコンテナイメージをGCRなどから落とすことになるので、Pod起動まである程度時間はかかります。そのことを見越して、HPAの設定をしておく必要があります。

現状ベータ版での提供ですので、商用環境投入には注意が必要です。また、利用にあたっては大規模なクラスタでの使用が推奨されないなどありますので、公式ドキュメントもお読みください。

## 設定方法

### 既存クラスタの設定変更
GKEクラスタ  `test-cluster` にある、ノードプール `test-pool` に対して、最小2ノードから最大20ノードまでAutoscalingするように設定するには `gcloud container clusters update` コマンドを利用します。コマンド例は下記です。 `--zone` は省略しています。
Kubernetes マスターが再起動するため、完了までちょっと時間かかります。

```shell-session
$ gcloud container clusters update test-cluster --enable-autoscaling --min-nodes=2 --max-nodes=20 --node-pool test-pool
Updating test-cluster...done.
Updated [https://container.googleapis.com/v1/projects/XXXXXXXX/zones/XXXXXXX/clusters/test-cluster].
```

### 新規にAutoscaling有効なクラスタを作成する
最初からAutoscaling有効なGKEクラスタを作成するには、 `gcloud container clusters create` 実行時にAutoscaling関連のオプションを付加します。

```shell-session
$ gcloud container clusters create <クラスタ名> --enable-autoscaling --max-nodes=<最大ノード数> --min-nodes=<最小ノード数> <その他のオプション>
```

### 確認
GKEクラスタ `test-cluster` のautoscaling設定がどうなのかは、 `gcloud container clusters describe`　コマンドで確認できます。

```shell-session
$ gcloud container clusters describe test-cluster
<snip>
- autoscaling:
    enabled: true
    maxNodeCount: 20
    minNodeCount: 2
  config:
    diskSizeGb: xxx
<snip>
  name: test-pool
<snip>
```


### 無効化

[これ](https://cloud.google.com/sdk/gcloud/reference/alpha/container/clusters/update) によると Autoscalingを 無効化したい場合は、以下のようにコマンドを実行すれば良いです。Nodeの台数は、無効化した時の台数で固定されます。無効化後に台数を変更したいときは、普通に `gcloud container clusters resize` を実行します。

```shell-session
$ gcloud container clusters update test-cluster --disable-autoscaling --node-pool test-pool
Updating test-cluster...done.
Updated [https://container.googleapis.com/v1/projects/XXXXXXXX/zones/XXXXXXX/clusters/test-cluster].
```

設定がどうなったか確認してみましょう。

```shell-session
$ gcloud container clusters describe test-cluster
<snip>
- autoscaling: {}
  config:
    diskSizeGb: xxx
<snip>
  name: test-pool
<snip>
```

設定が消えていますね。

# 最後に

KubernetesのHPAとGKEのCluster Autoscalerについて紹介してみました。
GCPも東京リージョン始まってから日本語のドキュメントも増えてきました。東京リージョンでもGKEは使えますので、みなさまもGKEでコンテナ生活を試してみてはいかがでしょうか。

明日(12/4)はt-yotsuさんによるDataFlowに関する発表です