EKS 1.33 が利用できるようになったので、In-Place Pod Resource Resize を試してみた
こんにちは。クラウド事業本部の枡川です。
EKS において Kubernetes v1.33 を利用できるようになりました。
アップデート内容を見てみる
Kubernetes v1.33 のアップデートとして、In-Place Update of Pod Resources が Beta になったというものがあります。
In-Place Pod Resource Resize (Beta): In-place resource resize has been promoted to beta, allowing dynamic updates to CPU and memory resources for existing Pods without restarts - enabling vertical scaling of stateful workloads with zero downtime and seamless resource adjustments based on traffic patterns.
ステートフルなリソースかつ Pod の再起動を許容できない場合でも必要に応じて垂直スケールすることができる機能です。
また、CPU の limits/requests やメモリの requests についてはスケールインも可能なので、起動時のみ一時的に大きなリソースを割り当てておくような運用も可能です。
Memory limits cannot be decreased unless the resizePolicy for memory is RestartContainer. Memory requests can generally be decreased.
https://kubernetes.io/docs/tasks/configure-pod-container/resize-container-resources/#limitations
メモリの limits を減少させることについては OOM killer の可能性を考えての制限ですが、今後のバージョンアップで可能にする方向のようです。
合わせて Dynamic Resource Allocation も有効化されています。
こちらは 1.32 で beta になった機能ですが、EKS では有効化されていませんでした。
GPU などの特殊なハードウェアを複数の Pod に柔軟に割り当てるための機能になります。
その他、 EKS 最適化 AMI が EKS 1.33 以降では公開されないことは注意が必要です。
Amazon Linux 2023 ベースのものは引き続き公開されているので、そちらを利用したり Bottlerocket を使うのが良いでしょう。
In-Place Update of Pod Resources を使ってみる
下記 Kubernetes 公式ドキュメントに沿って EKS で試してみます。
まず、eksctl で EKS クラスターを作成します。
v1.33 を選択し、非 Auto Mode とします。
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: test-cluster
region: ap-northeast-1
version: "1.33"
iam:
withOIDC: true
vpc:
clusterEndpoints:
publicAccess: true
privateAccess: true
cloudWatch:
clusterLogging:
enableTypes:
- "audit"
- "authenticator"
- "controllerManager"
- "scheduler"
managedNodeGroups:
- name: node-group-al2023
amiFamily: AmazonLinux2023
instanceTypes:
- t3.medium
maxSize: 1
minSize: 1
desiredCapacity: 1
privateNetworking: true
volumeType: gp3
volumeSize: 50
autoModeConfig:
enabled: false
addons:
- name: eks-pod-identity-agent
version: latest
- name: vpc-cni
version: latest
useDefaultPodIdentityAssociations: true
- name: coredns
version: latest
- name: kube-proxy
version: latest
create cluster
コマンドを実行します。
% eksctl create cluster -f cluster.yaml
2025-05-31 18:30:41 [ℹ] eksctl version 0.208.0
2025-05-31 18:30:41 [ℹ] using region ap-northeast-1
2025-05-31 18:30:42 [ℹ] setting availability zones to [ap-northeast-1d ap-northeast-1c ap-northeast-1a]
2025-05-31 18:30:42 [ℹ] subnets for ap-northeast-1d - public:192.168.0.0/19 private:192.168.96.0/19
2025-05-31 18:30:42 [ℹ] subnets for ap-northeast-1c - public:192.168.32.0/19 private:192.168.128.0/19
2025-05-31 18:30:42 [ℹ] subnets for ap-northeast-1a - public:192.168.64.0/19 private:192.168.160.0/19
2025-05-31 18:30:42 [ℹ] nodegroup "node-group-al2023" will use "" [AmazonLinux2023/1.33]
2025-05-31 18:30:42 [ℹ] using Kubernetes version 1.33
2025-05-31 18:30:42 [ℹ] creating EKS cluster "test-cluster" in "ap-northeast-1" region with managed nodes
2025-05-31 18:30:42 [ℹ] 1 nodegroup (node-group-al2023) was included (based on the include/exclude rules)
2025-05-31 18:30:42 [ℹ] will create a CloudFormation stack for cluster itself and 1 managed nodegroup stack(s)
2025-05-31 18:30:42 [ℹ] if you encounter any issues, check CloudFormation console or try 'eksctl utils describe-stacks --region=ap-northeast-1 --cluster=test-cluster'
2025-05-31 18:30:42 [ℹ] Kubernetes API endpoint access will use provided values {publicAccess=true, privateAccess=true} for cluster "test-cluster" in "ap-northeast-1"
2025-05-31 18:30:42 [ℹ] configuring CloudWatch logging for cluster "test-cluster" in "ap-northeast-1" (enabled types: audit, authenticator, controllerManager, scheduler & disabled types: api)
2025-05-31 18:30:42 [ℹ] default addons metrics-server were not specified, will install them as EKS addons
2025-05-31 18:30:42 [ℹ]
2 sequential tasks: { create cluster control plane "test-cluster",
2 sequential sub-tasks: {
5 sequential sub-tasks: {
1 task: { create addons },
wait for control plane to become ready,
associate IAM OIDC provider,
no tasks,
update VPC CNI to use IRSA if required,
},
create managed nodegroup "node-group-al2023",
}
}
2025-05-31 18:30:42 [ℹ] building cluster stack "eksctl-test-cluster-cluster"
2025-05-31 18:30:42 [ℹ] deploying stack "eksctl-test-cluster-cluster"
2025-05-31 18:31:12 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:31:42 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:32:42 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:33:43 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:34:44 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:35:44 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:36:44 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:37:44 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:38:45 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:39:45 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:40:45 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-cluster"
2025-05-31 18:40:47 [ℹ] creating addon: eks-pod-identity-agent
2025-05-31 18:40:48 [ℹ] successfully created addon: eks-pod-identity-agent
2025-05-31 18:40:48 [ℹ] "addonsConfig.autoApplyPodIdentityAssociations" is set to true; will lookup recommended pod identity configuration for "vpc-cni" addon
2025-05-31 18:40:48 [ℹ] deploying stack "eksctl-test-cluster-addon-vpc-cni-podidentityrole-aws-node"
2025-05-31 18:40:48 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-addon-vpc-cni-podidentityrole-aws-node"
2025-05-31 18:41:18 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-addon-vpc-cni-podidentityrole-aws-node"
2025-05-31 18:41:19 [ℹ] creating addon: vpc-cni
2025-05-31 18:41:20 [ℹ] successfully created addon: vpc-cni
2025-05-31 18:41:21 [ℹ] creating addon: coredns
2025-05-31 18:41:21 [ℹ] successfully created addon: coredns
2025-05-31 18:41:21 [ℹ] creating addon: kube-proxy
2025-05-31 18:41:22 [ℹ] successfully created addon: kube-proxy
2025-05-31 18:41:22 [ℹ] creating addon: metrics-server
2025-05-31 18:41:22 [ℹ] successfully created addon: metrics-server
2025-05-31 18:43:25 [ℹ] addon "vpc-cni" active
2025-05-31 18:43:26 [ℹ] updating IAM resources stack "eksctl-test-cluster-addon-vpc-cni-podidentityrole-aws-node" for pod identity association "a-bnzlafltvfmhfyccq"
2025-05-31 18:43:27 [ℹ] waiting for CloudFormation changeset "eksctl--aws-node-update-1748684606" for stack "eksctl-test-cluster-addon-vpc-cni-podidentityrole-aws-node"
2025-05-31 18:43:27 [ℹ] nothing to update
2025-05-31 18:43:27 [ℹ] IAM resources for aws-node (pod identity association ID: a-bnzlafltvfmhfyccq) are already up-to-date
2025-05-31 18:43:27 [ℹ] updating addon
2025-05-31 18:43:38 [ℹ] addon "vpc-cni" active
2025-05-31 18:43:38 [ℹ] building managed nodegroup stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:43:39 [ℹ] deploying stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:43:39 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:44:10 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:44:51 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:45:43 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:47:04 [ℹ] waiting for CloudFormation stack "eksctl-test-cluster-nodegroup-node-group-al2023"
2025-05-31 18:47:04 [ℹ] waiting for the control plane to become ready
2025-05-31 18:47:04 [✔] saved kubeconfig as "/Users/masukawa.kentaro/.kube/config"
2025-05-31 18:47:04 [ℹ] no tasks
2025-05-31 18:47:04 [✔] all EKS cluster resources for "test-cluster" have been created
2025-05-31 18:47:05 [ℹ] nodegroup "node-group-al2023" has 1 node(s)
2025-05-31 18:47:05 [ℹ] node "ip-192-168-109-90.ap-northeast-1.compute.internal" is ready
2025-05-31 18:47:05 [ℹ] waiting for at least 1 node(s) to become ready in "node-group-al2023"
2025-05-31 18:47:05 [ℹ] nodegroup "node-group-al2023" has 1 node(s)
2025-05-31 18:47:05 [ℹ] node "ip-192-168-109-90.ap-northeast-1.compute.internal" is ready
2025-05-31 18:47:05 [✔] created 1 managed nodegroup(s) in cluster "test-cluster"
2025-05-31 18:47:06 [ℹ] kubectl command should work with "/Users/masukawa.kentaro/.kube/config", try 'kubectl get nodes'
2025-05-31 18:47:06 [✔] EKS cluster "test-cluster" in "ap-northeast-1" region is ready
各バージョンは下記のようになります。
% kubectl version
Client Version: v1.33.1
Kustomize Version: v5.6.0
Server Version: v1.33.1-eks-7308294
Kubernetes 公式ドキュメント で紹介されているマニフェストを適用します。
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.8
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Default, but explicit here
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
CPU は limits/requests ともに 700m になっていることを Containers.pause.Limits/Requests
から確認できます。
% kubectl describe pod resize-demo
Name: resize-demo
Namespace: default
Priority: 0
Service Account: default
Node: ip-192-168-109-90.ap-northeast-1.compute.internal/192.168.109.90
Start Time: Sat, 31 May 2025 22:37:59 +0900
Labels: <none>
Annotations: <none>
Status: Running
IP: 192.168.108.83
IPs:
IP: 192.168.108.83
Containers:
pause:
Container ID: containerd://dc68922bfca7e6fe3f26c71e8c15cd3d4e7c49f01744a8a6a7008445e34c662f
Image: registry.k8s.io/pause:3.8
Image ID: registry.k8s.io/pause@sha256:9001185023633d17a2f98ff69b6ff2615b8ea02a825adffa40422f51dfdcde9d
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 31 May 2025 22:38:01 +0900
Ready: True
Restart Count: 0
Limits:
cpu: 700m
memory: 200Mi
Requests:
cpu: 700m
memory: 200Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hd8qh (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-hd8qh:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
Optional: false
DownwardAPI: true
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 14s default-scheduler Successfully assigned default/resize-demo to ip-192-168-109-90.ap-northeast-1.compute.internal
Normal Pulling 13s kubelet Pulling image "registry.k8s.io/pause:3.8"
Normal Pulled 12s kubelet Successfully pulled image "registry.k8s.io/pause:3.8" in 1.268s (1.268s including waiting). Image size: 311286 bytes.
Normal Created 12s kubelet Created container: pause
Normal Started 12s kubelet Started container pause
下記コマンドを実行して、垂直スケールします。
この際、--subresource resize
オプションが必要になります。
% kubectl patch pod nginx-6cc5dc7978-pdj42 --subresource resize --patch '{"spec":{"containers":[{"name":"nginx", "resources":{"requests":{"cpu":"0.5","memory":"512Mi"}, "limits":{"cpu":"1","memory":"1024Mi"}}}]}}'
pod/nginx-6cc5dc7978-pdj42 patched
同じ Pod のまま、CPU の limits/requests が 800m になりました。
良い感じです。
% kubectl describe pod resize-demo
Name: resize-demo
Namespace: default
Priority: 0
Service Account: default
Node: ip-192-168-109-90.ap-northeast-1.compute.internal/192.168.109.90
Start Time: Sat, 31 May 2025 22:37:59 +0900
Labels: <none>
Annotations: <none>
Status: Running
IP: 192.168.108.83
IPs:
IP: 192.168.108.83
Containers:
pause:
Container ID: containerd://dc68922bfca7e6fe3f26c71e8c15cd3d4e7c49f01744a8a6a7008445e34c662f
Image: registry.k8s.io/pause:3.8
Image ID: registry.k8s.io/pause@sha256:9001185023633d17a2f98ff69b6ff2615b8ea02a825adffa40422f51dfdcde9d
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 31 May 2025 22:38:01 +0900
Ready: True
Restart Count: 0
Limits:
cpu: 800m
memory: 200Mi
Requests:
cpu: 800m
memory: 200Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hd8qh (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-hd8qh:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
Optional: false
DownwardAPI: true
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 2m18s default-scheduler Successfully assigned default/resize-demo to ip-192-168-109-90.ap-northeast-1.compute.internal
Normal Pulling 2m17s kubelet Pulling image "registry.k8s.io/pause:3.8"
Normal Pulled 2m16s kubelet Successfully pulled image "registry.k8s.io/pause:3.8" in 1.268s (1.268s including waiting). Image size: 311286 bytes.
Normal Created 2m16s kubelet Created container: pause
Normal Started 2m16s kubelet Started container pause
--subresource resize
オプションを省いて実行すると In-Place Update of Pod Resources を使わないので、requests/limits を変更できませんと怒られます。
% kubectl patch pod resize-demo --patch '{"spec":{"containers":[{"name":"pause", "resources":{"requests":{"cpu":"900m"}, "limits":{"cpu":"900m"}}}]}}'
The Pod "resize-demo" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.containers[*].image`,`spec.initContainers[*].image`,`spec.activeDeadlineSeconds`,`spec.tolerations` (only additions to existing tolerations),`spec.terminationGracePeriodSeconds` (allow it to be set to 1 if it was previously negative)
core.PodSpec{
Volumes: {{Name: "kube-api-access-hd8qh", VolumeSource: {Projected: &{Sources: {{ServiceAccountToken: &{ExpirationSeconds: 3607, Path: "token"}}, {ConfigMap: &{LocalObjectReference: {Name: "kube-root-ca.crt"}, Items: {{Key: "ca.crt", Path: "ca.crt"}}}}, {DownwardAPI: &{Items: {{Path: "namespace", FieldRef: &{APIVersion: "v1", FieldPath: "metadata.namespace"}}}}}}, DefaultMode: &420}}}},
InitContainers: nil,
Containers: []core.Container{
{
... // 6 identical fields
EnvFrom: nil,
Env: nil,
Resources: core.ResourceRequirements{
Limits: core.ResourceList{
- s"cpu": {i: resource.int64Amount{value: 800, scale: -3}, s: "800m", Format: "DecimalSI"},
+ s"cpu": {i: resource.int64Amount{value: 900, scale: -3}, s: "900m", Format: "DecimalSI"},
s"memory": {i: {...}, Format: "BinarySI"},
},
Requests: core.ResourceList{
- s"cpu": {i: resource.int64Amount{value: 800, scale: -3}, s: "800m", Format: "DecimalSI"},
+ s"cpu": {i: resource.int64Amount{value: 900, scale: -3}, s: "900m", Format: "DecimalSI"},
s"memory": {i: {...}, Format: "BinarySI"},
},
Claims: nil,
},
ResizePolicy: {{ResourceName: s"cpu", RestartPolicy: "NotRequired"}, {ResourceName: s"memory", RestartPolicy: "RestartContainer"}},
RestartPolicy: nil,
... // 13 identical fields
},
},
EphemeralContainers: nil,
RestartPolicy: "Always",
... // 29 identical fields
}
監査ログには requestURI
が /api/v1/namespaces/default/pods/resize-demo/resize?fieldManager=kubectl-patch
として記録されます。
※ --subresource
オプションを付けない場合は /api/v1/namespaces/default/pods/resize-demo
へのリクエストになります。
In-Place Update of Pod Resources では Pod そのものの更新ではなく、プロパティに対する変更をリクエストしていることがここからも読み取れます。
{
"kind": "Event",
"apiVersion": "audit.k8s.io/v1",
"level": "RequestResponse",
"auditID": "37fc06a2-5c62-4550-8843-646d09de1dbb",
"stage": "ResponseComplete",
"requestURI": "/api/v1/namespaces/default/pods/resize-demo/resize?fieldManager=kubectl-patch",
"verb": "patch",
"user": {
"username": "arn:aws:sts::xxxxxxxxxxxx:assumed-role/AWSReservedSSO_AdministratorAccess_xxxxxxxxxxxx/masukawa",
"uid": "aws-iam-authenticator:xxxxxxxxxxxx:xxxxxxxxxxxx",
"groups": ["system:authenticated"],
"extra": {
"accessKeyId": ["xxxxxxxxxxxx"],
"arn": [
"arn:aws:sts::xxxxxxxxxxxx:assumed-role/AWSReservedSSO_AdministratorAccess_xxxxxxxxxxxx/masukawa"
],
"canonicalArn": [
"arn:aws:iam::xxxxxxxxxxxx:role/AWSReservedSSO_AdministratorAccess_xxxxxxxxxxxx"
],
"principalId": ["xxxxxxxxxxxx"],
"sessionName": ["masukawa"],
"sigs.k8s.io/aws-iam-authenticator/principalId": ["xxxxxxxxxxxx"]
}
},
"sourceIPs": ["219.104.138.156"],
"userAgent": "kubectl1.33.1/v1.33.1 (darwin/arm64) kubernetes/8adc0f0",
"objectRef": {
"resource": "pods",
"namespace": "default",
"name": "resize-demo",
"apiVersion": "v1",
"subresource": "resize"
},
"responseStatus": {
"metadata": {},
"code": 200
},
"requestObject": {
"spec": {
"containers": [
{
"name": "pause",
"resources": {
"requests": {
"cpu": "800m"
},
"limits": {
"cpu": "800m"
}
}
}
]
}
},
"responseObject": {
"kind": "Pod",
"apiVersion": "v1",
"metadata": {
"name": "resize-demo",
"namespace": "default",
"uid": "7bde55fb-2a7c-4151-b5dc-6f1e66bc088c",
"resourceVersion": "39479",
"generation": 2,
"creationTimestamp": "2025-05-31T13:37:59Z",
"annotations": {
"kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"v1\",\"kind\":\"Pod\",\"metadata\":{\"annotations\":{},\"name\":\"resize-demo\",\"namespace\":\"default\"},\"spec\":{\"containers\":[{\"image\":\"registry.k8s.io/pause:3.8\",\"name\":\"pause\",\"resizePolicy\":[{\"resourceName\":\"cpu\",\"restartPolicy\":\"NotRequired\"},{\"resourceName\":\"memory\",\"restartPolicy\":\"RestartContainer\"}],\"resources\":{\"limits\":{\"cpu\":\"700m\",\"memory\":\"200Mi\"},\"requests\":{\"cpu\":\"700m\",\"memory\":\"200Mi\"}}}]}}\n"
},
"managedFields": [
{
"manager": "kubectl-client-side-apply",
"operation": "Update",
"apiVersion": "v1",
"time": "2025-05-31T13:37:59Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:metadata": {
"f:annotations": {
".": {},
"f:kubectl.kubernetes.io/last-applied-configuration": {}
}
},
"f:spec": {
"f:containers": {
"k:{\"name\":\"pause\"}": {
".": {},
"f:image": {},
"f:imagePullPolicy": {},
"f:name": {},
"f:resizePolicy": {},
"f:resources": {
".": {},
"f:limits": {
".": {},
"f:memory": {}
},
"f:requests": {
".": {},
"f:memory": {}
}
},
"f:terminationMessagePath": {},
"f:terminationMessagePolicy": {}
}
},
"f:dnsPolicy": {},
"f:enableServiceLinks": {},
"f:restartPolicy": {},
"f:schedulerName": {},
"f:securityContext": {},
"f:terminationGracePeriodSeconds": {}
}
}
},
{
"manager": "kubelet",
"operation": "Update",
"apiVersion": "v1",
"time": "2025-05-31T13:38:02Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:status": {
"f:conditions": {
"k:{\"type\":\"ContainersReady\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"Initialized\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"PodReadyToStartContainers\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
},
"k:{\"type\":\"Ready\"}": {
".": {},
"f:lastProbeTime": {},
"f:lastTransitionTime": {},
"f:status": {},
"f:type": {}
}
},
"f:containerStatuses": {},
"f:hostIP": {},
"f:hostIPs": {},
"f:phase": {},
"f:podIP": {},
"f:podIPs": {
".": {},
"k:{\"ip\":\"192.168.108.83\"}": {
".": {},
"f:ip": {}
}
},
"f:startTime": {}
}
},
"subresource": "status"
},
{
"manager": "kubectl-patch",
"operation": "Update",
"apiVersion": "v1",
"time": "2025-05-31T13:40:01Z",
"fieldsType": "FieldsV1",
"fieldsV1": {
"f:spec": {
"f:containers": {
"k:{\"name\":\"pause\"}": {
"f:resources": {
"f:limits": {
"f:cpu": {}
},
"f:requests": {
"f:cpu": {}
}
}
}
}
}
},
"subresource": "resize"
}
]
},
"spec": {
"volumes": [
{
"name": "kube-api-access-hd8qh",
"projected": {
"sources": [
{
"serviceAccountToken": {
"expirationSeconds": 3607,
"path": "token"
}
},
{
"configMap": {
"name": "kube-root-ca.crt",
"items": [
{
"key": "ca.crt",
"path": "ca.crt"
}
]
}
},
{
"downwardAPI": {
"items": [
{
"path": "namespace",
"fieldRef": {
"apiVersion": "v1",
"fieldPath": "metadata.namespace"
}
}
]
}
}
],
"defaultMode": 420
}
}
],
"containers": [
{
"name": "pause",
"image": "registry.k8s.io/pause:3.8",
"resources": {
"limits": {
"cpu": "800m",
"memory": "200Mi"
},
"requests": {
"cpu": "800m",
"memory": "200Mi"
}
},
"resizePolicy": [
{
"resourceName": "cpu",
"restartPolicy": "NotRequired"
},
{
"resourceName": "memory",
"restartPolicy": "RestartContainer"
}
],
"volumeMounts": [
{
"name": "kube-api-access-hd8qh",
"readOnly": true,
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
}
],
"terminationMessagePath": "/dev/termination-log",
"terminationMessagePolicy": "File",
"imagePullPolicy": "IfNotPresent"
}
],
"restartPolicy": "Always",
"terminationGracePeriodSeconds": 30,
"dnsPolicy": "ClusterFirst",
"serviceAccountName": "default",
"serviceAccount": "default",
"nodeName": "ip-192-168-109-90.ap-northeast-1.compute.internal",
"securityContext": {},
"schedulerName": "default-scheduler",
"tolerations": [
{
"key": "node.kubernetes.io/not-ready",
"operator": "Exists",
"effect": "NoExecute",
"tolerationSeconds": 300
},
{
"key": "node.kubernetes.io/unreachable",
"operator": "Exists",
"effect": "NoExecute",
"tolerationSeconds": 300
}
],
"priority": 0,
"enableServiceLinks": true,
"preemptionPolicy": "PreemptLowerPriority"
},
"status": {
"phase": "Running",
"conditions": [
{
"type": "PodReadyToStartContainers",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2025-05-31T13:38:02Z"
},
{
"type": "Initialized",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2025-05-31T13:37:59Z"
},
{
"type": "Ready",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2025-05-31T13:38:02Z"
},
{
"type": "ContainersReady",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2025-05-31T13:38:02Z"
},
{
"type": "PodScheduled",
"status": "True",
"lastProbeTime": null,
"lastTransitionTime": "2025-05-31T13:37:59Z"
}
],
"hostIP": "192.168.109.90",
"hostIPs": [
{
"ip": "192.168.109.90"
}
],
"podIP": "192.168.108.83",
"podIPs": [
{
"ip": "192.168.108.83"
}
],
"startTime": "2025-05-31T13:37:59Z",
"containerStatuses": [
{
"name": "pause",
"state": {
"running": {
"startedAt": "2025-05-31T13:38:01Z"
}
},
"lastState": {},
"ready": true,
"restartCount": 0,
"image": "registry.k8s.io/pause:3.8",
"imageID": "registry.k8s.io/pause@sha256:9001185023633d17a2f98ff69b6ff2615b8ea02a825adffa40422f51dfdcde9d",
"containerID": "containerd://dc68922bfca7e6fe3f26c71e8c15cd3d4e7c49f01744a8a6a7008445e34c662f",
"started": true,
"allocatedResources": {
"cpu": "700m",
"memory": "200Mi"
},
"resources": {
"limits": {
"cpu": "700m",
"memory": "200Mi"
},
"requests": {
"cpu": "700m",
"memory": "200Mi"
}
},
"volumeMounts": [
{
"name": "kube-api-access-hd8qh",
"mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
"readOnly": true,
"recursiveReadOnly": "Disabled"
}
]
}
],
"qosClass": "Guaranteed"
}
},
"requestReceivedTimestamp": "2025-05-31T13:40:01.856824Z",
"stageTimestamp": "2025-05-31T13:40:01.872612Z",
"annotations": {
"authorization.k8s.io/decision": "allow",
"authorization.k8s.io/reason": "EKS Access Policy: allowed by ClusterRoleBinding \"arn:aws:iam::xxxxxxxxxxxx:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_AdministratorAccess_xxxxxxxxxxxx+arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy\" of ClusterRole \"arn:aws:eks::aws:cluster-access-policy/AmazonEKSClusterAdminPolicy\" to User \"xxxxxxxxxxxx\"",
"pod-security.kubernetes.io/enforce-policy": "privileged:latest"
}
}
Pod そのものをマニフェストファイルで管理していれば、マニフェストファイル書き換えに依る更新も可能です。
ただし、特に考えずに実行すると下記エラーが発生しました。
% kubectl apply -f pod-resize.yaml --subresource resize
error: --subresource can only be specified for --server-side
kubectl で --subresource
オプションを利用する際、Server-Side Apply を利用していないと、適用できないとのことです。
In-Place Update of Pod Resources に限った話ではなく、status や scale も含めた subresouce を扱う時に係る制限のようです。
下記ドキュメントに従い、Server-Side Apply に変更します。
まず、マニフェストファイルを kubectl patch
で更新された現在の limits/requests の値に更新します。
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.8
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Default, but explicit here
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "800m"
requests:
memory: "200Mi"
cpu: "800m"
その後、下記コマンドを実行します。
% kubectl apply -f pod-resize.yaml --server-side
pod/resize-demo serverside-applied
無事、Server-Side Apply に成功したので、マニフェストファイルを修正して limits/requests を 900m まで上げてみます。
apiVersion: v1
kind: Pod
metadata:
name: resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.8
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Default, but explicit here
- resourceName: memory
restartPolicy: RestartContainer
resources:
limits:
memory: "200Mi"
cpu: "900m"
requests:
memory: "200Mi"
cpu: "900m"
--server-side
オプションを付与して、apply すると今回は成功しました。
% kubectl apply -f pod-resize.yaml --server-side --subresource resize
pod/resize-demo serverside-applied
再作成にならず、requests/limits を更新できています。
% kubectl describe pod resize-demo
Name: resize-demo
Namespace: default
Priority: 0
Service Account: default
Node: ip-192-168-109-90.ap-northeast-1.compute.internal/192.168.109.90
Start Time: Sat, 31 May 2025 22:37:59 +0900
Labels: <none>
Annotations: <none>
Status: Running
IP: 192.168.108.83
IPs:
IP: 192.168.108.83
Containers:
pause:
Container ID: containerd://dc68922bfca7e6fe3f26c71e8c15cd3d4e7c49f01744a8a6a7008445e34c662f
Image: registry.k8s.io/pause:3.8
Image ID: registry.k8s.io/pause@sha256:9001185023633d17a2f98ff69b6ff2615b8ea02a825adffa40422f51dfdcde9d
Port: <none>
Host Port: <none>
State: Running
Started: Sat, 31 May 2025 22:38:01 +0900
Ready: True
Restart Count: 0
Limits:
cpu: 900m
memory: 200Mi
Requests:
cpu: 900m
memory: 200Mi
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hd8qh (ro)
Conditions:
Type Status
PodReadyToStartContainers True
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-hd8qh:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
Optional: false
DownwardAPI: true
QoS Class: Guaranteed
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 13m default-scheduler Successfully assigned default/resize-demo to ip-192-168-109-90.ap-northeast-1.compute.internal
Normal Pulling 13m kubelet Pulling image "registry.k8s.io/pause:3.8"
Normal Pulled 13m kubelet Successfully pulled image "registry.k8s.io/pause:3.8" in 1.268s (1.268s including waiting). Image size: 311286 bytes.
Normal Created 13m kubelet Created container: pause
Normal Started 13m kubelet Started container pause
最後に
EKS が Kubernetes v1.33 を利用できるようになったので、In-Place Update of Pod Resources を触ってみました。
スケールアウトに頼り辛く、Pod の再起動を許容できない場合に便利そうです。
Dynamic Resource Allocation など他にも新しく使える機能は多いので、別途試してみようと思います。