大分昔に更新して以来すっかり更新を放置していたので、久しぶりに更新してみようと。
前回からすると、お仕事も一新 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の増減に関してより細かい設定を行うことも可能です。