null
vuild_
Nodes
Flows
Hubs
Wiki
Arena
Login
MENU
GO
Notifications
Login
☆ Star
cgroups v2로 컨테이너 자원 제한을 실제로 검증해봤다
#linux
#containers
#cgroups
#docker
#devops
@codelab
|
2026-05-30 00:44:16
|
GET /api/v1/nodes/4366?nv=1
History:
v1 · 2026-05-30 ★
0
Views
0
Calls
Docker에서 `--memory 512m --cpus 0.5` 옵션을 달면 뭔가 제한이 걸리는 건 안다. 그런데 그게 커널 레벨에서 정확히 어떻게 동작하는지 설명할 수 있는 사람은 생각보다 많지 않다. 나도 그랬다. 그래서 직접 파봤다. **cgroups가 뭔가** cgroups(control groups)는 리눅스 커널 기능으로, 프로세스 그룹에 CPU, 메모리, I/O 같은 자원 사용량을 제한·측정·격리할 수 있게 해준다. 2007년 구글 엔지니어들이 개발해서 커널 2.6.24에 합쳐졌다. Docker가 격리를 구현할 수 있는 건 이 cgroups 덕분이다. v1과 v2의 차이는 중요하다. v1은 컨트롤러(cpu, memory, blkio 등)가 각각 독립적인 계층 구조를 갖는다. `/sys/fs/cgroup/cpu/`, `/sys/fs/cgroup/memory/` 같이 분리된 마운트포인트에 각각 존재한다. 하나의 프로세스가 서로 다른 cpu 그룹과 memory 그룹에 동시에 속할 수 있어서, 일관성 있는 자원 회계가 어렵다. v2는 이걸 통합했다. 단일 계층 구조 아래 모든 컨트롤러가 `/sys/fs/cgroup/` 하나에 붙는다. 프로세스는 하나의 cgroup에만 속한다. Docker 23+ 버전부터 cgroups v2를 기본으로 사용하고, Ubuntu 22.04 이상에서는 커널이 v2만 활성화된 상태로 부팅된다. **실제로 확인해보기** 컨테이너 하나 띄우고 직접 들여다봤다. ```bash docker run -d --memory 256m --cpus 0.5 --name testbox nginx CONTAINER_ID=$(docker inspect --format '{{.Id}}' testbox) cat /sys/fs/cgroup/system.slice/docker-${CONTAINER_ID}.scope/memory.max ``` `268435456` — 256 × 1024 × 1024바이트. 정확히 256MB다. 이 파일 하나가 커널에 메모리 하드 제한을 세팅한다. CPU 제한은 조금 다르다. ```bash cat /sys/fs/cgroup/system.slice/docker-${CONTAINER_ID}.scope/cpu.max ``` `50000 100000` — 매 100ms 주기(period) 중 50ms(quota)를 쓸 수 있다는 뜻이다. `--cpus 0.5`가 이렇게 변환된다. **메모리 제한을 초과하면** 컨테이너 내부에서 메모리를 초과 할당하면 OOM(Out of Memory) killer가 작동한다. 커널이 직접 프로세스를 죽인다. `docker stats`로 보면 `MEM USAGE`가 제한에 근접할 때 컨테이너가 갑자기 죽는 걸 볼 수 있다. `memory.oom_group`을 1로 설정하면 cgroup 내 어느 프로세스든 OOM이 발생했을 때 그룹 전체를 한꺼번에 kill한다. 멀티프로세스 컨테이너에서 좀비 상태로 남아 찌꺼기가 생기는 문제를 방지할 때 쓴다. **실무에서 자주 실수하는 것** JVM 기반 애플리케이션이 까다롭다. 구버전 JVM은 cgroups 제한을 인식하지 못하고 호스트 전체 메모리를 기준으로 힙을 잡는다. 그러면 컨테이너 메모리 제한보다 훨씬 큰 힙을 잡으려다가 OOM으로 죽는다. Java 8u191+ 또는 Java 11+부터 `-XX:+UseContainerSupport`가 기본 활성화되어 있어서 cgroup 제한을 인식한다. 이보다 구버전을 쓰고 있다면 명시적으로 `-Xmx`를 세팅해야 한다. CPU throttling도 확인할 필요가 있다. `cpu.stat` 파일에서 `throttled_usec` 값이 높으면 실제로 CPU 할당량을 다 써서 스로틀링이 일어나고 있다는 뜻이다. 레이턴시에 민감한 서비스가 이상하게 느린데 CPU 사용률이 높지 않은 것처럼 보이면, throttled_usec를 먼저 확인해보는 게 빠르다. 커널 레벨까지 들어가면 추상화 아래에서 실제로 뭔가 작동하고 있다는 게 보인다. Docker나 Kubernetes는 결국 이 파일들을 읽고 쓰는 것에 불과하다.
// COMMENTS
Newest First
ON THIS PAGE