「メトリクスサーバーを使用して、KubernetesのHorizontal Pod Autoscalerの設定方法」
はじめに
Kubernetesは、耐障害性と拡張性の両方を提供することを目指しています。それは、異なるリソース割り当てを持つ複数のポッドを展開することで、アプリケーションの冗長性を提供します。必要に応じて自分自身の展開を手動で拡張または縮小することができますが、KubernetesはHorizontal Pod Autoscalingと呼ばれる機能を使用して、オンデマンドでスケーリングするためのファーストクラスのサポートを提供します。これは、現在のニーズに基づいてリソース(アプリケーションポッド)を自動的に拡大または縮小するクローズドループシステムです。自動スケーリングが必要な各アプリケーション展開にHorizontalPodAutoscaler(またはHPA)リソースを作成し、それに自動的に世話をしてもらいます。
高い水準でのHPAの役割は次のとおりです。
-
- アプリケーションのワークロード(Pods)からリソース要求メトリクスを監視し、メトリクスサーバーに問い合わせします。
-
- HPAの定義で設定した目標閾値と、アプリケーションのワークロード(CPUとメモリ)の平均リソース利用状況を比較します。
- 目標閾値に達すると、HPAはアプリケーションの展開をスケールアップして、需要の増加に対応します。閾値を下回る場合は、展開をスケールダウンします。アプリケーションの展開をスケールするためのHPAのロジックについては、公式ドキュメントのアルゴリズムの詳細ページを参照してください。
ホリゾンタルポッドオートスケーラーは、クラスターの制御プレーン内にある専用のコントローラを介して実装されたKubernetes制御ループを駆動するCRD(カスタムリソース定義)です。アプリケーションのデプロイメントをターゲットとしたHorizontalPodAutoscalerのYAMLマニフェストを作成し、その後、クラスターでHPAリソースを適用するためにkubectlを使用します。
HPAが正常に動作するためには、CPU使用率やメモリ使用率など必要なメトリクスを収集するためのメトリクスサーバーがクラスター内で利用可能である必要があります。Kubernetes Metrics Serverは、その1つの直感的なオプションです。Metrics Serverは、Kubeletからリソースのメトリクスを収集し、それらをKubernetes APIサーバー経由でHorizontal Pod Autoscalerに公開することによって機能します。必要な場合は、Metrics APIはkubectl topを介してもアクセスすることができます。
このチュートリアルでは、次のことができます:
- Deploy Metrics Server to your Kubernetes cluster.
- Learn how to create Horizontal Pod Autoscalers for your applications.
- Test each HPA setup, using two scenarios: constant and variable application load.
もし管理されたKubernetesホスティングサービスをお探しの場合は、成長を重視した当社のシンプルな管理されたKubernetesサービスをご覧ください。
前提条件
このチュートリアルに従うためには、以下のものが必要です:
- A Kubernetes cluster with role-based access control (RBAC) enabled. This setup will use a Silicon Cloud Kubernetes cluster, but you could also create a cluster manually. Your Kubernetes version should be between 1.20 and 1.25.
- The kubectl command-line tool installed in your local environment and configured to connect to your cluster. You can read more about installing kubectl in the official documentation. If you are using a Silicon Cloud Kubernetes cluster, please refer to How to Connect to a Silicon Cloud Kubernetes Cluster to learn how to connect to your cluster using kubectl.
- The version control tool Git available in your development environment. If you are working in Ubuntu, you can refer to installing Git on Ubuntu 22.04
- The Kubernetes Helm package manager also available in your development environment. You can refer to how to install software with Helm to install Helm locally.
ステップ1:Helmを使ってMetrics Serverをインストールする。
まず、ヘルムパッケージリストにメトリクスサーバーリポジトリを追加します。 helm repo add を使用することができます。
- helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server
次に、helm repo updateコマンドを使用して利用可能なパッケージを更新してください。
- helm repo update metrics-server
Hang tight while we grab the latest from your chart repositories… …Successfully got an update from the “metrics-server” chart repository Update Complete. ⎈Happy Helming!⎈
ヘルムにリポジトリを追加したので、Kubernetesの展開にメトリクスサーバを追加することができます。ここで独自の展開設定を書くこともできますが、このチュートリアルではSilicon CloudのKubernetesスターターキットに従い、メトリクスサーバの設定を行います。
それを行うために、Kubernetes スターターキットの Git リポジトリをクローンしてください。
- git clone https://github.com/digitalocean/Kubernetes-Starter-Kit-Developers.git
「metrics-server」の構成は「Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/metrics-server-values-v3.8.2.yaml」にあります。nanoやお好きなテキストエディタを使用して表示や編集ができます。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/metrics-server-values-v3.8.2.yaml
いくつかの在庫パラメーターが含まれています。レプリカは固定値であり、2です。
## Starter Kit metrics-server configuration
## Ref: https://github.com/kubernetes-sigs/metrics-server/blob/metrics-server-helm-chart-3.8.2/charts/metrics-server
##
# Number of metrics-server replicas to run
replicas: 2
apiService:
# Specifies if the v1beta1.metrics.k8s.io API service should be created.
#
# You typically want this enabled! If you disable API service creation you have to
# manage it outside of this chart for e.g horizontal pod autoscaling to
# work with this release.
create: true
hostNetwork:
# Specifies if metrics-server should be started in hostNetwork mode.
#
# You would require this enabled if you use alternate overlay networking for pods and
# API server unable to communicate with metrics-server. As an example, this is required
# if you use Weave network on EKS
enabled: false
メトリクスサーバーの利用可能なパラメーターの説明については、メトリクスサーバーチャートページを参照してください。
Note
ファイルを確認し、必要な変更を行った後は、このファイルをhelm installコマンドと一緒に提供することで、metrics-serverのデプロイを進めることができます。
- HELM_CHART_VERSION=“3.8.2”
- helm install metrics-server metrics-server/metrics-server –version “$HELM_CHART_VERSION“ \
- –namespace metrics-server \
- –create-namespace \
- -f “Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/metrics-server-values-v${HELM_CHART_VERSION}.yaml”
これにより、設定されたKubernetesクラスタにメトリクスサーバーが展開されます。
NAME: metrics-server LAST DEPLOYED: Wed May 25 11:54:43 2022 NAMESPACE: metrics-server STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: *********************************************************************** * Metrics Server * *********************************************************************** Chart version: 3.8.2 App version: 0.6.1 Image tag: k8s.gcr.io/metrics-server/metrics-server:v0.6.1 ***********************************************************************
デプロイメント後に、helm lsを使用して、metrics-serverがデプロイメントに追加されたことを確認できます。
- helm ls -n metrics-server
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION metrics-server metrics-server 1 2022-02-24 14:58:23.785875 +0200 EET deployed metrics-server-3.8.2 0.6.1
次に、metrics-serverネームスペースに展開されたすべてのKubernetesリソースのステータスを確認することができます。
- kubectl get all -n metrics-server
設定に基づいてデプロイした場合、deployment.appsおよびreplicaset.appsの値は2つの利用可能なインスタンスをカウントするはずです。
NAME READY STATUS RESTARTS AGE pod/metrics-server-694d47d564-9sp5h 1/1 Running 0 8m54s pod/metrics-server-694d47d564-cc4m2 1/1 Running 0 8m54s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/metrics-server ClusterIP 10.245.92.63 <none> 443/TCP 8m54s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/metrics-server 2/2 2 2 8m55s NAME DESIRED CURRENT READY AGE replicaset.apps/metrics-server-694d47d564 2 2 2 8m55s
あなたは現在、Kubernetesクラスターにメトリクスサーバーを展開しました。次のステップでは、HorizontalPodAutoscalerカスタムリソース定義のいくつかのパラメータを確認します。
ステップ2 – HPAの理解
これまで、あなたの設定では、展開するReplicaSetインスタンスの数に固定値が使用されていました。このステップでは、HorizontalPodAutoscaler CRDを定義する方法を学び、この値を動的に増減させることができます。
典型的なHorizontalPodAutoscaler CRDは次のようになります。
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app-deployment
minReplicas: 1
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
この設定で使用されるパラメータは次の通りです。
- spec.scaleTargetRef: A named reference to the resource being scaled.
- spec.minReplicas: The lower limit for the number of replicas to which the autoscaler can scale down.
- spec.maxReplicas: The upper limit.
- spec.metrics.type: The metric to use to calculate the desired replica count. This example is using the Resource type, which tells the HPA to scale the deployment based on average CPU (or memory) utilization. averageUtilization is set to a threshold value of 50.
アプリケーションの展開には、2つのオプションがあります。HPAを作成する方法を選ぶことができます。
-
- 既存のデプロイメントに対して kubectl autoscale コマンドを使用してください。
- HPAのYAMLマニフェストを作成し、その後、kubectlを使用してクラスターへの変更を適用してください。
最初にオプション1を試します。Silicon Cloud Kubernetes Starter Kitから別の設定を使用します。myapp-test.yamlというデプロイメントが含まれていて、任意のCPU負荷を作成してHPAを実演します。
お気に入りのテキストエディター、またはnanoを使って、そのファイルを確認することができます。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/myapp-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-test
spec:
selector:
matchLabels:
run: myapp-test
replicas: 1
template:
metadata:
labels:
run: myapp-test
spec:
containers:
- name: busybox
image: busybox
resources:
limits:
cpu: 50m
requests:
cpu: 20m
command: ["sh", "-c"]
args:
- while [ 1 ]; do
echo "Test";
sleep 0.01;
done
このファイルの最後の数行に注意してください。それらはシェルの構文を含んでおり、負荷をシミュレートするために1秒に100回「テスト」というメッセージを繰り返し表示するものです。ファイルのレビューが終了したら、kubectlを使用してクラスタに展開することができます。
- kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/myapp-test.yaml
次に、 kubectl autoscale を使用して、myapp-test デプロイメントをターゲットにした HorizontalPodAutoscaler を作成します。
- kubectl autoscale deployment myapp-test –cpu-percent=50 –min=1 –max=3
このコマンドに渡される引数に注意してください。これは、CPU利用率が50パーセントに達すると、デプロイメントが1から3のレプリカにスケーリングされることを意味します。
「kubectl get hpa」を実行することで、HPAリソースが作成されたかを確認できます。
- kubectl get hpa
出力のTARGETS列は、最終的に現在の使用率%/目標の使用率%の数値を示します。
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE myapp-test Deployment/myapp-test 240%/50% 1 3 3 52s
Note
HPAが生成するログイベントは、kubectl describeを使用して観察することもできます。
- kubectl describe hpa myapp-test
Name: myapp-test Namespace: default Labels: <none> Annotations: <none> CreationTimestamp: Mon, 28 May 2022 10:10:50 -0800 Reference: Deployment/myapp-test Metrics: ( current / target ) resource cpu on pods (as a percentage of request): 240% (48m) / 50% Min replicas: 1 Max replicas: 3 Deployment pods: 3 current / 3 desired … Events: Type Reason Age From Message —- —— —- —- ——- Normal SuccessfulRescale 17s horizontal-pod-autoscaler New size: 2; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 37s horizontal-pod-autoscaler New size: 3; reason: cpu resource utilization (percentage of request) above target
これはkubectl autoscaleメソッドです。本番環境では、通常は専用のYAMLマニフェストを使用して、各HPAを定義するべきです。これにより、マニフェストをGitリポジトリにコミットして変更を追跡し、必要に応じて修正することができます。
このチュートリアルの最後のステップで、実例を進めます。次に進む前に、myapp-testのデプロイメントと関連するHPAリソースを削除してください。
- kubectl delete hpa myapp-test
- kubectl delete deployment myapp-test
ステップ3 – メトリクスサーバーを使用してアプリケーションの自動スケーリング
この最後のステップでは、YAMLマニフェストを使用してサーバーロードを生成し、スケーリングする2つの異なる方法を試してみます。
-
- CPU密集型の演算を行うことによって、一定の負荷を生成するアプリケーション展開。
- シェルスクリプトは、ウェブアプリケーションのために高速な連続したHTTPリクエストを実行することで外部負荷をシミュレーションします。
定常負荷試験 (Teijō fuka shiken)
このシナリオでは、Pythonを使用して実装されたサンプルアプリケーションを作成し、いくつかのCPU集中型処理を行います。前のステップのシェルスクリプトと同様に、このPythonコードはスターターキットの例のマニフェストの1つに含まれています。nanoまたはお気に入りのテキストエディタを使用してconstant-load-deployment-test.yamlを開くことができます。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-deployment-test.yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: python-test-code-configmap
data:
entrypoint.sh: |-
#!/usr/bin/env python
import math
while True:
x = 0.0001
for i in range(1000000):
x = x + math.sqrt(x)
print(x)
print("OK!")
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: constant-load-deployment-test
spec:
selector:
matchLabels:
run: python-constant-load-test
replicas: 1
template:
metadata:
labels:
run: python-constant-load-test
spec:
containers:
- name: python-runtime
image: python:alpine3.15
resources:
limits:
cpu: 50m
requests:
cpu: 20m
command:
- /bin/entrypoint.sh
volumeMounts:
- name: python-test-code-volume
mountPath: /bin/entrypoint.sh
readOnly: true
subPath: entrypoint.sh
volumes:
- name: python-test-code-volume
configMap:
defaultMode: 0700
name: python-test-code-configmap
上記のPythonコードは、繰り返し任意の平方根を生成します。デプロイメントでは、必要なPythonランタイムをホストするDockerイメージを取得し、それから以前に示したサンプルPythonスクリプトをホストするアプリケーションポッドにConfigMapをアタッチします。
まず、この展開のために別の名前空間を作成してください(観察のため)、それからkubectlを使用して展開してください。
- kubectl create ns hpa-constant-load
- kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-deployment-test.yaml -n hpa-constant-load
configmap/python-test-code-configmap created deployment.apps/constant-load-deployment-test created
Note
デプロイメントが正常に作成され、稼働していることを確認してください。
- kubectl get deployments -n hpa-constant-load
NAME READY UP-TO-DATE AVAILABLE AGE constant-load-deployment-test 1/1 1 1 8s
次に、このクラスタに別のHPAを展開する必要があります。constant-load-hpa-test.yamlには、このシナリオに合致する例があります。このファイルはnanoやお気に入りのテキストエディタで開くことができます。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-hpa-test.yaml -n hpa-constant-load
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: constant-load-test
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: constant-load-deployment-test
minReplicas: 1
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50
kubectlを使用してデプロイしてください。
- kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/constant-load-hpa-test.yaml -n hpa-constant-load
これにより、サンプルのPythonデプロイメントをターゲットにしたHPAリソースが作成されます。kubectl get hpaコマンドを使用してconstant-load-test HPAの状態を確認できます。
- kubectl get hpa constant-load-test -n hpa-constant-load
定常負荷デプロイテストを対象とする「REFERENCE」列、および最後の例と同様の現在のCPUリソース要求と閾値値を示す「TARGETS」列に注意してください。
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE constant-load-test Deployment/constant-load-deployment-test 255%/50% 1 3 3 49s
サンプルアプリケーションの展開において、REPLICAS列の値がHPA CRD仕様に記載されている通りに1から3に増加したことにも気づくことができます。この例では、アプリケーションが非常に迅速にCPU負荷を生成するため、これが非常に速く発生しました。前の例と同様に、kubectl describe hpa -n hpa-constant-loadを使用して記録されたHPAイベントを確認することもできます。
外部負荷テスト
より興味深く現実的なシナリオは、外部負荷が生成される場所を観察することです。この最後の例では、前のテストからのデータを再利用しないために、異なる名前空間とマニフェストのセットを使用します。
この例では、現在の引用サンプルサーバーを使用します。このサーバーにHTTPリクエストが送信されるたびに、異なる引用が応答として送信されます。HTTPリクエストを1ミリ秒ごとに送信することで、クラスターに負荷をかけます。この展開は、quote_deployment.yamlに含まれています。nanoまたはお好きなテキストエディターを使用してこのファイルを確認してください。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote_deployment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: quote
spec:
replicas: 1
selector:
matchLabels:
app: quote
template:
metadata:
labels:
app: quote
spec:
containers:
- name: quote
image: docker.io/datawire/quote:0.4.1
ports:
- name: http
containerPort: 8080
resources:
requests:
cpu: 100m
memory: 50Mi
limits:
cpu: 200m
memory: 100Mi
---
apiVersion: v1
kind: Service
metadata:
name: quote
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: quote
この場合、実際のHTTPクエリースクリプトはマニフェストに含まれていません。このマニフェストは、クエリを実行するためのアプリを準備するだけです。ファイルのレビューが完了したら、kubectlを使用して引用名前空間と展開を作成してください。
- kubectl create ns hpa-external-load
- kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote_deployment.yaml -n hpa-external-load
引用アプリケーションの展開とサービスが正常に動作していることを確認してください。
- kubectl get all -n hpa-external-load
NAME READY STATUS RESTARTS AGE pod/quote-dffd65947-s56c9 1/1 Running 0 3m5s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/quote ClusterIP 10.245.170.194 <none> 80/TCP 3m5s NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/quote 1/1 1 1 3m5s NAME DESIRED CURRENT READY AGE replicaset.apps/quote-6c8f564ff 1 1 1 3m5s
次に、見積もりデプロイメントのHPAを作成します。これは、quote-deployment-hpa-test.yamlで設定されます。nanoまたはお気に入りのテキストエディタでファイルを確認してください。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote-deployment-hpa-test.yaml
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: external-load-test
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: quote
behavior:
scaleDown:
stabilizationWindowSeconds: 60
minReplicas: 1
maxReplicas: 3
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 20
この場合、CPU利用率のリソースメトリック(20%)には異なる閾値が設定されています。スケーリングの挙動も異なります。この設定により、scaleDown.stabilizationWindowSecondsの動作が変更され、値が60秒に設定されます。これは必ずしも常に必要ではありませんが、この場合はオートスケーラーがスケールダウンアクションを行う様子をより早く見たい場合に使用できます。デフォルトでは、HorizontalPodAutoscalerには5分のクールダウン期間があります。これはほとんどの場合に十分であり、レプリカのスケーリング時の変動を回避できるはずです。
準備ができたら、kubectlを使ってそれを展開してください。
- kubectl apply -f Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/manifests/hpa/metrics-server/quote-deployment-hpa-test.yaml -n hpa-external-load
現在、HPAリソースが正しく設定されており稼働しているかを確認してください。
- kubectl get hpa external-load-test -n hpa-external-load
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE external-load-test Deployment/quote 1%/20% 1 3 1 108s
最後に、shellスクリプトquote_service_load_test.shを使用して実際のHTTPクエリを実行します。このshellスクリプトを先にマニフェストに埋め込まなかった理由は、クラスタで実行しながらターミナルに直接ログを表示できるようにするためです。nanoやお気に入りのテキストエディタを使用してスクリプトを確認してください。
- nano Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/scripts/quote_service_load_test.sh
#!/usr/bin/env sh
echo
echo "[INFO] Starting load testing in 10s..."
sleep 10
echo "[INFO] Working (press Ctrl+C to stop)..."
kubectl run -i --tty load-generator \
--rm \
--image=busybox \
--restart=Never \
-n hpa-external-load \
-- /bin/sh -c "while sleep 0.001; do wget -q -O- http://quote; done" > /dev/null 2>&1
echo "[INFO] Load testing finished."
このデモンストレーションのために、別々の2つのターミナルウィンドウを開いてください。最初のウィンドウでquote_service_load_test.shシェルスクリプトを実行してください。
- Kubernetes-Starter-Kit-Developers/09-scaling-application-workloads/assets/scripts/quote_service_load_test.sh
次に、2番目のウィンドウで、HPAリソースに-wフラグを使用してkubectl watchコマンドを実行します。
- kubectl get hpa -n hpa-external-load -w
負荷が増えていくのが表示されて、自動的にスケールが調整されるのを確認してください。
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE external-load-test Deployment/quote 1%/20% 1 3 1 2m49s external-load-test Deployment/quote 29%/20% 1 3 1 3m1s external-load-test Deployment/quote 67%/20% 1 3 2 3m16s
負荷が増加すると、オートスケーラーが作動し、クォートサーバーデプロイメントのレプリカセットをより高い値に増やします。負荷生成スクリプトが停止すると、クールダウン期間が設けられ、1分ほど経った後にレプリカセットは初期値の1に戻ります。最初のターミナルウィンドウに戻ってから、実行中のスクリプトを終了するためにCtrl+Cを押すことができます。
結論
このチュートリアルでは、異なるシナリオでKubernetesメトリクスサーバーを使用して水平ポッドオートスケーリング(HPA)の動作を展開し、観察しました。HPAは、必要に応じてインフラストラクチャがトラフィックをより多く処理できるようにするために、Kubernetesの重要なコンポーネントです。
以下の文章を日本語に自然に言い換えます(選択肢は1つだけです):
メトリクスサーバーには重大な制限があり、CPUやメモリ使用状況を超えたメトリクスは提供できません。メトリクスサーバーのドキュメンテーションを詳しく確認すれば、使用ケース内での操作方法を理解することができます。もしディスク使用状況やネットワーク負荷など他のメトリクスを使用してスケールを行いたい場合は、特別なアダプターであるプロメテウスアダプターを介してプロメテウスを使用することができます。