궁금한게 많은 개발자 노트

cgroup의 cpu controller (subsystem) 본문

Operating System

cgroup의 cpu controller (subsystem)

궁금한게 많은 개발자 2024. 11. 8. 17:42

운영 측면에서 모든 리소스가 중요하겠지만 그 중 cpu, memory에 대한 리소스가 가장 중요하다고 생각하실 것 같습니다. 이에 cpu 컨트롤러에 대해 조금 더 자세히 알아보려 합니다. 😎

cpu컨트롤러는 특정 cgroup에 속하는 프로세스의 cpu리소스를 할당하고 제한하는 역할을합니다. 이를 통해 cpu 사용률을 제어하고 프로세스 간 cpu 자원을 균등하거나 특정 비율로 배분할 수 있습니다. 이제 cpu 컨트롤러의 인터페이스 파일을 알아보겠습니다.

 

cpu.max

  • 최대 CPU사용률을 설정하는 파일
  • quota period 형식으로 값을 설정
    • quota: 주기 동안 사용 가능한 최대 CPU 시간 (마이크로초 단위)
    • period: 주기 설정 (마이크로초 단위), 기본값은 100,000마이크로초(0.1초)입니다.(최소 1ms, 최대 1초)
/sys/fs/cgroup/A # cat cpu.max
max 100000 # MAX(QUOTA) PERIOD

echo "50000 100000" > /sys/fs/cgroup/A/cpu.max

위와 같은 경우 첫 번째 예시는 max로 quota를 설정하였으며 0.1초동안 max로 cpu를 사용한다는 의미입니다. 이 때는 throttled상태가 되지 않지만 기간 내 무한히 cpu를 사용한다는 의미는 아닙니다.

두 번째 예시는 0.1초마다 최대 0.05초 cpu를 사용한다는 의미로 cpu사용률을 50%로 제한한다는 의미입니다.

이러한 과정을 kubernetes에서는 spec.containers[].resources.limits.cpu 값을 통해 cpu사용률을 제어하고 있습니다. 마찬가지로 코어의 개수가 아닌 사용률에 대한 제한을 두는 것입니다.

 

cpu.weight

  • 루트 제어 그룹이 아닌 하위 제어그룹에만 존재
  • cpu.weight값을 기반으로 cpu를 분배받을 수 있도록 하는 파일 (cpu의 상대적인 할당 비율)
  • 1~10000의 값을 지정할 수 있으며 기본값은 100
  • 다른 cgroup과 비교하여 cpu리소스를 얼마나 비율적으로 할당 받을 수 있는지 결정
echo $$ > /sys/fs/cgroup/A/cgroup.procs
echo 100 > /sys/fs/cgroup/A/cpu.weight

echo $$ > /sys/fs/cgroup/B/cgroup.procs
echo 200 > /sys/fs/cgroup/B/cpu.weight

 

위 예시에서는 A, B cgroup에 대해 각각 100, 200의 cpu.weight를 주었습니다. 이 경우에 A만 cpu를 사용한다면 100%를 모두 사용할 수 있겠지만 A, B 모두가 cpu를 사용하는 상황에서는 33.3%, 66.6%로 조정되는 것을 볼 수 있습니다.

마찬가지로 kubernetes에서는 spec.containers[].resource.requests.cpu 값을 통해 이러한 설정을 지원하고 있습니다. 코어의 개수를 설정하는 것이 아니라 다른 container와 비교하여 얼마만큼의 가중치를 가져가냐의 의미입니다.

(k8s에서 기본적으로 limits만 적용 시, 그에 맞는 requests가 적용 된다고 가이드되고 있습니다, 또한 k8s에서는 limits를 적용하여 불 필요한 병목을 야기하지 않고, requests만 적용하여 각 container가 요청할 수 있는 비율을 설정 함에따라 최대 가질 수 있는 cpu가 할당 되는 효과를 얻을 수 있으므로 requests만 적용하는 경우도 많다고 합니다.)

 

cpu.stat

  • 모든 제어 그룹에 존재하는 읽기 전용 파일
  • 각 제어 그룹에 속한 프로세스들이 사용한 cpu관련 통계를 제공 - cpu사용 패턴 모니터링, 성능 최적화 가능
    • usage_usec: cpu 총 사용 시간 (마이크로초 단위)
    • user_usec: user mode cpu 사용 시간
    • system_usec: kernel mode cpu 사용 시간
    • nr_periods: cgroup이 cpu를 할당받기 위해 시도한 횟수, 스케줄러에 의해 cpu가 할당된 횟수
    • nr_throttled: cpu사용이 제한되어 throttling된 횟수
    • throttled_usec: throttling된 시간
    • nr_bursts: cpu brust mode로 전환된 횟수
    • burst_usec: brust mode에서 사용한 시간
  • 실제 container혹은 프로세스에서 사용하는 cpu사용량은 어떻게 구할까요?
    • 현재 cpu.stat의 usage_usec 및 현재 시간 마이크로초 산출
    • N초 휴식
    • N초 뒤 cpu.stat의 usage_usec 및 현재 시간 마이크로초 산출
    • usage_usec 차이 / 마이크로초 차이 * 100 = cpu 사용량

위에서 언급된 지표들을 통해 cpu가 어떻게 사용되고 제어되는지 알 수 있었습니다. 그렇다면 cpu throttling은 언제 발생할까요? cgroup이 설정된 cpu사용 한도에 도달하거나 초과했을 때 발생하고 해당 cgroup은 일시적으로 cpu를 사용할 수 없으며 대기해야 합니다.

cpu.max를 통해 주기당 사용할 수 있는 cpu 시간을 설정할 수 있고 cpu.weight가 높은 cgroup일수록 cpu자원 배분에 대한 우선순위를 가져 max quota에 도달할 확률이 높기에 cpu.stat에서 nr_throttled값이 증가하는 결과를 볼 수 있을 것 같습니다. 이러한 다양한 cpu 컨트롤러의 인터페이스 파일을 통해 현재 cpu 사용량을 모니터링하고 제어하여 운영 환경에 맞는 다양한 리소스를 적절히 관리할 수 있으면 좋을 것 같습니다. 긴 글 읽어주셔서 감사합니다 🤗👍

 

'Operating System' 카테고리의 다른 글

cgroup(control group) 이란?  (0) 2024.11.04
Comments