50줄 코드로 컨테이너를 직접 만들어보자!
chroot 시스템 콜(System Call)을 활용하여 컨테이너 내부에서 호스트 파일 시스템(Host File System) 접근을 차단, 보안 강화(Security Enhancement)
Ubuntu rootfs를 제공하여 컨테이너 내에서 쉘(Shell) 실행 환경을 구축하고, 실행 환경(Execution Environment) 독립성 확보
PID 네임스페이스(PID Namespace)와 /proc 마운트(Mount)를 통해 컨테이너 내부에서 프로세스(Process) 식별 및 관리, 프로세스 격리(Process Isolation) 구현
cgroups를 사용하여 컨테이너의 자원 사용량 제한, 자원 관리(Resource Management)를 통해 호스트 시스템(Host System) 안정성 유지
chroot를 이용한 파일 시스템 격리
본문에서는 chroot(Change Root) 시스템 콜을 사용하여 컨테이너의 루트 디렉터리(/)를 변경, 호스트 파일 시스템(Host File System) 접근을 제한한다. chroot는 프로세스(Process)의 관점에서 파일 시스템의 루트를 변경하여, 컨테이너 내부에서 호스트의 파일에 접근하는 것을 막는다.
격리된 환경(Isolated Environment) 구축: chroot를 통해 컨테이너는 자신만의 파일 시스템 뷰(File System View)를 가지며, 호스트 시스템의 파일에 접근할 수 없다.
보안 강화(Security Enhancement): chroot는 컨테이너 탈출 시도를 방지하여, 호스트 시스템의 보안을 강화하는 핵심 기술이다.
단점: chroot는 파일 시스템 격리만 제공하며, 프로세스 격리(Process Isolation)를 위해서는 네임스페이스(Namespace) 기술과 함께 사용해야 한다.
Ubuntu rootfs를 이용한 쉘(Shell) 실행 환경 구성
글에서는 컨테이너 내에서 쉘(Shell)을 실행하기 위해 Ubuntu rootfs를 제공하는 과정을 설명한다. rootfs는 쉘 실행에 필요한 기본 바이너리(Binary)와 디렉터리 구조를 포함하는 파일 시스템(File System)이다.
Docker를 활용한 rootfs 생성: Docker를 사용하여 Ubuntu 컨테이너를 생성하고, 해당 컨테이너의 파일 시스템을 압축 파일(ubuntu.tar)로 추출한다.
chroot 적용: 추출한 rootfs를 컨테이너의 루트 디렉터리로 설정하여, 컨테이너 내에서 쉘 명령어를 실행할 수 있도록 한다.
/bin/bash 실행: rootfs 내에 /bin/bash 바이너리가 존재하므로, 컨테이너 내부에서 쉘을 실행할 수 있다. rootfs는 컨테이너의 최소 실행 환경(Minimum Execution Environment)을 제공한다.
PID 네임스페이스(Namespace)와 /proc 마운트를 통한 프로세스 격리
본문에서는 PID 네임스페이스(PID Namespace)와 /proc 파일 시스템(File System)을 사용하여 컨테이너 내부의 프로세스(Process)를 격리하는 방법을 설명한다. PID 네임스페이스는 각 컨테이너에 독립적인 PID 공간을 제공하고, /proc는 실행 중인 프로세스 정보를 제공한다.
PID 네임스페이스 생성: CLONE_NEWPID 플래그(Flag)를 사용하여 새로운 PID 네임스페이스를 생성, 컨테이너 내부에서 PID 1번 프로세스를 갖도록 한다.
/proc 마운트: 컨테이너 내부에서 /proc 파일 시스템을 마운트하여, ps 명령어를 통해 실행 중인 프로세스 정보를 확인할 수 있도록 한다.
프로세스 격리: PID 네임스페이스와 /proc를 통해 컨테이너는 호스트 시스템의 프로세스에 영향을 받지 않고, 독립적으로 프로세스를 관리한다.
cgroups를 활용한 자원 제한
글에서는 cgroups(Control Groups)를 사용하여 컨테이너의 자원 사용량을 제한하는 방법을 설명한다. cgroups는 리눅스 커널(Linux Kernel)의 기능으로, 프로세스(Process) 그룹의 자원 사용을 제어한다.
cgroup 생성: /sys/fs/cgroup/pids 디렉터리에 새로운 디렉터리를 생성하여, 컨테이너에 대한 cgroup을 생성한다.
자원 제한 설정: pids.max 파일에 최대 프로세스 수를 기록하여, 컨테이너가 생성할 수 있는 프로세스 수를 제한한다.
프로세스 할당: cgroup.procs 파일에 현재 프로세스 ID(PID)를 기록하여, 해당 프로세스를 cgroup에 할당한다.
결과적으로 cgroups는 컨테이너가 호스트 시스템의 자원을 과도하게 사용하는 것을 방지하고, 안정적인 시스템 운영(Stable System Operation)을 가능하게 한다.
컨테이너 구현의 핵심 원리
본문은 컨테이너가 네임스페이스(Namespace), chroot, cgroups를 활용하여 구현됨을 강조한다. 이 기술들은 컨테이너의 핵심 기능을 제공하며, 컨테이너 기술의 근본적인 이해를 돕는다.
네임스페이스: 프로세스 격리(Process Isolation)를 위한 핵심 기술로, 컨테이너에 독립적인 시스템 자원 뷰(System Resource View)를 제공한다.
chroot: 파일 시스템 격리(File System Isolation)를 통해 컨테이너의 보안을 강화하고, 호스트 시스템의 파일 접근을 제한한다.
cgroups: 자원 관리(Resource Management)를 위한 기술로, 컨테이너의 자원 사용량을 제한하여 호스트 시스템의 안정성을 유지한다.
결론적으로, 컨테이너는 이러한 기술들을 조합하여 가볍고(Lightweight), 격리된(Isolated) 실행 환경을 제공한다.