Container and OS-Level Virtualization

컨테이너 개념, 동작 원리(namespace, cgroup), VM과의 차이


🎯 컨테이너란?

컨테이너(Container): 애플리케이션과 그 실행 환경(라이브러리, 설정 등)을 패키징하여 격리된 공간에서 실행하는 기술

핵심 특징:

  • Host OS의 커널을 공유
  • 각 컨테이너는 독립된 프로세스 공간
  • VM처럼 별도 OS를 부팅하지 않음 → 가볍고 빠름

🆚 VM vs Container

flowchart TB
    subgraph VM["Virtual Machine"]
        direction TB
        VA[App App App]
        VB[Bins/Libs]
        VC[Guest OS]
        VD[Hypervisor]
        VE[Host OS]
        VF[Hardware]
        VA --> VB --> VC --> VD --> VE --> VF
    end
    
    subgraph Container["Container"]
        direction TB
        CA[App App App]
        CB[Bins/Libs]
        CC["(커널 공유)"]
        CD[Container Engine]
        CE["Host OS (Kernel)"]
        CF[Hardware]
        CA --> CB --> CC --> CD --> CE --> CF
    end
구분VMContainer
격리 방식하드웨어 가상화OS 수준 격리
커널각자 보유Host와 공유
오버헤드큼 (Guest OS 전체)작음 (프로세스 수준)
시작 시간분 단위초 단위
이미지 크기GBMB
밀도낮음 (수십 개)높음 (수백~수천 개)
격리 강도강함상대적으로 약함

💡 컨테이너를 “가상화”라고 부르기도 하지만, 엄밀히는 OS 수준 격리(OS-level isolation) 또는 **컨테이너화(Containerization)**가 더 정확한 표현임.


⚙️ 컨테이너의 핵심 기술 (Linux)

컨테이너는 Linux 커널의 두 가지 핵심 기능을 활용함.

Namespace

프로세스가 볼 수 있는 시스템 자원의 범위를 격리하는 메커니즘

각 컨테이너는 자신만의 namespace를 가져서 마치 독립된 시스템처럼 보임.

Namespace격리 대상설명
PID프로세스 ID컨테이너 내부에서 PID 1부터 시작
NET네트워크독립된 네트워크 인터페이스, IP, 포트
MNT마운트 포인트독립된 파일시스템 뷰
UTS호스트명독립된 hostname
IPCIPC 자원독립된 세마포어, 메시지 큐
USER사용자 ID컨테이너 내부 root ≠ Host root
# 현재 프로세스의 namespace 확인
ls -la /proc/$$/ns/
 
# 특정 namespace에서 명령 실행 (unshare)
sudo unshare --pid --fork --mount-proc /bin/bash
# → 새 PID namespace에서 bash 실행, PID 1이 됨

Cgroup (Control Group)

프로세스가 사용할 수 있는 자원의 양을 제한하는 메커니즘

자원설명
CPUCPU 시간 제한
Memory메모리 사용량 제한
I/O디스크 I/O 대역폭 제한
Network네트워크 대역폭 제한
# cgroup 정보 확인
cat /proc/$$/cgroup
 
# Docker 컨테이너의 메모리 제한 설정 예시
docker run -m 512m nginx  # 메모리 512MB 제한

Namespace + Cgroup = Container

flowchart TB
    subgraph Container["Container"]
        subgraph NS["Namespace (격리)"]
            NS1["PID: 자체 프로세스 트리"]
            NS2["NET: 자체 네트워크 스택"]
            NS3["MNT: 자체 파일시스템 뷰"]
        end
        subgraph CG["Cgroup (자원 제한)"]
            CG1["CPU: 50% 제한"]
            CG2["Memory: 512MB 제한"]
        end
    end
    
    Kernel["Host Linux Kernel"]
    
    Container -->|커널 공유| Kernel

🐳 컨테이너 런타임

실제로 컨테이너를 생성하고 실행하는 소프트웨어.

계층 구조

flowchart TB
    subgraph High["High-level Runtime"]
        Docker["Docker, Podman"]
    end
    
    subgraph Mid["Container Runtime"]
        Containerd["containerd, CRI-O"]
    end
    
    subgraph Low["Low-level Runtime (OCI)"]
        Runc["runc, crun"]
    end
    
    subgraph Kernel["Linux Kernel"]
        NS["namespace, cgroup"]
    end
    
    High --> Mid --> Low --> Kernel
    
    style High fill:#e1f5fe
    style Mid fill:#fff3e0
    style Low fill:#fce4ec
    style Kernel fill:#e8f5e9

주요 런타임

런타임레벨설명
DockerHigh가장 유명, CLI/이미지 빌드/레지스트리 통합
PodmanHighDocker 호환, 데몬리스, rootless
containerdMidDocker에서 분리, Kubernetes 기본 런타임
CRI-OMidKubernetes 전용 경량 런타임
runcLowOCI 표준 구현체, 실제 컨테이너 생성

📦 컨테이너 이미지

이미지(Image): 컨테이너 실행에 필요한 모든 것을 패키징한 읽기 전용 템플릿

레이어 구조

이미지는 여러 레이어가 쌓인 형태임. 각 레이어는 변경사항만 저장함.

flowchart TB
    subgraph Image["Container Image"]
        L4["Layer 4: App code"]
        L3["Layer 3: pip install"]
        L2["Layer 2: Python"]
        L1["Layer 1: Ubuntu"]
        
        L4 --> L3 --> L2 --> L1
    end
    
    L4 -.- N4["← 내 애플리케이션"]
    L3 -.- N3["← 패키지 설치"]
    L2 -.- N2["← 런타임"]
    L1 -.- N1["← 베이스 이미지"]

장점:

  • 레이어 공유로 저장 공간 절약
  • 변경된 레이어만 다시 빌드/전송
  • 캐싱으로 빌드 속도 향상

이미지 vs 컨테이너

구분이미지컨테이너
상태정적 (읽기 전용)동적 (실행 중)
비유클래스인스턴스
저장레지스트리호스트 메모리/디스크
# 이미지 = 템플릿
docker pull nginx
 
# 컨테이너 = 이미지로부터 생성된 인스턴스
docker run nginx  # 이미지에서 컨테이너 생성 및 실행

🔒 컨테이너 보안 고려사항

컨테이너는 커널을 공유하므로 VM보다 격리 수준이 낮음.

주요 고려사항:

항목설명
커널 공유커널 취약점이 모든 컨테이너에 영향
root 권한컨테이너 내 root가 Host에 영향줄 수 있음
이미지 신뢰검증되지 않은 이미지 사용 위험

보안 강화 방법:

  • rootless 컨테이너 사용 (Podman 기본)
  • User namespace 활용
  • seccomp, AppArmor, SELinux 적용
  • 신뢰된 베이스 이미지 사용
  • 최소 권한 원칙 적용

🤔 언제 VM, 언제 Container?

상황선택이유
다른 OS 실행 필요VM컨테이너는 Host 커널 공유
강한 보안 격리 필요VM하드웨어 수준 격리
레거시 애플리케이션VM전체 OS 환경 필요
마이크로서비스Container빠른 배포, 높은 밀도
CI/CD 파이프라인Container빠른 시작, 일관된 환경
클라우드 네이티브Container오케스트레이션 (K8s)

💡 현대 환경에서는 VM 위에 컨테이너를 돌리는 경우도 많음. 클라우드 VM(EC2 등) 안에서 Docker/Kubernetes를 실행하는 구조.


🔗 관련 포스트


🔗 참고 자료