13년차의 서버실

서버, 인프라, 홈랩 기술 블로그

[태그:] cgroups

  • 컨테이너는 어떻게 격리되나 — namespaces와 cgroups 원리

    “컨테이너는 가벼운 VM”이라고들 하지만, 사실 둘은 원리가 완전히 다릅니다. 컨테이너는 가상 머신이 아니라 “격리된 프로세스”일 뿐입니다. 그 격리를 만드는 두 가지 리눅스 커널 기능 — namespaces와 cgroups — 를 이해하면 LXC·Docker가 왜 그렇게 가벼운지, 그리고 왜 Docker-in-LXC에 특별한 설정이 필요한지가 보입니다.

    1. 컨테이너 vs VM — 근본 차이

    VM 컨테이너
    격리 방식 하드웨어 가상화 커널 기능(격리된 프로세스)
    커널 게스트마다 별도 호스트와 공유
    부팅 OS 부팅(수십 초) 프로세스 시작(즉시)
    오버헤드 큼 거의 없음

    컨테이너는 호스트 커널을 그대로 공유하면서, “이 프로세스는 자기만의 세상에 있는 것처럼” 보이게 속입니다. 그 속임수의 두 축이 namespaces와 cgroups입니다.

    2. namespaces — “무엇을 볼 수 있는가”

    namespace는 프로세스가 보는 시야를 격리합니다. 종류별로 각각 다른 자원을 가립니다.

    namespace 격리 대상
    PID 프로세스 목록(자기 PID 1)
    NET 네트워크(자기 IP·인터페이스)
    MNT 파일시스템 마운트
    UTS 호스트명
    IPC 프로세스 간 통신
    USER 사용자·권한(UID 매핑)

    그래서 컨테이너 안에서 ps를 치면 자기 프로세스만 보이고, 자기만의 IP를 갖습니다. 실제로는 호스트의 한 프로세스일 뿐인데도요. USER namespace가 바로 “unprivileged 컨테이너”의 핵심 — 컨테이너의 root를 호스트의 비특권 사용자로 매핑해 보안을 높입니다.

    3. cgroups — “얼마나 쓸 수 있는가”

    namespace가 “시야”라면, cgroups(control groups)는 “자원 사용량 제한”입니다.

    • CPU: 이 컨테이너는 코어 2개까지
    • 메모리: 512MB 넘으면 제한
    • I/O: 디스크 대역폭 제한

    Proxmox에서 LXC에 cores·memory를 지정하면, 내부적으로 cgroups가 그 한도를 강제합니다. vCPU 오버커밋이 가능한 것도 cgroups가 실제 사용량을 조율하기 때문입니다.

    4. 그래서 Docker-in-LXC가 까다롭다

    컨테이너가 이 커널 기능들에 의존하다 보니, 컨테이너 안에서 또 컨테이너(LXC 안 Docker)를 돌리려면 커널 기능 접근을 열어줘야 합니다.

    • nesting=1: 중첩된 namespace 생성 허용
    • keyctl=1: Docker가 쓰는 커널 키링 접근 허용

    원리를 알고 나면 이 플래그들이 왜 필요한지 자연스럽게 이해됩니다 — 컨테이너의 격리 메커니즘을 한 겹 더 쌓는 것이니까요.

    5. 정리

    컨테이너 = namespaces(시야 격리) + cgroups(자원 제한)로 만든 “격리된 프로세스”입니다. VM처럼 커널을 통째로 복제하지 않으니 가볍고 빠른 거죠. 이 원리 하나를 잡으면 LXC·Docker의 동작, unprivileged의 의미, nesting 플래그의 이유가 전부 하나로 꿰어집니다.