はじめに
Kubernetes Horizontal Pod Autoscaler(HPA) は、そのリソースの CPU 使用率に基づいて設定されたデプロイ、レプリケーションコントローラー、またはレプリカセット内の Pods の数を自動的にスケーリングします。
HPA を動作させるには、メトリクスソース (metrics-server など) が EKS クラスターにインストールされている必要があります。
Cluster
cluster は、以前書いた下記の記事の「cluster」を参考に準備します。
metrics-server
# metrics-server をデプロイ
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
serviceaccount/metrics-server created
clusterrole.rbac.authorization.k8s.io/system:aggregated-metrics-reader created
clusterrole.rbac.authorization.k8s.io/system:metrics-server created
rolebinding.rbac.authorization.k8s.io/metrics-server-auth-reader created
clusterrolebinding.rbac.authorization.k8s.io/metrics-server:system:auth-delegator created
clusterrolebinding.rbac.authorization.k8s.io/system:metrics-server created
service/metrics-server created
deployment.apps/metrics-server created
apiservice.apiregistration.k8s.io/v1beta1.metrics.k8s.io created
# metrics-server がデプロイされたことを確認
kubectl get deploy metrics-server -n kube-system
NAME READY UP-TO-DATE AVAILABLE AGE
metrics-server 1/1 1 1 108s
なお、metrics-server の pod が自身の node の kubelet にアクセスできないという仕様があるようです。
# metrics-server の pod を確認
kubectl get pod metrics-server-5d875656f5-4xt6b -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
metrics-server-5d875656f5-4xt6b 1/1 Running 0 10m 192.168.105.150 fargate-ip-192-168-105-150.ap-northeast-1.compute.internal <none> <none>
# CPU MEMORY を確認すると、metrics-server の node のみ メトリクス の取得ができていない
kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
fargate-ip-192-168-104-238.ap-northeast-1.compute.internal 16m 0% 125Mi 6%
fargate-ip-192-168-120-144.ap-northeast-1.compute.internal 17m 0% 130Mi 7%
fargate-ip-192-168-105-150.ap-northeast-1.compute.internal <unknown> <unknown> <unknown> <unknown>
# metrics-server のログを確認
kubectl logs metrics-server-5d875656f5-4xt6b -n kube-system
E1110 02:31:36.639649 1 scraper.go:140] "Failed to scrape node" err="Get \"https://192.168.105.150:10250/metrics/resource\": dial tcp 192.168.105.150:10250: connect: connection refused" node="fargate-ip-192-168-105-150.ap-northeast-1.compute.internal"
Horizontal Pod Autoscaler
Apache Web Server Application のサンプルです。
これは、 500 millicpu
の CPU limits があります。
php-apache.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: php-apache
spec:
selector:
matchLabels:
run: php-apache
template:
metadata:
labels:
run: php-apache
spec:
containers:
- name: php-apache
image: registry.k8s.io/hpa-example
ports:
- containerPort: 80
resources:
limits:
cpu: 500m
requests:
cpu: 200m
---
apiVersion: v1
kind: Service
metadata:
name: php-apache
labels:
run: php-apache
spec:
ports:
- port: 80
selector:
run: php-apache
HPA は CPU 使用率が 50% で、最小 1 個の Pod、最大 10 個 の Pods を使用するオートスケーラーです。
php-apache-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: php-apache
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
# php-apache.yaml を apply
kubectl apply -f php-apache.yaml
deployment.apps/php-apache created
service/php-apache created
# deploy,pod,service を確認
kubectl get deploy,pod,service -o wide
NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
deployment.apps/php-apache 1/1 1 1 46m php-apache registry.k8s.io/hpa-example run=php-apache
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/php-apache-5bdbb8dbf8-4skcc 1/1 Running 0 46m 192.168.124.189 fargate-ip-192-168-124-189.ap-northeast-1.compute.internal <none> <none>
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
service/php-apache ClusterIP 10.100.61.142 <none> 80/TCP 46m run=php-apache
# php-apache-hpa.yaml を apply
kubectl apply -f php-apache-hpa.yaml
horizontalpodautoscaler.autoscaling/php-apache created
# hpa を確認
kubectl get hpa
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 0%/50% 1 10 1 19s
動作確認
# kubectl run -i --tty load-generator: 新しいPodを作成し、そのPod内で対話的なセッションを開始します。このPodはload-generatorと呼ばれます。
# --rm: Podが終了するときに削除されるようにします。これにより、一時的なジョブの実行に便利です。
# --image=busybox: 使用するDockerイメージを指定します。この場合、busyboxという軽量なLinuxディストリビューションが使用されます。
# --restart=Never: Podが終了したら再起動しないように指定します。これはジョブを一度だけ実行する場合に役立ちます。
# /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done": Pod内で実行されるコマンド。具体的には、wgetを使用してhttp://php-apacheに対して0.01秒ごとにHTTPリクエストを行います。これにより、指定されたエンドポイントに対して継続的な負荷がかかるようになります。
kubectl run -i \
--tty load-generator \
--rm --image=busybox \
--restart=Never \
-- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"
# hpa で TARGETS が上昇していることを確認
kubectl get hpa php-apache
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
php-apache Deployment/php-apache 114%/50% 1 10 2 4m43s
# pod が増加していることを確認
kubectl get pod
NAME READY STATUS RESTARTS AGE
load-generator 1/1 Running 0 2m19s
php-apache-5bdbb8dbf8-4skcc 1/1 Running 0 8m22s
php-apache-5bdbb8dbf8-bh4wg 0/1 Pending 0 47s
参考