GIG

赴くままに技術を。

クラスターオートスケール機能

大分昔に更新して以来すっかり更新を放置していたので、久しぶりに更新してみようと。

前回からすると、お仕事も一新 Azure を触る機会が多くなりました。 いろいろと検証するのですが、書き溜めたメモがなかなか放流できずじまいに。

今回は、Azure Kubernetes Service (AKS) でたまに聞かれることがあるクラスターオートスケール機能について書いてみます。

Azure Kubernetes Service (AKS) でのアプリケーションの需要を満たすようにクラスターを自動的にスケーリング

Kubernetes のオートスケール機能

オートスケールの対象は、PodとNode です。
Pod は、負荷に応じて、Pod 数を増減させる水平オートスケールと、Pod 数ではなく割り当てる CPU / メモリリソースを調整する垂直オートスケール機能があります。
Node の方は、クラスターオートスケール という機能で、負荷状況ではなく、 Pod が割り当てられない (Pending) になった時点で Node を追加する仕組みになります。
現時点で、 AKS でサポートしているのは、水平オートスケール機能とクラスターオートスケール機能になります。

検証

それでは検証してみます。 まずは AKS クラスターを構築します。

$ az group create --name labca --location japaneast
$ az aks create \
  --resource-group labca \
  --name labca \
  --node-count 1 \
  --node-vm-size Standard_DS2_v2 \
  --enable-vmss \
  --enable-cluster-autoscaler \
  --min-count 1 \
  --max-count 3

Standard_DS2_v2 なので、1 ノード当たり 2 vCPU (2000m) 持つことになります (実際、割り当て可能なのは、1900m)。

$ az aks get-credentials -g labca -n labca
$ kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-24609861-vmss000000   Ready    agent   12m   v1.15.10

それでは、以下のようなシナリオで Node が追加されることを確認してみます。

  • 水平オートスケール (HorizontalpodAutoscaler) により、CPU 負荷が 50 % 以上を超えた場合、Pod を最大 5 つまでスケールアウトさせる
  • 対象のPodでは、絶えず負荷がかかるようにしておく

まずは水平オートスケールリソースを作成

$ cat << EOF | kubectl apply -f -
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: stress-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: stress
  minReplicas: 1
  maxReplicas: 5
  targetCPUUtilizationPercentage: 50
EOF

次いでオートスケール対象のPodを作成

$ cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: stress
  namespace: default
spec:
  replicas: 1
  selector:
    matchLabels:
      app: stress
  template:
    metadata:
      labels:
        app: stress
    spec:
      containers:
      - name: stress-test
        image: busybox
        command: ["dd", "if=/dev/zero", "of=/dev/null"]
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 500m
EOF

Pod の増加を見てみます。 他の管理系のPodがあるため、2つ (cpu : 1000m)分のみしかRunningになりませんでした。

kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
stress-864dc999dd-cpbk2   1/1     Running   0          65s
stress-864dc999dd-khfxp   1/1     Running   0          2m
stress-864dc999dd-lnggt   0/1     Pending   0          5s
stress-864dc999dd-ngbq7   0/1     Pending   0          5s

次いでクラスターオートスケールの状態を確認すると、Eventsにスケールアップのイベントが発生していることが分かります(vmss サイズを2に変更した旨)。

$ kubectl describe configmap -n kube-system cluster-autoscaler-status
...(省略)...
Events:
  Type    Reason         Age   From                Message
  ----    ------         ----  ----                -------
  Normal  ScaledUpGroup  80s   cluster-autoscaler  Scale-up: setting group aks-nodepool1-24609861-vmss size to 2
  Normal  ScaledUpGroup  80s   cluster-autoscaler  Scale-up: group aks-nodepool1-24609861-vmss size set to 2

しばらく待つと、Nodeが追加されました。

$ kubectl get nodes
NAME                                STATUS   ROLES   AGE   VERSION
aks-nodepool1-24609861-vmss000000   Ready    agent   25m   v1.15.10
aks-nodepool1-24609861-vmss000001   Ready    agent   35s   v1.15.10

それに伴い、PendingになっていたPodもデプロイされ、5つすべてRunningになります。

$ kubectl get pods
NAME                      READY   STATUS    RESTARTS   AGE
stress-864dc999dd-cpbk2   1/1     Running   0          15m
stress-864dc999dd-ffrtq   1/1     Running   0          10m
stress-864dc999dd-khfxp   1/1     Running   0          16m
stress-864dc999dd-lnggt   1/1     Running   0          14m
stress-864dc999dd-ngbq7   1/1     Running   0          14m

以上にようにアプリケーションの負荷に伴い、インフラ側でも柔軟に対応させることが可能となります。
Nodeの増減に関してより細かい設定を行うことも可能です。

クラスター オートスケーラーの設定の変更