파드와 컨테이너의 리소스 관리

파드와 컨테이너의 리소스 관리 (Resource Management for Pods and Containers)

Pod를 정의할 때, 각 컨테이너가 리소스를 얼마나 필요로 하는지 선택적으로 지정할 수 있어요. 가장 흔하게 지정하는 리소스는 CPU와 메모리(RAM)인데, 그 외에도 다른 리소스가 있을 수 있죠.

파드 안의 컨테이너에 리소스 요청(request) 을 지정하면, kube-scheduler가 이 정보를 이용해 파드를 어떤 노드에 배치할지 결정해요. 반면 컨테이너에 리소스 상한(limit) 을 지정하면, kubelet이 그 상한을 강제해서 실행 중인 컨테이너가 설정한 상한보다 더 많은 리소스를 쓰지 못하게 해요. kubelet은 또한 해당 컨테이너를 위해 시스템 리소스의 요청량만큼을 미리 예약해 두기도 하죠.

요청과 상한 (Requests and limits)

예를 들어 컨테이너에 memory 요청을 256 MiB로 설정하고, 그 컨테이너가 8GiB 메모리를 가진 노드에 다른 파드 없이 스케줄링됐다고 해볼게요. 그러면 이 컨테이너는 그보다 더 많은 RAM을 사용하려 시도할 수 있어요.

상한은 얘기가 조금 달라요. cpumemory 상한은 모두 kubelet(과 컨테이너 런타임)에 의해 적용되고, 최종적으로는 커널이 강제해요. Linux 노드에서는 Linux 커널이 cgroups를 통해 상한을 강제하죠. cpumemory 상한이 강제되는 방식은 조금 달라요.

이 말은 memory 상한이 반응적으로(reactively) 적용된다는 뜻이에요. 컨테이너가 자신의 memory 상한보다 더 많은 메모리를 사용할 수는 있지만, 그렇게 하면 죽임당할 수도 있어요.

리소스 유형 (Resource types)

리소스 유형(resource type) 은 기본 단위를 가지며, 요청·상한·모두로 지정될 수 있어요. Kubernetes에는 다음과 같은 내장 리소스 유형이 있어요:

파드와 컨테이너의 리소스 요청 및 상한

  • spec.containers[].resources.limits.cpu
  • spec.containers[].resources.limits.memory
  • spec.containers[].resources.limits.ephemeral-storage
  • spec.containers[].resources.limits.hugepages-<size>
  • spec.containers[].resources.requests.cpu
  • spec.containers[].resources.requests.memory
  • spec.containers[].resources.requests.ephemeral-storage
  • spec.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.cpu0.5로 설정한 컨테이너를 정의하면, 1.0 CPU를 요청했을 때에 비해 절반만큼의 CPU 시간을 요청하는 거예요.

CPU 리소스 단위에서 수량 표현식 0.1100m과 동일해요. 이는 "백 밀리 CPU(one hundred millicpu)"라고 읽을 수 있는데, 어떤 사람들은 "백 밀리코어(one hundred millicores)"라고 말하기도 해요. 같은 뜻으로 이해하면 돼요.

CPU 리소스는 항상 절대적인 양으로 지정되며, 상대적인 양으로는 절대 지정되지 않아요. 예를 들어 500m CPU는 그 컨테이너가 싱글 코어·듀얼 코어·48코어 머신 중 어디에서 실행되든 대략 같은 양의 연산 능력을 나타내요.

참고: Kubernetes는 1m 또는 0.001 CPU보다 더 정밀한 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을 참고하세요.

더 알아보기