파드에 할당된 CPU·메모리 리소스 크기 조정하기
파드에 할당된 CPU·메모리 리소스 크기 조정하기
이 페이지는 파드를 다시 만들지 않고 파드 수준에서 설정된 CPU와 메모리 리소스를 변경하는 방법을 설명해요.
In-place Pod Resize 기능은 실행 중인 파드의 리소스 할당을 수정해 애플리케이션 중단을 피하게 해줘요. 개별 컨테이너 리소스의 크기를 조정하는 과정은 컨테이너에 할당된 CPU·메모리 리소스 크기 조정에서 다뤄요.
이 페이지는 In-place 파드 수준 리소스 크기 조정에 초점을 맞춰요. 파드 수준 리소스는 spec.resources에 정의되며, 파드의 모든 컨테이너가 소비하는 총 리소스의 상한으로 작용해요. In-place 파드 수준 리소스 크기 조정 기능은 실행 중인 파드의 이 총체적 CPU·메모리 할당을 직접 변경하게 해줘요.
출처: 문서
본문
시작하기 전에
Kubernetes 클러스터가 있어야 하고 kubectl 명령줄 도구가 클러스터와 통신하도록 구성되어 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 최소 두 개 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube를 이용해 만들거나, 아래 Kubernetes 플레이그라운드 중 하나를 사용할 수 있어요.
버전을 확인하려면 kubectl version을 입력해요. 컨트롤 플레인과 클러스터의 모든 노드에서 다음 기능 게이트가 활성화되어 있어야 해요.
- InPlacePodLevelResourcesVerticalScaling
- PodLevelResources
- InPlacePodVerticalScaling
- NodeDeclaredFeatures
kubectl 클라이언트 버전은 --subresource=resize 플래그를 사용하려면 최소 v1.32여야 해요.
파드 크기 조정 상태와 재시도 로직
kubelet이 리소스 변경을 추적하고 재시도하는 데 사용하는 메커니즘은 컨테이너 수준과 파드 수준 크기 조정 요청 사이에 공유돼요.
상태, 이유, 재시도 우선순위는 컨테이너 크기 조정에 정의된 것과 동일해요.
- 상태 조건 (Status Conditions): kubelet은
PodResizePending(이유:Infeasible또는Deferred)과PodResizeInProgress를 사용해 요청의 상태를 알려줘요. - 재시도 우선순위 (Retry Priority):
Deferred크기 조정은 PriorityClass, 그다음 QoS 클래스(Guaranteed가 Burstable보다 우선), 마지막으로 지연된 기간에 따라 재시도돼요. - 추적 (Tracking):
observedGeneration필드를 사용해 마지막으로 처리된 크기 조정 요청의 상태가 어느 파드 사양(metadata.generation)에 해당하는지 추적할 수 있어요.
이 조건들과 재시도 로직에 대한 전체 설명은 컨테이너 크기 조정 문서의 파드 크기 조정 상태 섹션을 참고해요.
컨테이너 크기 조정 정책과 파드 수준 크기 조정
파드 수준 리소스 크기 조정은 자체 재시작 정책을 지원하거나 요구하지 않아요.
- 파드 수준 정책 없음: 파드의 총 리소스(
spec.resources) 변경은 재시작을 트리거하지 않고 항상 제자리(in-place)에서 적용돼요. 파드 수준 리소스가 파드의 cgroup에 대한 전반적 제약으로 작용하고 컨테이너 내부의 애플리케이션 런타임을 직접 관리하지 않기 때문이에요. - 컨테이너 정책이 여전히 적용됨:
resizePolicy는 여전히 컨테이너 수준(spec.containers[*].resizePolicy)에서 구성해야 해요. 이 정책은 리소스 요청이나 한도가 변경될 때 개별 컨테이너가 재시작되는지 여부를 주관하며, 그 변경이 직접적인 컨테이너 수준 크기 조정이나 파드 수준 리소스 엔벨로프 업데이트에 의해 시작됐는지와 무관해요.
제한 사항 (Limitations)
Kubernetes 1.37에서 파드 수준 리소스를 제자리에서 크기 조정하는 것은 컨테이너 수준 리소스 크기 조정: 제한 사항에서 찾을 수 있는 컨테이너 수준 리소스 크기 조정에 설명된 모든 제한의 적용을 받아요.
추가로, 파드 수준 리소스 크기 조정에 특화된 다음 제약이 있어요.
- 컨테이너 요청 검증: 결과 파드 수준 리소스 요청(
spec.resources.requests)이 파드 안의 모든 개별 컨테이너의 해당 리소스 요청의 합 이상일 때만 크기 조정이 허용돼요. 이는 파드에 대한 최소 보장 리소스 가용성을 유지해요. - 컨테이너 한도 검증: 개별 컨테이너 한도가 파드 수준 리소스 한도(
spec.resources.limits) 이하일 때 크기 조정이 허용돼요. 파드 수준 한도는 어떤 단일 컨테이너도 초과할 수 없는 경계로 작용하지만, 컨테이너 한도의 합은 파드 수준 한도를 초과할 수 있어, 파드 안의 컨테이너 간 리소스 공유를 가능하게 해요.
예시: 파드 수준 리소스 크기 조정
먼저 제자리 CPU 크기 조정과 재시작 필요한 메모리 크기 조정을 위해 설계된 파드를 만들어요.
apiVersion: v1
kind: Pod
metadata:
name: pod-level-resize-demo
spec:
containers:
- name: pause
image: registry.k8s.io/pause:3.9
resizePolicy:
- resourceName: cpu
restartPolicy: NotRequired # Default, but explicit here
- resourceName: memory
restartPolicy: RestartContainer
resources:
requests:
cpu: 100m
memory: 100Mi
- name: nginx-server
image: registry.k8s.io/nginx:latest
resizePolicy:
- resourceName: cpu
restartPolicy: RestartContainer
- resourceName: memory
restartPolicy: RestartContainer
resources: # Pod-level resources
requests:
cpu: 200m
memory: 200Mi
limits:
cpu: 200m
memory: 200Mi
파드를 만들어요.
kubectl create -f pod-level-resize.yaml
이 파드는 파드 수준 요청이 한도와 같으므로 Guaranteed QoS 클래스로 시작해요. 초기 상태를 확인해요.
# Wait a moment for the pod to be running
kubectl get pod pod-level-resize-demo --output=yaml
spec.resources(200m CPU, 200Mi 메모리)를 관찰해요. status.containerStatuses[0].restartCount(0이어야 함)와 status.containerStatuses[1].restartCount(0이어야 함)를 주목해요.
이제 파드 수준 CPU 요청과 한도를 300m으로 늘려요. kubectl patch를 --subresource resize 명령줄 인자와 함께 사용해요.
kubectl patch pod pod-level-resize-demo --subresource resize --patch \
'{"spec":{"resources":{"requests":{"cpu":"300m"}, "limits":{"cpu":"300m"}}}}'
# Alternative methods:
# kubectl edit pod pod-level-resize-demo --subresource resize
# kubectl apply -f <updated-manifest> --subresource resize --server-side
패치 후 파드 상태를 다시 확인해요.
kubectl get pod pod-level-resize-demo --output=yaml
다음을 볼 수 있어요.
spec.resources.requests와spec.resources.limits가 이제cpu: 300m을 보여줘요.status.containerStatuses[0].restartCount는 0으로 유지돼요. CPUresizePolicy가NotRequired이기 때문이에요.status.containerStatuses[1].restartCount는 1로 증가해, CPU 변경을 적용하기 위해 컨테이너가 재시작되었음을 나타내요. 크기 조정이 파드 수준에서 적용되었음에도 불구하고 Container 1에서 재시작이 발생했는데, 이는 파드 수준 한도와 컨테이너 수준 정책 사이의 복잡한 관계 때문이에요. Container 1이 명시적 CPU 한도를 지정하지 않았기 때문에, 그것의 기반 리소스 구성(예: cgroups)이 암묵적으로 파드의 전체 CPU 한도를 그것의 유효 최대 소비 경계로 채택했어요. 파드 수준 CPU 한도가 200m에서 300m으로 패치되자, 이 작업은 결과적으로 Container 1에 강제되는 암묵적 한도를 변경했어요. Container 1의 CPUresizePolicy가 명시적으로RestartContainer로 설정되어 있었기 때문에, kubelet은 기반 리소스 강제 메커니즘의 이 변경을 올바르게 적용하기 위해 컨테이너를 재시작할 의무가 생겼고, 따라서 컨테이너 한도가 직접 정의되지 않았더라도 파드 수준 한도 변경이 컨테이너 재시작 정책을 트리거할 수 있음을 확인해요.
정리
파드를 삭제해요.
kubectl delete pod pod-level-resize-demo
다음 단계
애플리케이션 개발자용
클러스터 관리자용
- 네임스페이스의 기본 메모리 요청·한도 구성
- 네임스페이스의 기본 CPU 요청·한도 구성
- 네임스페이스의 최소·최대 메모리 제약 구성
- 네임스페이스의 최소·최대 CPU 제약 구성
- 네임스페이스의 메모리·CPU 쿼터 구성