Containerization Part.2 - 컨테이너 구조
Containers: cgroups, Linux kernel namespaces, ufs, Docker, and intro to Kubernetes pods를 정리한 글입니다.
컨테이너 소개
컨테이너는 호스트 시스템에서 실행되는 일련의 격리된(Isolated) 프로세스들입니다.
대부분의 경우 컨테이너는 실제로 Linux OS처럼 보이고 동작합니다.
이 격리(Isolation)는 Linux의 커널 기능인 Cgroups
, Namespaces
, Union-capable FS
등으로 구현됩니다.
다음은 컨테이너의 구조입니다.
컨테이너는 호스트의 시스템 리소스를 사용합니다.
리소스 사용을 측정하고, 제한하기 위해 Cgroups
를 사용하고, 커널 리소스를 격리하기 위해 Namespaces
를 사용합니다.
이제 앞에서 말한 각 커널 기능 Namespaces
, Cgroups
, Union-capable FS(Overlay FS)
에 대해 소개하겠습니다.
Namespaces
Namespaces
는 전역 시스템 리소스를 추상화하여 Namespaces
내의 프로세스에 고유한 전역 리소스 인스턴스가 격리된 것처럼 보이게 합니다.
(From: namespaces(7) - Linux manual page)
Namespaces
의 종류는 다음과 같습니다:
pid
namespace: 프로세스 격리net
namespace: network 인터페이스 격리ipc
namespace: IPC 리소스 접근 관리mnt
namespace: 파일 시스템 마운트 포인트 관리uts
namespace: 커널과 버전 식별자 격리
각 프로세스는 위의 각 종류마다 하나의 Namespaces
에 포함되어 있습니다.
Cgroups
Cgroups
는 리소스 사용량을 측정(metering)하거나 제한(limiting)합니다.
Union-capable(Overlay) Filesystem
Union-capable file system(union mount, overlay)
은 여러 디렉토리를 하나의 디렉토리로 보이도록 결합하는 방법입니다.
즉, union mount
는 여러 개의 파일 시스템을 mount 하지만 하나의 파일 시스템만 mount 된 것처럼 사용할 수 있습니다.
Docker 이미지는 파일 시스템들의 레이어(layer)들로 구성되었습니다.
일반적인 Linux 를 시작하기 위해서는 두 개의 파일 시스템 bootfs
, rootfs
이 필요합니다.
bootfs
(boot 파일 시스템)은 일반적인 Linux boot 파일 시스템입니다.
부트 로더와 커널을 가지고 있고, 컨테이너가 부팅되면 메모리로 이동한 후 unmount 됩니다.
rootfs
은 유닉스 기반 OS의 일반적인 디렉토리 구조(/dev, /proc, /bin, /etc, /lib, /usr and /tmp, 등)와 앱을 실행하기 위해 필요한 모든 환경설정 파일 및 바이너리 및 라이브러리 파일 등을 포함합니다.
rootfs
에는 실제 OS가 설치됩니다. 원래 Linux 에서 rootfs
은 처음에 read-only 로 mount 된 후 integrity 체크 후에 read-write 로 바뀌지만 Docker에서는 계속 read-only 모드로 유지됩니다. read-write 모드로 변환하지 않는 이유는 Docker가 union mount
를 사용해서 read-only 파일 시스템들을 root 파일 시스템 위로 쌓는 구조이기 때문입니다.
Docker 구조에서는 이러한 파일 시스템 하나 하나가 바로 이미지(image)입니다.
이미지들을 레이어 구조로 쌓아 마지막에는 union mount
를 사용하여 하나의 파일 시스템처럼 보이게 합니다.
모든 read-only 파일 시스템들이 mount 되고 docker 컨테이너가 시작 될 때 마지막으로 read-write 파일 시스템을 layer 맨 위에 mount 합니다.
이 파일 시스템에서 컨테이너가 필요한 프로세스를 생성하고 실행합니다.
이러한 패턴을 copy on write
라고 합니다.
copy on write
구조는 Dockerfile 을 이용해 docker 이미지를 빌드할 때 효과적입니다.
Docker 이미지를 빌드할 때 Dockerfile 내 각각의 명령이 바로 이미지 파일 시스템이 됩니다.
그러므로 빌드할 때 처음부터 모두 빌드하지 않고 바뀐 파일시스템만 mount 하므로 효과적이고 빠르게 빌드할 수 있으며 빌드가 도중에 실패하더라도 마지막으로 성공한 명령은 빌드가 되어있는 상태이므로 그 이미지에 쉘로 접속해서 디버깅할 수 있습니다.
댓글남기기