- Authors
- Name
- はじめに
- VPAとは?
- VPAのインストール
- 基本的なVPA設定
- In-Place Pod Resizeの有効化(Kubernetes 1.35+)
- リサイズ過程のモニタリング
- 本番環境のベストプラクティス
- トラブルシューティング
- 実践例:JavaアプリへのVPA適用
- まとめ

はじめに
Kubernetesでワークロードのリソースを自動調整するVertical Pod Autoscaler(VPA)には、長年「Podを再起動しなければならない」という致命的な欠点がありました。しかし、Kubernetes 1.35(2025年12月)でIn-Place Pod ResizeがGAに昇格したことで、ついに再起動なしでCPU/メモリをリアルタイム調整できるようになりました。
この記事では、VPAの基本概念からIn-Place Resizerとの連携、本番デプロイ戦略まで、段階的に解説します。
VPAとは?
VPA(Vertical Pod Autoscaler)は、PodのCPU/メモリのrequestsとlimitsを自動調整するKubernetesコンポーネントです。
HPA vs VPA
| 区分 | HPA | VPA |
|---|---|---|
| スケーリング方向 | 水平(Pod数の増減) | 垂直(リソースサイズの調整) |
| 適したワークロード | Statelessサービス | Stateful、シングルインスタンス |
| ダウンタイム | なし | 従来:再起動必要 → 1.35+:なし |
VPAの構成要素
VPAは3つのコンポーネントで構成されます:
# 1. Recommender: リソース使用量を分析し、推奨値を計算
# 2. Updater: 推奨値に基づいてPodの更新をトリガー
# 3. Admission Controller: 新しく作成されるPodに推奨値を適用
VPAのインストール
Helmでインストール
# VPA Helm chartの追加
helm repo add fairwinds-stable https://charts.fairwinds.com/stable
helm repo update
# VPAのインストール
helm install vpa fairwinds-stable/vpa \
--namespace vpa-system \
--create-namespace \
--set recommender.enabled=true \
--set updater.enabled=true \
--set admissionController.enabled=true
# インストール確認
kubectl get pods -n vpa-system
手動インストール(公式リポジトリ)
git clone https://github.com/kubernetes/autoscaler.git
cd autoscaler/vertical-pod-autoscaler
# CRDとコンポーネントのインストール
./hack/vpa-up.sh
# 確認
kubectl get customresourcedefinitions | grep verticalpodautoscaler
基本的なVPA設定
VPAリソースの作成
# vpa-nginx.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: nginx-vpa
namespace: default
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: nginx-deployment
updatePolicy:
updateMode: 'Auto' # Off, Initial, Recreate, Auto
resourcePolicy:
containerPolicies:
- containerName: nginx
minAllowed:
cpu: '50m'
memory: '64Mi'
maxAllowed:
cpu: '2'
memory: '2Gi'
controlledResources: ['cpu', 'memory']
controlledValues: RequestsAndLimits
kubectl apply -f vpa-nginx.yaml
# VPA推奨値の確認
kubectl get vpa nginx-vpa -o yaml
updateModeオプションの比較
# Off: 推奨値のみ提供、自動更新なし(モニタリング用)
updateMode: "Off"
# Initial: Pod作成時のみ推奨値を適用
updateMode: "Initial"
# Recreate: 推奨値が変更されるとPodを再作成
updateMode: "Recreate"
# Auto: 最適な方法を自動選択(1.35+ではIn-Placeを含む)
updateMode: "Auto"
# InPlaceOrRecreate: In-Place優先、不可能な場合は再作成(1.35+ Beta)
updateMode: "InPlaceOrRecreate"
In-Place Pod Resizeの有効化(Kubernetes 1.35+)
Feature Gateの確認
Kubernetes 1.35以降、In-Place Pod Resizeはデフォルトで有効です:
# クラスターバージョンの確認
kubectl version --short
# Feature gateの状態確認(1.35+ではデフォルトtrue)
kubectl get --raw /api/v1/nodes | jq '.items[0].status.features'
resizePolicyの設定
PodがIn-Place ResizeをサポートするにはresizePolicyを明示する必要があります:
# deployment-with-resize.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.27
resources:
requests:
cpu: '100m'
memory: '128Mi'
limits:
cpu: '500m'
memory: '512Mi'
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # CPUは再起動なしで調整
- resourceName: memory
restartPolicy: NotRequired # メモリも再起動なしで調整
kubectl apply -f deployment-with-resize.yaml
VPA + InPlaceOrRecreate連携
# vpa-inplace.yaml
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
updatePolicy:
updateMode: 'InPlaceOrRecreate'
minReplicas: 2 # 最小維持レプリカ数
resourcePolicy:
containerPolicies:
- containerName: web
minAllowed:
cpu: '50m'
memory: '64Mi'
maxAllowed:
cpu: '4'
memory: '4Gi'
controlledResources: ['cpu', 'memory']
kubectl apply -f vpa-inplace.yaml
# In-Place resizeの発生を確認
kubectl get pods -w
# STATUSがRunningを維持したままresourcesが変更される
リサイズ過程のモニタリング
Podリソース変更の確認
# Podの現在のリソースを確認
kubectl get pod web-app-xxx -o jsonpath='{.spec.containers[0].resources}'
# allocated resourcesの確認(実際に割り当てられたリソース)
kubectl get pod web-app-xxx -o jsonpath='{.status.containerStatuses[0].allocatedResources}'
# resizeステータスの確認
kubectl get pod web-app-xxx -o jsonpath='{.status.resize}'
# "InProgress", "Proposed", "Deferred", ""(完了)
VPA推奨値モニタリングスクリプト
#!/bin/bash
# watch-vpa.sh - VPA推奨値のリアルタイムモニタリング
VPA_NAME=${1:-web-app-vpa}
NAMESPACE=${2:-default}
while true; do
echo "=== $(date) ==="
kubectl get vpa $VPA_NAME -n $NAMESPACE -o jsonpath='
Target:
CPU: {.status.recommendation.containerRecommendations[0].target.cpu}
Memory: {.status.recommendation.containerRecommendations[0].target.memory}
Lower Bound:
CPU: {.status.recommendation.containerRecommendations[0].lowerBound.cpu}
Memory: {.status.recommendation.containerRecommendations[0].lowerBound.memory}
Upper Bound:
CPU: {.status.recommendation.containerRecommendations[0].upperBound.cpu}
Memory: {.status.recommendation.containerRecommendations[0].upperBound.memory}
'
echo ""
sleep 30
done
Prometheusメトリクス
# VPA関連の主要メトリクス
# kube_verticalpodautoscaler_status_recommendation_target
# vpa_recommender_recommendation_latency
# vpa_updater_evictions_total
# Pod CPU推奨値 vs 実際の使用量
rate(container_cpu_usage_seconds_total[5m])
# vs
kube_verticalpodautoscaler_status_recommendation_target{resource="cpu"}
本番環境のベストプラクティス
1. 段階的な導入戦略
# Step 1: Offモードで推奨値のみ観察(1〜2週間)
updateMode: "Off"
# Step 2: Initialモードで新しいPodにのみ適用
updateMode: "Initial"
# Step 3: InPlaceOrRecreateで自動調整
updateMode: "InPlaceOrRecreate"
2. PDB(PodDisruptionBudget)との併用
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
name: web-app-pdb
spec:
minAvailable: 2
selector:
matchLabels:
app: web-app
---
# VPAはRecreateフォールバック時にPDBを尊重
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
updatePolicy:
updateMode: 'InPlaceOrRecreate'
minReplicas: 2
evictionRequirements:
- resources: ['cpu', 'memory']
changeRequirement: TargetHigherThanRequests
3. HPAとVPAの同時使用
# HPA: CPUベースの水平スケーリング
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: web-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
# VPA: メモリのみの垂直スケーリング(CPUはHPAが管理)
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: web-app-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: web-app
updatePolicy:
updateMode: 'InPlaceOrRecreate'
resourcePolicy:
containerPolicies:
- containerName: web
controlledResources: ['memory']
minAllowed:
memory: '128Mi'
maxAllowed:
memory: '4Gi'
4. GoldilocksでVPA推奨値を可視化
# Goldilocksのインストール(VPA推奨値ダッシュボード)
helm install goldilocks fairwinds-stable/goldilocks \
--namespace goldilocks \
--create-namespace
# ネームスペースでGoldilocksを有効化
kubectl label namespace default goldilocks.fairwinds.com/enabled=true
# ダッシュボードにアクセス
kubectl port-forward -n goldilocks svc/goldilocks-dashboard 8080:80
トラブルシューティング
In-Place Resizeが動作しない場合
# 1. Kubernetesバージョンの確認
kubectl version --short
# 1.35+が必要
# 2. ノードのContainer Runtimeの確認
kubectl get nodes -o jsonpath='{.items[*].status.nodeInfo.containerRuntimeVersion}'
# containerd 1.7+またはCRI-O 1.29+が必要
# 3. PodのresizePolicyの確認
kubectl get pod <pod-name> -o jsonpath='{.spec.containers[0].resizePolicy}'
# 4. resizeステータスの確認
kubectl get pod <pod-name> -o jsonpath='{.status.resize}'
# "Deferred" -> ノードにリソース不足
# "Infeasible" -> ノードがresizeをサポートしていない
# 5. イベントの確認
kubectl describe pod <pod-name> | grep -A5 "Events"
VPAが推奨値を生成しない場合
# VPA Recommenderのログ確認
kubectl logs -n vpa-system -l app=vpa-recommender --tail=50
# metrics-serverの動作確認
kubectl top pods
# VPAステータスの確認
kubectl describe vpa <vpa-name>
実践例:JavaアプリへのVPA適用
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-app
spec:
replicas: 3
selector:
matchLabels:
app: spring-boot
template:
metadata:
labels:
app: spring-boot
spec:
containers:
- name: app
image: myregistry/spring-boot-app:latest
resources:
requests:
cpu: '500m'
memory: '512Mi'
limits:
cpu: '2'
memory: '2Gi'
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired
- resourceName: memory
restartPolicy: RestartContainer # JVMはヒープの再設定が必要
env:
- name: JAVA_OPTS
value: '-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0'
---
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: spring-boot-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: spring-boot-app
updatePolicy:
updateMode: 'InPlaceOrRecreate'
resourcePolicy:
containerPolicies:
- containerName: app
minAllowed:
cpu: '200m'
memory: '256Mi'
maxAllowed:
cpu: '4'
memory: '4Gi'
まとめ
Kubernetes 1.35のIn-Place Pod Resize GAとVPAのInPlaceOrRecreateモードは、本番環境でのリソース最適化を次のレベルに引き上げます。重要なポイント:
- In-Place ResizeでPod再起動なしにCPU/メモリを調整可能
- VPA + InPlaceOrRecreateで自動化された垂直スケーリング
- HPAとVPAの併用時は管理リソースを分離(HPA=CPU、VPA=Memory)
- 段階的な導入:Off → Initial → InPlaceOrRecreate
クイズ(5問)
Q1. VPAの3つの構成要素は? Recommender、Updater、Admission Controller
Q2. In-Place Pod ResizeがGAになったKubernetesバージョンは? Kubernetes 1.35(2025年12月)
Q3. VPAのupdateModeのうち、推奨値のみ提供し自動更新しないモードは? Off
Q4. HPAとVPAを同時に使用する際に推奨されるリソースの分離方法は? HPAがCPUベースの水平スケーリング、VPAがメモリのみの垂直スケーリング
Q5. JVMベースのアプリでメモリのIn-Place Resize時にrestartPolicyをRestartContainerに設定する理由は? JVMがヒープメモリを動的に再設定する必要があるため、コンテナの再起動が必要