현대 Linux 서버에서는 하나의 운영체제에서 여러 애플리케이션을 동시에 실행하는 것이 일반적입니다. 웹 서버, 데이터베이스, 캐시 서버, 컨테이너 등이 함께 실행되는 환경에서는 특정 프로그램이 CPU나 메모리를 과도하게 사용하면 다른 서비스까지 영향을 받을 수 있습니다.
이 문제를 해결하기 위해 Linux Kernel은 cgroups(Control Groups) 라는 기능을 제공합니다.
cgroups는 프로세스를 그룹으로 묶어 CPU, 메모리, 디스크 I/O, 네트워크 등의 자원을 제한하거나 모니터링할 수 있는 기능입니다. Docker와 Kubernetes도 내부적으로 cgroups를 사용하여 컨테이너의 자원을 관리합니다.
이번 글에서는 cgroups의 개념과 동작 원리, 주요 기능, 확인 방법, 그리고 실무 활용 사례를 자세히 알아보겠습니다.
cgroups란?
cgroups(Control Groups)는 프로세스 그룹별로 시스템 자원을 제어하고 모니터링하는 Linux Kernel 기능입니다.
동작 구조는 다음과 같습니다.
Linux Kernel
↓
cgroups
↓
CPU
Memory
Disk I/O
Network
↓
Process Group
하나의 프로세스가 아니라 여러 프로세스를 하나의 그룹으로 관리할 수 있습니다.
cgroups가 필요한 이유
예를 들어 하나의 서버에서 다음 서비스가 실행된다고 가정해 보겠습니다.
- Nginx
- MySQL
- Redis
- Java Application
Java 프로그램이 CPU를 100% 사용하면 다른 서비스의 응답 속도가 크게 떨어질 수 있습니다.
cgroups를 사용하면
Java
↓
CPU 최대 50%
↓
다른 서비스 보호
처럼 자원 사용량을 제한할 수 있습니다.
cgroups에서 제어 가능한 자원
대표적으로 다음 자원을 관리할 수 있습니다.
| 자원 | 설명 |
|---|---|
| CPU | 사용 비율 제한 |
| Memory | 메모리 사용량 제한 |
| CPUSet | CPU 코어 지정 |
| Block I/O | 디스크 I/O 제한 |
| PIDs | 생성 가능한 프로세스 수 제한 |
| HugeTLB | HugePages 사용량 제한 |
Docker의 --memory, --cpus 옵션도 이러한 기능을 활용합니다.
cgroups v1과 v2
현재 Linux에는 두 가지 버전이 존재합니다.
| 항목 | cgroups v1 | cgroups v2 |
|---|---|---|
| 구조 | Controller별 분리 | 통합 구조 |
| 관리 | 복잡함 | 단순함 |
| 성능 | 양호 | 향상 |
| 현재 사용 | 일부 시스템 | 대부분의 최신 배포판 |
Ubuntu 22.04, RHEL 9 등은 기본적으로 cgroups v2를 사용합니다.
현재 cgroups 확인
현재 마운트 상태를 확인합니다.
mount | grep cgroup
예시
cgroup2 on /sys/fs/cgroup type cgroup2
cgroup2가 표시되면 v2를 사용 중인 것입니다.
cgroups 파일 시스템
cgroups는 /sys/fs/cgroup에서 관리됩니다.
확인
ls /sys/fs/cgroup
예시
cpu.max
memory.max
memory.current
io.max
pids.max
각 파일을 통해 현재 설정과 사용량을 확인할 수 있습니다.
CPU 제한
현재 CPU 제한 확인
cat /sys/fs/cgroup/cpu.max
예시
50000 100000
이는 100ms 동안 최대 50ms의 CPU 사용을 허용한다는 의미입니다.
메모리 제한
현재 메모리 제한 확인
cat /sys/fs/cgroup/memory.max
예시
2147483648
이는 2GB 메모리 제한을 의미합니다.
현재 사용량 확인
cat /sys/fs/cgroup/memory.current
PID 제한
생성 가능한 프로세스 수도 제한할 수 있습니다.
cat /sys/fs/cgroup/pids.max
예시
512
프로세스가 512개를 초과하면 추가 생성이 제한됩니다.
Docker와 cgroups
Docker 컨테이너를 실행할 때 다음과 같이 자원을 제한할 수 있습니다.
docker run \
--memory=2g \
--cpus=2 nginx
내부적으로는 다음과 같이 동작합니다.
Docker
↓
cgroups
↓
Kernel
↓
CPU / Memory 제한
Docker는 별도의 자원 제어 기능을 구현하는 것이 아니라 Linux Kernel의 cgroups를 활용합니다.
Kubernetes와 cgroups
Kubernetes에서도 Pod의 자원을 제한할 수 있습니다.
예시
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
Kubernetes는 이 값을 Container Runtime에 전달하고, Runtime은 cgroups를 통해 실제 제한을 적용합니다.
실무에서 자주 사용하는 명령어
현재 cgroups 확인
mount | grep cgroup
파일 시스템 확인
ls /sys/fs/cgroup
CPU 제한
cat /sys/fs/cgroup/cpu.max
메모리 제한
cat /sys/fs/cgroup/memory.max
현재 메모리 사용량
cat /sys/fs/cgroup/memory.current
PID 제한
cat /sys/fs/cgroup/pids.max
실무 사례
예를 들어 Kubernetes 노드에서 특정 Pod가 메모리를 과도하게 사용하는 상황을 가정해 보겠습니다.
다음 순서로 분석합니다.
- Pod의
limits.memory설정 확인 /sys/fs/cgroup/memory.current에서 실제 사용량 확인memory.max와 비교- OOM 발생 여부 확인
- 필요 시 메모리 제한 조정
이 과정을 통해 특정 컨테이너가 전체 노드의 메모리를 독점하는 것을 방지할 수 있습니다.
자주 묻는 질문
cgroups와 namespace는 같은 기능인가요?
아닙니다. cgroups는 자원 제한과 모니터링을 담당하며, namespace는 프로세스, 네트워크, 파일 시스템 등을 서로 격리하는 기능입니다. Docker는 두 기능을 함께 사용합니다.
Docker 없이도 cgroups를 사용할 수 있나요?
가능합니다. cgroups는 Linux Kernel 기능이므로 Docker와 관계없이 직접 사용할 수 있습니다.
cgroups가 OOM Killer와도 관련이 있나요?
관련이 있습니다. cgroups로 메모리 제한을 설정한 그룹이 제한을 초과하면 해당 그룹 내부에서 OOM이 발생할 수 있으며, 컨테이너 환경에서는 특정 컨테이너만 종료되고 다른 서비스는 계속 동작할 수 있습니다.
마무리
cgroups는 Linux Kernel에서 CPU, 메모리, 디스크 I/O 등 시스템 자원을 효율적으로 제어하기 위한 핵심 기능입니다. 특히 Docker와 Kubernetes의 자원 관리 기반 기술로 사용되며, 멀티서비스 환경에서 안정성과 성능을 유지하는 데 중요한 역할을 합니다. /sys/fs/cgroup 구조와 주요 설정 파일을 이해하면 컨테이너 환경뿐 아니라 일반 Linux 서버에서도 효과적인 자원 관리와 성능 튜닝이 가능합니다.