Contents
CPU の単位と実体 – core と millicore(mCPU)の意味
Kubernetes が扱う CPU は「論理コア」を基準に 2 つの表記 が可能です。このセクションでは、両者の関係とクラウド/オンプレ環境での実体を整理します。
単位の概要
- 1 core(=
1) - クラウド:1 vCPU(ハイパースレッド)
-
ベアメタル:1 物理コアまたは SMT が有効な場合は 1 ハイパースレッド
-
1000m(=
1000 millicore、通称 mCPU) - 1 core の千分の一。たとえば
500mは 0.5 CPU に相当し、同ノード上で500mの Pod が 2 個あればちょうど 1 core を占有します。
ポイント:Kubernetes が内部的に扱うのは OS レベルの 論理 コアです。したがってクラウドベンダーが提供する vCPU と 1:1 に考えて問題ありません。
millicore(mCPU)の定義
| 表記例 | 意味 |
|---|---|
250m |
0.25 CPU |
0.25 |
同上(文字列でも可) |
"0.5" |
同上 |
計算式:1 core = 1000m → request: "250m" ⇔ 0.25 CPU
クラウドプロバイダーとベアメタルでの CPU 実体
Table 1: 各環境における 1 vCPU / 1 core の実装例
| 環境 | 1 vCPU(または 1 core)の実体 |
|---|---|
| AWS (EC2) | 1 vCPU = 1 ハイパースレッド(Intel Xeon・AMD EPYC) |
| GCP | 1 vCPU = 1 ハイパースレッド |
| Azure | 1 vCPU = 1 ハイパースレッド |
| ベアメタル (オンプレ) | 1 core = 1 物理コア(SMT 有効時はハイパースレッド) |
CPU request と limit の意味と動作原理
request と limit は、Pod が どれだけの CPU を確保できるか と 最大で使用できる上限 を分離して管理する仕組みです。ここではそれぞれが Kubernetes のどこで参照され、どのように制御されるかを解説します。
スケジューラが参照する request
Kubernetes のスケジューラは リクエスト合計 がノードの allocatable CPU に収まるかどうかで Pod 配置を決定します。
- 最低保証:
requestは「この量は必ず確保される」ことを意味し、過不足なく分散させることでスロットリングや OOM のリスクを低減します。 - 例:ノードの空き CPU が 4 CPU(4000m)であるとき、
request: "1500m"の Pod が 2 個入れば残りは 1000m になるため、次にrequest: "1200m"を持つ Pod はスケジューリングできません。
CFS quota による limit 制御
Linux の CFS (Completely Fair Scheduler) が cpu.cfs_quota_us / cpu.cfs_period_us で上限を設定し、Pod が limit 超過分の CPU を要求するとスロットリングが発生します。
- 実際の使用率:
kubectl topに表示される%CPUは CFS が許可した時間割合です。 - 例:
limit: "500m"のコンテナが 800 m の負荷を受けても、CFS が 300 m 分だけ待機させて実使用量は 500 m に抑えられます。
注意:
request ≤ limitが必須です。limitを過小に設定すると、予期しないスロットリングでサービス品質が低下します。
YAML での resources 設定例と kubectl 操作方法
Kubernetes のリソース指定は Pod 定義 の spec.containers[].resources に記述します。以下では実装例と、変更手順をベストプラクティスに沿って示します。
Pod/Container の resources フィールド記述例
Code 1: CPU・メモリの request / limit を明示したシンプルな Pod 定義
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
apiVersion: v1 kind: Pod metadata: name: cpu-demo spec: containers: - name: app image: nginx:stable resources: requests: cpu: "250m" # 0.25 CPU を保証 memory: "128Mi" limits: cpu: "500m" # 最大 0.5 CPU に制限 memory: "256Mi" |
- core 表記は
cpu: "1"、millicore 表記はcpu: "1000m"と書けます。 requestsが省略された場合はデフォルトで0となり、QoS は BestEffort に分類されます。
既存リソース変更のベストプラクティス
Pod 自体に対して直接 kubectl set resources pod … を実行すると、Pod が再作成される(削除→新規作成) ため一時的にダウンタイムが発生します。実運用では Deployment / StatefulSet のような上位オブジェクトを対象に変更し、ローリングアップデートで安全に反映させます。
1. Deployment に対してリソースを更新する例
|
1 2 3 4 5 |
# 既存 deployment を取得(例: cpu-demo-deploy) kubectl set resources deployment cpu-demo-deploy \ --limits=cpu=600m,memory=300Mi \ --requests=cpu=300m,memory=150Mi |
Code 2:
set resourcesが Deployment に適用できることを示すコマンド例
この操作は Deployment の Pod テンプレートを書き換えるだけなので、ローリング再起動 が自動的に行われ、サービス停止時間が最小化されます。
2. 手動で Pod を編集する場合(テストや緊急対応向け)
|
1 2 |
kubectl edit pod cpu-demo # エディタが開くので resources セクションを修正 |
編集後、Kubelet が変更を検知して Pod の再起動 が走ります。実運用では上記のように上位オブジェクトで管理することを推奨します。
3. 設定内容の確認
|
1 2 |
kubectl get pod cpu-demo -o yaml | grep -A5 resources |
CPU Manager Policy と専有 CPU(exclusive core)の割り当て手順
CPU の 物理的な専有 が必要になるシナリオ(リアルタイム処理、HPC、GPU 併用など)では、Kubelet の cpu-manager-policy を static に設定します。
ポリシー比較表
Table 2: none と static の挙動の違い
| ポリシー | 主な目的 | 整数コアの専有可否 |
|---|---|---|
none (デフォルト) |
柔軟に共有スケジューリング | ×(CFS による制御のみ) |
static |
整数コア単位で 専有 させる | ○(NUMA も考慮可能) |
static ポリシー導入手順
- kubelet 起動オプションに追記(systemd 環境を想定)
bash
# /etc/systemd/system/kubelet.service.d/10-extra-args.conf
[Service]
Environment="KUBELET_EXTRA_ARGS=--cpu-manager-policy=static --cpu-manager-reconcile-period=5s"
- kubelet を再起動
bash
systemctl daemon-reload
systemctl restart kubelet
- Node が整数コアを確保できるか確認
bash
kubectl get node $(kubectl get nodes -o name | head -n1) -o jsonpath='{.status.allocatable.cpu}'
# 例: "8"(8 cores) → static ポリシーが有効になる条件を満たす
- Pod 定義で整数 core を request に指定
yaml
apiVersion: v1
kind: Pod
metadata:
name: exclusive-cpu-pod
spec:
containers:
- name: cpu-bound
image: busybox
command: ["sh", "-c", "while true; do echo hi; sleep 5; done"]
resources:
requests:
cpu: "2" # 整数 core → 2 専有 CPU が割り当てられる
limits:
cpu: "2"
- 専有 CPU の割り当て状況を確認
bash
kubectl get pod exclusive-cpu-pod -o jsonpath='{.status.containerStatuses[0].allocatedResources.cpu}'
# 出力例: 2
ポイント:
staticポリシーは Node の allocatable CPU が整数であること が前提です。余剰が少ないノードではスケジューリングできなくなるため、事前にkubectl describe node <node>で残容量を確認してください。
ローカル環境(minikube / Kind)での CPU リソース検証ガイド
ローカルクラスターは設定ミスやリソース競合を安全に検証できるため、開発・学習フェーズで必ず使うべき基盤です。ここでは minikube と Kind の具体的な手順とサンプル設定ファイルを示します。
Kind 用クラスター設定例
Code 3: 4 CPU、2 GiB メモリのシングルノード Kind クラスタ定義(kind-config.yaml)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# kind-config.yaml kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane extraPortMappings: [] # 必要に応じてポート公開を追加 kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: cpu-manager-policy: "static" # static ポリシーをローカルでもテスト可能 extraMounts: [] # ボリュームマウントは不要なので省略 # CPU とメモリの割り当て(Kind はデフォルトでホストのリソースを共有) # 以下は Docker の run オプションに相当します。 # 例: `docker run --cpus=4 --memory=2g ...` extraRuntimeConfig: "system-reserved": "cpu=500m,memory=256Mi" |
|
1 2 3 |
# クラスタ作成コマンド kind create cluster --config=kind-config.yaml |
Code 4:
kindが自動的に CPU を割り当てる仕組みの補足説明
デプロイとモニタリング手順(共通)
- リソース定義をデプロイ
bash
kubectl apply -f cpu-demo.yaml
- Metrics Server のインストール(未導入の場合)
bash
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
- CPU 使用率の取得
bash
kubectl top pod cpu-demo
# 出力例:
# NAME CPU(cores) MEMORY(bytes)
# cpu-demo 0.12 130Mi
- リソース変更をロールアウトで反映(Deployment が前提)
bash
kubectl set resources deployment cpu-demo-deploy --requests=cpu=300m --limits=cpu=600m
QoS クラス別ベストプラクティスとトラブルシュート
Kubernetes は QoS (Quality of Service) クラス によって Pod の優先順位を決定します。各クラスの特徴と、実務で陥りやすいミス・対処法をまとめました。
QoS クラス概要
| クラス | 条件 | 特徴 |
|---|---|---|
| Guaranteed | 全コンテナが requests == limits かつ両方指定 |
最も高優先度。CPU が逼迫してもスロットリングされにくい |
| Burstable | request < limit(どちらかが未指定でも可) |
基本的に request 分だけ保証、余剰リソースがあれば上限まで利用可能 |
| BestEffort | requests と limits が未設定 |
最低優先度。ノード逼迫時は最初に削除対象となる |
ベストプラクティス:ミッションクリティカルでないワークロードは Burstable に統一し、
requestは実測負荷の 70 % 前後に抑えると資源効率が向上します。
よくある設定ミスと対処法
Table 3: 代表的な症状とその解決手順
| 症状 | 主な原因 | 修正例 |
|---|---|---|
| Pod が起動しない | limit が request 未満 |
requests.cpu: "500m" → limits.cpu: "500m" に統一 |
kubectl top が 0 m を表示 |
Metrics Server が未導入、または cAdvisor 無効 | minikube addons enable metrics-server または kind load docker-image metrics-server |
| CPU 使用率が期待より低い | request が過大設定で余剰リソースが確保されすぎ |
実測データに基づき request を 70 % 程度に削減 |
mCPU の桁数エラー(例: "12000m") |
Kubernetes は 1 core = 1000m が上限。超過はエラーになる | cpu: "12" と整数で指定、または 12000m → 12 に分割 |
対処フロー
kubectl describe pod <name>でイベントとスケジューラのメッセージを確認- YAML の
resourcesセクションを見直し、request ≤ limitを保証 - 必要に応じて Node の CPU 割当(
minikube start --cpus=...や Kind のextraRuntimeConfig)を増やす
まとめ
- CPU 単位は
1 core = 1000m。millicore は細かいリソース調整に必須です。 - requestはスケジューラが参照する最低保証、limitは CFS が実行時に強制する上限です。
request ≤ limitを常に守りましょう。 - YAML と
kubectl set resourcesによる変更は、Deployment など上位オブジェクトで行うと安全です。Pod 直接の変更は再作成が伴います。 - CPU Manager の static ポリシーを有効化すると整数コアを専有でき、リアルタイム処理や HPC に最適です。ただし Node の allocatable が整数であることを事前に確認してください。
- ローカル環境(minikube / Kind)では
kind-config.yamlを用意して CPU 制限・static ポリシーの挙動を手軽に検証できます。kubectl topで実際の使用率を観測し、QoS クラス別のベストプラクティスに沿って設定すれば、過剰予約やスロットリングを防げます。
上記手順とサンプルを自分のクラスターへ適用し、kubectl top でリソース使用率を確認すれば、CPU 設定が正しく機能していることを即座に検証できます。公式ドキュメント(https://kubernetes.io/ja/docs/tasks/configure-pod-container/assign-cpu-resource/)も合わせて参照し、環境ごとの微妙な差異に注意しながら運用してください。