前書き
Kubernetesで構築されたアプリケーションを使用する場合、開発者は、トラフィックのピーク時や負荷処理の増加を処理するために、追加のpodsをスケジュールする必要があります。 デフォルトでは、これらの追加ポッドのスケジュールは手動の手順です。開発者は、トラフィックの増加に対応するために、deployment object内の必要なreplicasの数を変更し、追加のポッドが不要になったら元に戻す必要があります。 手動介入へのこの依存は、多くのシナリオで理想的とは言えません。 たとえば、誰も目を覚ましてポッドのスケーリングを行っていない夜中にワークロードがピーク時間に達する可能性があります。また、手動応答では負荷に十分に対応できない場合、Webサイトで予期しないトラフィックの増加が発生する可能性があります。 このような状況で、最も効率的でエラーが発生しにくいアプローチは、Horizontal Pod Autoscaler (HPA)を使用してクラスターのスケーリングを自動化することです。
Metrics Serverからの情報を使用することにより、HPAはリソース使用量の増加を検出し、ワークロードをスケーリングすることで対応します。 これは特にマイクロサービスアーキテクチャで役立ち、KubernetesクラスターがCPU使用率などのメトリックに基づいて展開をスケーリングできるようになります。 コンテナ化されたアプリケーションをデプロイするためのプラットフォームを開発者に提供するマネージドKubernetesオファリングであるDigitalOcean Kubernetes (DOKS)と組み合わせると、HPAを使用して、トラフィックと負荷の変化にすばやく適応する自動インフラストラクチャを作成できます。
[。注意]##
Note:ワークロードに自動スケーリングを使用するかどうかを検討する場合、自動スケーリングはステートレスアプリケーション、特にアプリケーションの複数のインスタンスを実行してトラフィックを並行して受け入れることができるアプリケーションに最適であることに注意してください。 自動スケーリングの主な目的は、アプリケーションのワークロードをKubernetesクラスター内の複数のインスタンスに動的に分散し、単一のインスタンスを過負荷にすることなく、タイムリーかつ安定した方法でアプリケーションがトラフィックを処理するのに必要なリソースを確保することであるため、この並列処理は重要です
この並列性を示さないワークロードの例は、データベースの自動スケーリングです。 競合状態、データの整合性の問題、データの同期、データベースクラスターメンバーの継続的な追加と削除を考慮する必要があるため、データベースの自動スケーリングの設定は非常に複雑になります。 このような理由から、このチュートリアルのデータベースの自動スケーリング戦略を使用することはお勧めしません。
このチュートリアルでは、CPU負荷の増加に対応するために水平方向に自動スケーリングできるDOKSでのサンプルNginxデプロイメントをセットアップします。 これを実現するには、Metrics Serverをクラスターにデプロイして、HPAがスケーリングのタイミングを決定するときに使用するポッドメトリックを収集します。
前提条件
このガイドを始める前に、次のものが必要です。
-
接続が
kubectl
のデフォルトとして構成されたDigitalOceanKubernetesクラスター。kubectl
を構成する方法の説明は、クラスターを作成するときのConnect to your Clusterステップの下に表示されます。 DigitalOceanでKubernetesクラスターを作成するには、Kubernetes Quickstartを参照してください。 -
ローカルマシンにインストールされたHelmパッケージマネージャー、およびクラスターにインストールされたTiller。 これを行うには、How To Install Software on Kubernetes Clusters with the Helm Package Managerチュートリアルのステップ1と2を完了します。
[[step-1 -—- creating-a-test-deployment]] ==ステップ1—テストデプロイメントの作成
HPAの効果を示すために、最初にオートスケールに使用するアプリケーションをデプロイします。 このチュートリアルでは、標準のNginx Docker imageをデプロイとして使用します。これは、並列で完全に動作でき、Nginx Ingress Controllerなどのツールを使用してKubernetes内で広く使用されており、セットアップが軽量であるためです。 このNginxデプロイメントは、ベースイメージに標準で付属する静的なWelcome to Nginx!ページを提供します。 既に展開を行っている場合は、その展開を自由に使用して、この手順をスキップしてください。
次のコマンドを発行して、Nginxベースイメージを使用してサンプル展開を作成します。 デプロイメントに別の名前を付けたい場合は、名前web
を置き換えることができます。
kubectl create deployment web --image=nginx:latest
--image=nginx:latest
フラグは、最新バージョンのNginxベースイメージからデプロイメントを作成します。
数秒後、web
ポッドが回転します。 このポッドを表示するには、次のコマンドを実行します。これにより、現在のネームスペースで実行されているポッドが表示されます。
kubectl get pods
これにより、次のような出力が得られます。
OutputNAME READY STATUS RESTARTS AGE
web-84d7787df5-btf9h 1/1 Running 0 11s
元々デプロイされているポッドは1つだけであることに注意してください。 自動スケーリングがトリガーされると、より多くのポッドが自動的にスピンアップします。
これで、クラスター内で基本的な展開が実行されました。 これは、自動スケーリング用に構成する展開です。 次のステップは、このデプロイメントを構成して、リソース要求と制限を定義することです。
[[step-2 -—- setting-cpu-limits-and-requests-on-your-deployment]] ==ステップ2—デプロイメントでのCPU制限とリクエストの設定
このステップでは、デプロイメントのCPU使用率にrequests and limitsを設定します。 KubernetesのLimitsは、ポッドが使用できるリソース(CPUまたはメモリ)の最大量を表すためにデプロイに設定されます。 Requestsはデプロイメントに設定され、そのノードがスケジューリングの有効なノードと見なされるために、そのノードで必要なリソースの量を記述します。 たとえば、Webサーバーのメモリ要求が1GBに設定されている場合、少なくとも1GBの空きメモリがあるノードのみがスケジューリングの対象になります。 自動スケーリングの場合、スケーリングとスケジューリングの決定を行う際にHPAがこの情報を必要とするため、これらの制限と要求を設定する必要があります。
要求と制限を設定するには、作成したデプロイメントに変更を加える必要があります。 このチュートリアルでは、次のkubectl edit
コマンドを使用して、クラスターに格納されているAPIオブジェクト構成を変更します。 kubectl edit
コマンドは、KUBE_EDITOR
またはEDITOR
環境変数で定義されたエディターを開くか、Windowsの場合はデフォルトでvi
for Linuxまたはnotepad
にフォールバックします。
展開を編集します。
kubectl edit deployment web
展開の構成が表示されます。 デプロイメントのCPU使用率に指定されたリソース制限とリクエストを設定できるようになりました。 これらの制限により、この展開のポッドが個別に使用できる各リソースの量のベースラインが設定されます。 これを設定すると、ポッドが酷使されているかどうかを知るための参照フレームがHPAに与えられます。 たとえば、ポッドのCPUの上限limit
が100ミリコアであり、ポッドが現在95ミリコアを使用している場合、HPAは95%の容量であることを認識します。 100ミリコアという制限を設けないと、HPAはポッドの全容量を解読できません。
resources
セクションで制限とリクエストを設定できます。
展開構成ファイル
. . .
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:latest
imagePullPolicy: Always
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
. . .
このチュートリアルでは、CPUのrequests
を100m
に設定し、メモリを250Mi
に設定します。 これらの値は、デモンストレーションを目的としています。すべてのワークロードは異なるため、これらの値は他のワークロードには意味がない場合があります。 一般的なルールとして、これらの値は、このワークロードのポッドが使用すると予想される最大値に設定する必要があります。 これらの値を決定するには、アプリケーションを監視し、低い時間とピーク時間でのアプリケーションのパフォーマンスに関するリソース使用状況データを収集することをお勧めします。 これらの値はいつでも調整および変更できるため、いつでも戻ってデプロイメントを最適化できます。
先に進み、Nginxコンテナのresources
セクションの下に次の強調表示された行を挿入します。
展開構成ファイル
. . .
template:
metadata:
creationTimestamp: null
labels:
app: web
spec:
containers:
- image: nginx:latest
imagePullPolicy: Always
name: nginx
resources:
limits:
cpu: 300m
requests:
cpu: 100m
memory: 250Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
status:
availableReplicas: 1
. . .
これらの行を挿入したら、ファイルを保存して終了します。 構文に問題がある場合、kubectl
はファイルを再度開き、詳細についてはエラーが投稿されます。
制限とリクエストを設定したら、HPAがこれらの制限を監視して正しく遵守できるように、メトリックが収集されていることを確認する必要があります。 これを行うには、CPUメトリックを収集するサービスを設定します。 このチュートリアルでは、Metrics Serverプロジェクトを使用してこれらのメトリックを収集し、Helmチャートとともにインストールします。
[[step-3 -—- installing-metrics-server]] ==ステップ3—Metricsサーバーのインストール
次に、Kubernetes Metric Serverをインストールします。 これは、ポッドメトリックをスクレイピングするサーバーであり、HPAが自動スケーリングが必要かどうかを判断するために使用するメトリックを収集します。
Helmを使用してMetrics Serverをインストールするには、次のコマンドを実行します。
helm install stable/metrics-server --name metrics-server
これにより、Metrics Serverの最新の安定バージョンがインストールされます。 --name
フラグは、このリリースにmetrics-server
という名前を付けます。
このポッドが初期化されるのを待ったら、kubectl top pod
コマンドを使用してポッドのメトリックを表示してみてください。
kubectl top pod
このコマンドは、クラスター内のリソース使用量をポッドレベルで表示することを目的としていますが、DOKSがDNSを処理する方法のため、このコマンドはこの時点でエラーを返します。
OutputError: Metrics not available for pod
Error from server (ServiceUnavailable): the server is currently unable to handle the request (get pods.metrics.k8s.io)
このエラーは、DOKSノードが自身のDNSレコードを作成せず、Metrics Serverがホスト名を介してノードに接続するため、ホスト名が適切に解決されないために発生します。 この問題を修正するには、次のコマンドを使用してMetrics Serverコンテナにランタイムフラグを追加して、Metrics Serverがノードと通信する方法を変更します。
kubectl edit deployment metrics-server
command
セクションの下にフラグを追加します。
メトリックサーバー構成ファイル
. . .
template:
metadata:
creationTimestamp: null
labels:
app: metrics-server
release: metrics-server
spec:
affinity: {}
containers:
- command:
- /metrics-server
- --cert-dir=/tmp
- --logtostderr
- --secure-port=8443
image: gcr.io/google_containers/metrics-server-amd64:v0.3.4
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
. . .
追加するフラグは--kubelet-preferred-address-types=InternalIP
です。 このフラグは、ホスト名ではなくinternalIP
を使用してノードに接続するようにメトリックサーバーに指示します。 このフラグを回避策として使用して、内部IPアドレスを介してノードと通信できます。
また、--metric-resolution
フラグを追加して、メトリクスサーバーがメトリクスをスクレイプするデフォルトのレートを変更します。 このチュートリアルでは、60s
ごとにデータポイントを作成するようにMetrics Serverを設定しますが、より多くのメトリックスデータが必要な場合は、10s
または20s
ごとにメトリックスをスクレイプするようにMetricsServerに要求できます。 s。 これにより、期間ごとのリソース使用量のデータポイントが増えます。 ニーズに合わせてこの解像度を自由に微調整してください。
次の強調表示された行をファイルに追加します。
メトリックサーバー構成ファイル
. . .
template:
metadata:
creationTimestamp: null
labels:
app: metrics-server
release: metrics-server
spec:
affinity: {}
containers:
- command:
- /metrics-server
- --cert-dir=/tmp
- --logtostderr
- --secure-port=8443
- --metric-resolution=60s
- --kubelet-preferred-address-types=InternalIP
image: gcr.io/google_containers/metrics-server-amd64:v0.3.4
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 3
httpGet:
path: /healthz
. . .
フラグを追加したら、エディターを保存して終了します。
Metrics Serverが実行されていることを確認するには、数分後にkubectl top pod
を使用します。 前と同様に、このコマンドはポッドレベルでのリソース使用量を提供します。 今回は、稼働中のメトリックサーバーにより、各ポッドのメトリックを表示できます。
kubectl top pod
これにより、Metrics Serverポッドが実行された状態で、次の出力が得られます。
OutputNAME CPU(cores) MEMORY(bytes)
metrics-server-db745fcd5-v8gv6 3m 12Mi
web-555db5bf6b-f7btr 0m 2Mi
これで、機能的なMetricsサーバーができ、クラスター内のポッドのリソース使用量を表示および監視できるようになりました。 次に、このデータを監視し、CPU使用率が高い期間に対応するようにHPAを構成します。
[[step-4 -—-水平ポッドオートスケーラーの作成と検証]] ==ステップ4—水平ポッドオートスケーラーの作成と検証
最後に、展開用の水平ポッドオートスケーラー(HPA)を作成します。 HPAは、Metrics Serverから収集されたCPU使用率データを定期的にチェックし、ステップ2で設定したしきい値に基づいて展開をスケーリングする実際のKubernetesオブジェクトです。
kubectl autoscale
コマンドを使用してHPAを作成します。
kubectl autoscale deployment web --max=4 --cpu-percent=80
このコマンドは、web
デプロイメントのHPAを作成します。 また、--max
フラグを使用して、web
をスケーリングできる最大レプリカを設定します。この場合は4
として設定します。
--cpu-percent
フラグは、ステップ2で設定した制限の使用率でオートスケールをトリガーすることをHPAに通知します。 これは、リクエストを使用して、スケールアップされたポッドを初期リソース割り当てに対応できるノードにスケジュールするのにも役立ちます。 この例では、手順1で展開に設定した制限が100ミリコア(100m
)の場合、ポッドが平均CPU使用率で80m
に達すると、このコマンドは自動スケールをトリガーします。 これにより、展開はCPUリソースを使い果たす前に自動スケーリングできます。
展開が自動的にスケーリングできるようになったので、次はこれをテストします。
検証するには、クラスターをしきい値を超える負荷を生成し、オートスケーラーが引き継ぐのを監視します。 開始するには、2番目のターミナルを開いて、現在スケジュールされているポッドを監視し、2秒ごとにポッドのリストを更新します。 これを実行するには、次の2番目の端末でwatch
コマンドを使用します。
watch "kubectl top pods"
watch
コマンドは、引数として指定されたコマンドを継続的に発行し、端末に出力を表示します。 繰り返し間の期間は、-n
フラグを使用してさらに構成できます。 このチュートリアルでは、デフォルトの2秒の設定で十分です。
端末は最初にkubectl top pods
の出力を表示し、その後2秒ごとに、そのコマンドが生成する出力を更新します。これは次のようになります。
OutputEvery 2.0s: kubectl top pods
NAME CPU(cores) MEMORY(bytes)
metrics-server-6fd5457684-7kqtz 3m 15Mi
web-7476bb659d-q5bjv 0m 2Mi
web
に現在デプロイされているポッドの数に注意してください。
元の端末に切り替えます。 ここで、kubectl exec
を使用して現在のweb
ポッド内のターミナルを開き、人工的な負荷を作成します。 これは、ポッドに移動してstress
CLI toolをインストールすることで実現できます。
kubectl exec
を使用してポッドを入力し、強調表示されたポッド名をweb
ポッドの名前に置き換えます。
kubectl exec -it web-f765fd676-s9729 /bin/bash
このコマンドの概念は、ssh
を使用して別のマシンにログインするのと非常に似ています。 /bin/bash
は、ポッドにbashシェルを確立します。
次に、ポッド内のbashシェルから、リポジトリメタデータを更新し、stress
パッケージをインストールします。
apt update; apt-get install -y stress
[。注意]##
Note: CentOSベースのコンテナーの場合、これは次のようになります。
yum install -y stress
次に、stress
コマンドを使用してポッドにCPU負荷を生成し、実行させます。
stress -c 3
次に、2番目のターミナルでwatch
コマンドに戻ります。 Metrics ServerがHPAの定義済みのしきい値を超えるCPUデータを収集するまで数分待ちます。 メトリックは、デフォルトで、メトリックサーバーの構成時に--metric-resolution
を等しく設定したレートで収集されることに注意してください。 使用メトリックが更新されるまで、1分程度かかる場合があります。
約2分後、追加のweb
ポッドがスピンアップします。
OutputEvery 2.0s: kubectl top pods
NAME CPU(cores) MEMORY(bytes)
metrics-server-db745fcd5-v8gv6 6m 16Mi
web-555db5bf6b-ck98q 0m 2Mi
web-555db5bf6b-f7btr 494m 21Mi
web-555db5bf6b-h5cbx 0m 1Mi
web-555db5bf6b-pvh9f 0m 2Mi
これで、HPAがMetrics Serverによって収集されたCPU負荷に基づいて新しいポッドをスケジュールしたことがわかります。 この検証に満足したら、CTRL+C
を使用して最初のターミナルでstress
コマンドを停止し、ポッドのbashシェルを終了します。
結論
この記事では、CPU負荷に基づいて自動スケーリングするデプロイメントを作成しました。 CPUリソースの制限とリクエストをデプロイメントに追加し、Helmを使用してクラスターにMetrics Serverをインストールおよび構成し、スケーリングの決定を行うためにHPAを作成しました。
これは、Metrics ServerとHPAの両方のデモ展開です。 これで、特定のユースケースに合わせて構成を調整できます。 requests and limitationsのヘルプと情報については、必ずKubernetes HPAのドキュメントを調べてください。 また、Metrics Server projectを確認して、ユースケースに適用される可能性のあるすべての調整可能な設定を確認してください。
Kubernetesをさらに活用したい場合は、Kubernetes Community pageにアクセスするか、Managed Kubernetes serviceを調べてください。