コンテナに割り当てるCPUとメモリ容量を変更する
Kubernetes v1.27 [alpha]
(enabled by default: false)このページはQuality of Serviceに馴染みのある読者を前提としています。
このページでは、稼働中のPodやコンテナを再起動することなく、コンテナに割り当てられるCPUやメモリ容量を変更(リサイズ)するための方法を示します。
Kubernetesノードは、PodのContainerに指定したrequests
に基づいてPodにリソースを割り当て、limits
に基づいてPodのリソース使用量を制限します。
稼働中のPodのリソース割当を変更するには、 InPlacePodVerticalScaling
フィーチャーゲートを有効化する必要があります。
代替手法としては、Podを削除した上で、異なるリソース要求を有するPodをワークロードコントローラー に作成させることもできます。
稼働中のPodのリソースを変更するために
- Containerの
requests
とlimits
はCPUおよびメモリリソースに対して 可変 なものとなっています。 - Podステータスの
containerStatuses
におけるallocatedResources
フィールドは、PodのContainerに割り当てられたリソースを反映します。 - Podステータスの
containerStatuses
におけるresources
フィールドは、稼働中Containerに設定済みの実際のリソース要求(requests
)とリソース制限(limits
)を反映しており、これらの値はコンテナランタイムが通知したものです。 - Podステータスの
resize
フィールドは直前の適用待ちのリサイズ要求を示します。 このフィールドの値には次のようなものがあります。Proposed
: リサイズ要求の受理を表し、リクエストが検証済みかつ記録済み であることを示します。InProgress
: リサイズ要求がノードによって受理され、Podのコンテナに対する 適用が進行中であることを示します。Deferred
: リサイズ要求が現時点では通っていないことを示します。 他のPodが除去されてノードの資源が開放されたら、リサイズが承認されるかもしれません。Infeasible
: ノードがリサイズ要求に対応できないことを示すシグナルです。 Podに対してノードが割り当て可能なリソースの最大値を上回るリサイズ要求がある時に 発生する可能性があります。
始める前に
Kubernetesクラスターが必要、かつそのクラスターと通信するためにkubectlコマンドラインツールが設定されている必要があります。 このチュートリアルは、コントロールプレーンのホストとして動作していない少なくとも2つのノードを持つクラスターで実行することをおすすめします。 まだクラスターがない場合、minikubeを使って作成するか、 以下のいずれかのKubernetesプレイグラウンドも使用できます:
作業するKubernetesサーバーは次のバージョン以降のものである必要があります: 1.27. バージョンを確認するには次のコマンドを実行してください:kubectl version
.クラスターのコントロールプレーンを含む全ノードでInPlacePodVerticalScaling
フィーチャーゲートが有効化されている必要があります。
コンテナリサイズポリシー
リサイズポリシーはPodにおけるコンテナのCPUやメモリリソースを取り扱うためのきめ細かい制御を可能にします。 例えば、アプリケーションを再起動せずにコンテナのCPUリソースのリサイズを行える場合でも、メモリのリサイズについてはアプリケーションとコンテナの再起動が必要となる場合があります。
これを実現するために、ユーザーはContainerの仕様に resizePolicy
を指定できるようになっています。
以下の再起動ポリシーをCPUやメモリのリサイズの際に指定できます。
NotRequired
: 稼働中のコンテナリソースをリサイズします。RestartContainer
: コンテナを再起動させ、再起動時に新しいリソースを適用します。
resizePolicy[*].restartPolicy
が指定されない場合のデフォルトは、NotRequired
です。
備考:
PodのrestartPolicy
がNever
である場合、Podの全コンテナの再起動ポリシーがNotRequired
である必要があります。以下のPodの例は、ContainerのCPUのリサイズは再起動なしで実施させ、メモリのリサイズにはコンテナの再起動を要求するものです。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-5
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr-5
image: nginx
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
備考:
この例の requests ないしは limits が CPUとメモリの 両方を 変化させる場合、 メモリのリサイズが生じるので、コンテナは再起動します。リソース要求やリソース制限のあるPodを作成する
リソース要求やリソース制限をPodのコンテナに指定することで、保証(Guaranteed)ないしは バースト可能(Burstable)なQuality of ServiceクラスのPodを作成することができます。
次のような単一のコンテナを含むPodのマニフェストを考えてみましょう。
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-5
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr-5
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
Podをqos-example
Namespace に作成します。
kubectl create namespace qos-example
kubectl create -f https://k8s.io/examples/pods/qos/qos-pod-5.yaml
このPodは保証QoSクラスに区分され、700mのCPU、200Miのメモリを要求します。
Podの詳細な情報を見てみましょう。
kubectl get pod qos-demo-5 --output=yaml --namespace=qos-example
resizePolicy[*].restartPolicy
の値がデフォルトのNotRequired
になっていることに気づいたでしょうか。
これはCPUとメモリがコンテナ稼働中にリサイズできることを示しています。
spec:
containers:
...
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: NotRequired
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
...
containerStatuses:
...
name: qos-demo-ctr-5
ready: true
...
allocatedResources:
cpu: 700m
memory: 200Mi
resources:
limits:
cpu: 700m
memory: 200Mi
requests:
cpu: 700m
memory: 200Mi
restartCount: 0
started: true
...
qosClass: Guaranteed
Podのリソースを更新する
要求CPUを0.8CPUに増やしてみます。 これは手動でも指定できますし、VerticalPodAutoscaler(VPA)などを用いて自動的に検出/適用することもできます。
備考:
Podのリソース要求やリソース制限を変更して希望の容量に合わせることはできますが、Pod作成時に指定したQoSクラスを変更することはできません。PodのContainerのCPU要求とCPU制限をいずれも800m
に指定するパッチを当ててみます。
kubectl -n qos-example patch pod qos-demo-5 --patch '{"spec":{"containers":[{"name":"qos-demo-ctr-5", "resources":{"requests":{"cpu":"800m"}, "limits":{"cpu":"800m"}}}]}}'
Podへのパッチが当たったら、Podの詳細情報を参照してみましょう。
kubectl get pod qos-demo-5 --output=yaml --namespace=qos-example
以下のPod仕様は更新済みのCPU要求とCPU制限を反映しています。
spec:
containers:
...
resources:
limits:
cpu: 800m
memory: 200Mi
requests:
cpu: 800m
memory: 200Mi
...
containerStatuses:
...
allocatedResources:
cpu: 800m
memory: 200Mi
resources:
limits:
cpu: 800m
memory: 200Mi
requests:
cpu: 800m
memory: 200Mi
restartCount: 0
started: true
期待する新しいCPU要求を反映する形で allocatedResources
の値が更新されていることを確認しておきましょう。
これはノードがCPUリソースの追加要求に対応できたことを示しています。
Containerの状態においてはCPUリソースの値が更新されており、新しいCPUリソースが適用されたことを示しています。
ContainerのrestartCount
は変化しておらず、コンテナのCPUリソースがコンテナの再起動なしで変更されたことを示しています。
クリーンアップ
名前空間を削除しましょう。
kubectl delete namespace qos-example