cgroup의 CPU·메모리 제어 방식

1,127 단어·3 분·원문(.md)

linux kernel에서 cgroup(control groups)은 단순히 프로세스를 묶는 바구니가 아니다.

시스템 리소스를 추상화해 분배하고 격리하는 하부 시스템 핵심이다.

커널 내에서 계츠 구조를 가지고 각 프로세스는 특정 cgroup에 속하며 그룹들은 트리 구조로 연결된다.

  • cgroup v1 vs v2: 과거에는 리소스별로 계층 구조가 분리되어 관리 효율성이 떨어졌으나, 현재 표준인 v2 Unified Hierarchy를 사용하여 모든 리소스 컨트롤러가 하나의 트리 아래에서 관리된다.
  • 컨트롤러: cpu, memory, io등 특정 자원을 관리하는 커널 모듈이다.

CFS, Scheduling #

리눅스는 기본적으로 CFS(Completely Fair Scheduler)를 사용해 cpu 시간을 분배한다.

cgroup은 이 CFS의 동작 방식에 개입하여 자원을 할당한다.

Weight 기반 할당 (Shares) #

절대적인 수치가 아닌 상대적인 비율로 cpu를 할당한다.

  • 메커니즘: 각 cgroup은 cpu.weight 값을 가진다. 전체 가중치 합산 중 해당 그룹이 차지하는 비중만큼 cpu 시간을 점유한다.
  • 특징으로는 시스템이 한가할 때 제한없이 cpu를 쓰다가, 경합(contention)이 발생할때만 설정된 비율로 제한한다. 이를 work-conserving 방식이라 한다.

Quota/Period 기반 할당 #

특정 시간 동안 사용할 수 있는 절대 시간을 강제한다.

CPU Usage Limit=cpu.max (quota)period\text{CPU Usage Limit} = \frac{\text{cpu.max (quota)}}{\text{period}}

period 동안 quota만큼 다 사용하면, 해당 cgroup의 모든 프로세스는 다음 주기가 올 때까지 throttling 상태가 된다.

이는 실시간성이 중요한 서비스에서 주의해야할 지점이다.

Memory 제어 메커니즘: RSS, Page Cache #

메모리는 cpu와 달리 시간을 나눠쓰는것이 아니라 공간을 점유하는 자원이므로 제어 방식이 더 복잡하고 위험하다.

메모리 회계 accounting #

커널은 프로세스가 메모리를 할당받을때마다 해당 cgroup의 카운터를 올린다.

  • 익명 메모리 RSS, 페이지 캐시 page cache, 커널 메모리 slab 등이 모두 포함된다.
  • memory.max (hard limit), memory.low/high (soft limit, protection)으로 구분된다.

메모리 회수 및 oom killer #

  • Reclaim: cgroup이 제한값에 도달하면 커널은 직시 page reclaim을 시도한다. 주로 페이지 캐시를 비우고
  • OOM: 회수할 메모리가 없는데 더 요구하면 oom killer를 커널이 호출한다.
  • 선별: cgroup 내에서 oom_score가 가장 높은 프로세스를 종료시킨다. v2에서는 그룹 전체를 한꺼번에 종료시키는 memory.oom.group 설정도 가능하다.

커널 내부 동작 원리 #

cgroup은 /sys/fs/cgroup 이라는 VFS(Virtual File System)을 통해서 인터페이스를 제공한다.

우리가 이 디렉토리의 파일을 수정하면 커널 내부의 cgroup_subsys_state 구조체 값이 변경되고 스케줄러와 메모리 관리자 MM가 이 값을 참조하여 동작을 결정한다.

Resource Counter와 가상 파일 시스템으로 기억해두면 된다.

추가로 cpu quota를 너무 타이트하게 잡으면, 프로세스가 작업을 채 마치기 전에 중단되어

Tail Latency가 급증할 수 있다. 이를 모니터링 하기위해 cpu.stat 파일의 nr_throttled 수치를 반드시 확인해야한다.

현대의 쿠버네티스나 도커 컨테이너 격리 실체는 바로 이 cgroup과 namespace 격리의 조합이다.

SRE/question/q_19.md