파드와 컨테이너의 리소스 관리
파드와 컨테이너의 리소스 관리 (Resource Management for Pods and Containers)
Pod를 정의할 때, 각 컨테이너가 리소스를 얼마나 필요로 하는지 선택적으로 지정할 수 있어요. 가장 흔하게 지정하는 리소스는 CPU와 메모리(RAM)인데, 그 외에도 다른 리소스가 있을 수 있죠.
파드 안의 컨테이너에 리소스 요청(request) 을 지정하면, kube-scheduler가 이 정보를 이용해 파드를 어떤 노드에 배치할지 결정해요. 반면 컨테이너에 리소스 상한(limit) 을 지정하면, kubelet이 그 상한을 강제해서 실행 중인 컨테이너가 설정한 상한보다 더 많은 리소스를 쓰지 못하게 해요. kubelet은 또한 해당 컨테이너를 위해 시스템 리소스의 요청량만큼을 미리 예약해 두기도 하죠.
요청과 상한 (Requests and limits)
예를 들어 컨테이너에 memory 요청을 256 MiB로 설정하고, 그 컨테이너가 8GiB 메모리를 가진 노드에 다른 파드 없이 스케줄링됐다고 해볼게요. 그러면 이 컨테이너는 그보다 더 많은 RAM을 사용하려 시도할 수 있어요.
상한은 얘기가 조금 달라요. cpu와 memory 상한은 모두 kubelet(과 컨테이너 런타임)에 의해 적용되고, 최종적으로는 커널이 강제해요. Linux 노드에서는 Linux 커널이 cgroups를 통해 상한을 강제하죠. cpu와 memory 상한이 강제되는 방식은 조금 달라요.
이 말은 memory 상한이 반응적으로(reactively) 적용된다는 뜻이에요. 컨테이너가 자신의 memory 상한보다 더 많은 메모리를 사용할 수는 있지만, 그렇게 하면 죽임당할 수도 있어요.
리소스 유형 (Resource types)
리소스 유형(resource type) 은 기본 단위를 가지며, 요청·상한·모두로 지정될 수 있어요. Kubernetes에는 다음과 같은 내장 리소스 유형이 있어요:
파드와 컨테이너의 리소스 요청 및 상한
spec.containers[].resources.limits.cpuspec.containers[].resources.limits.memoryspec.containers[].resources.limits.ephemeral-storagespec.containers[].resources.limits.hugepages-<size>spec.containers[].resources.requests.cpuspec.containers[].resources.requests.memoryspec.containers[].resources.requests.ephemeral-storagespec.containers[].resources.requests.hugepages-<size>
파드 레벨 리소스 지정 (Pod-level resource specification)
클러스터에서 PodLevelResources 기능 게이트(feature gate)가 활성화되어 있다면, 파드 레벨에서도 리소스 요청과 상한을 지정할 수 있어요. 파드 레벨에서는 Kubernetes 1.37 기준으로 cpu 및/또는 memory 및/또는 hugepages 같은 특정 리소스 유형에 대해서만 요청·상한을 지원해요.
Kubernetes에서의 리소스 단위
CPU 리소스 단위
CPU 리소스의 상한과 요청은 cpu 단위로 측정돼요. Kubernetes에서 1 CPU 단위는 물리 CPU 코어 1개 또는 가상 코어 1개와 동일해요. 노드가 물리 호스트냐 물리 머신 안에서 도는 가상 머신이냐에 따라 달라지죠.
분수 형태의 요청도 허용돼요. spec.containers[].resources.requests.cpu를 0.5로 설정한 컨테이너를 정의하면, 1.0 CPU를 요청했을 때에 비해 절반만큼의 CPU 시간을 요청하는 거예요.
CPU 리소스 단위에서 수량 표현식 0.1은 100m과 동일해요. 이는 "백 밀리 CPU(one hundred millicpu)"라고 읽을 수 있는데, 어떤 사람들은 "백 밀리코어(one hundred millicores)"라고 말하기도 해요. 같은 뜻으로 이해하면 돼요.
CPU 리소스는 항상 절대적인 양으로 지정되며, 상대적인 양으로는 절대 지정되지 않아요. 예를 들어 500m CPU는 그 컨테이너가 싱글 코어·듀얼 코어·48코어 머신 중 어디에서 실행되든 대략 같은 양의 연산 능력을 나타내요.
참고: Kubernetes는
1m또는0.001CPU보다 더 정밀한 CPU 리소스 지정을 허용하지 않아요. 잘못된 CPU 수량을 실수로 사용하는 것을 피하기 위해, 1 CPU 미만을 사용할 때는 소수 형태 대신 milliCPU 형태로 CPU 단위를 지정하는 게 유용해요.
메모리 리소스 단위
Kubernetes API는 접미사 m도 허용해요(밀리바이트: 1바이트의 1/1000) 하지만, 이는 지정하기엔 유용하지 않아요. 반드시 정수 바이트 단위로 할당해야 하며, 때로는 1 gibibyte의 배수 같은 더 큰 덩어리로 할당할 수 있어요.
대략 같은 값을 나타내는 메모리 수량 예시를 몇 개 보여드릴게요:
128974848, 129e6, 129M, 128974848000m, 123Mi
접미사의 대소문자에 주의하세요. "M"은 메가바이트, "m"은 밀리바이트를 의미해요. 메모리 400m을 요청하면 0.4바이트를 요청하는 거예요. 이런 걸 입력한 사람은 아마 400 mebibytes(400Mi)나 400 megabytes(400M)를 요청하려던 거였을 거예요.
확장 리소스 (Extended resources)
확장 리소스는 kubernetes.io 도메인 밖에 있는 완전한 자격을 갖춘 리소스 이름이에요. 클러스터 운영자가 비(Kubernetes-)내장 리소스를 광고하고, 사용자가 그 리소스를 소비할 수 있게 해 줘요.
확장 리소스 소비하기
참고: 확장 리소스는 Opaque Integer Resources를 대체해요. 사용자는 예약된
kubernetes.io를 제외한 어떤 도메인 이름 접두사를 써도 돼요.
파드에서 확장 리소스를 소비하려면 컨테이너 스펙의 spec.containers[].resources.limits 맵에 리소스 이름을 키로 포함하면 돼요.
PID 제한 (PID limiting)
프로세스 ID(PID) 상한은 지정된 파드가 소비할 수 있는 PID 수를 제한하도록 kubelet을 구성하게 해 줘요. 자세한 내용은 PID Limiting을 참고하세요.