본문 바로가기

AI Feed
Tech & Product/AI, 더 깊게

Docker의 등장 배경과 구조

Docker 등장 배경

chroot

chroot는 ‘root 디렉토리(/)'를 변경하는 기능입니다. 프로세스의 root 디렉토리를 변경하여 해당 프로세스가 chroot로 설정한 root 디렉토리 밖의 파일이나 디렉토리에 접근하는 것을 제한합니다. 하지만 chroot는 파일이나 디렉토리에 대한 접근 권한만 제어하기 때문에 완전한 가상화가 아니었고 설정 방법도 복잡하여 여러 가지 제약이 있었습니다.

 

LXC

이후 cgroups와 namespace기술을 이용한 컨테이너 기술의 시초인 LXC(Linux Container)라는 시스템 레벨의 가상화가 탄생하였고, OS 자체를 가상화하는 VM과는 다르게 해당 기술은 호스트 OS의 커널을 공유하고 단순히 하나의 격리 되어 있는 프로세스로써 동작하기 때문에 컨테이너라고 구분 지어 부르게 됩니다.

이미지 출처 : https://www.blackmagicboxes.com/?page_id=64

LXC가 격리된 환경을 제공하기는 했지만, 실질적으로 그 안에서 서비스를 운영하기 위한 기능들은 부족했기 때문에 이미지, 컨테이너 관리 등의 다양한 기능을 제공하는 Docker가 등장하게 되었습니다.


Docker 구조

Docker는 처음에는 LXC를 기반으로 구현되었지만 0.9버전부터는 LXC를 libcontainer로 대체하게 되었고, libcontainer가 runC로 변경되면서 현재는 runC를 사용하고 있습니다. LXC, libcontainer, runC 등은 cgroups와 namespace를 표준으로 정의한 OCI(Open Container Initative) 런타임 스펙을 구현한 컨테이너 기술의 구현체입니다. 아래는 현재 docker의 구조입니다.

이미지 출처 : https://ikcoo.tistory.com/194

dockerd

dockerd는 container build, security, volume, networking, secrets 등과 같은 docker의 기능을 RESTful API로 제공하여 docker-cli와 같은 클라이언트에서 사용할 수 있게 합니다. docker engine이라고 부르기도 합니다.

 

containerd

containerd는 network, volume과 같은 것들은 dockerd에게 맡기고 오로지 컨테이너에 대한 기능들(컨테이너 생성, 이미지 pull, 컨테이너 라이프 사이클 관리 등)만을 수행하는 데몬 프로세스입니다.

 

containerd-shim

containerd가 컨테이너 생성에 관여하기는 하지만 실제로 컨테이너를 생성하는 것은 containerd-shim과 runC입니다. containerd가 containerd-shim을 통해 runC를 호출하여 컨테이너를 생성하는데, runC는 컨테이너를 생성해주고 종료됩니다. 그래서 생성된 컨테이너의 stdin/out/err와 같은 해당 컨테이너에 대한 관리가 필요한데 그 역할을 containerd-shim이 담당합니다.

 

runC

runC는 OCI 런타임 스펙을 구현하고 있는 저수준 컨테이너 런타임으로, namespace와 cgroups를 통해 실제로 컨테이너를 생성하는 역할을 수행합니다. cgroups는 cpu, memory, network bandwidth 등의 자원 할당에 대한 기능을, namespace는 시스템의 리소스들(user, 파일, 네트워크, 프로세스 등)을 가상화(격리)하는 기능을 제공합니다.


이처럼 컨테이너 기술은 cgroups와 namespace를 이용하여 구현되어 있고, cgroups에서는 GPU에 대한 제어는 제공하지 않기 때문에 컨테이너 기술을 사용하는 Kubernetes에서도 기본적으로는 GPU를 할당할 수 없지만, Ten의 Coaster를 사용하면 Kubernetes에서 GPU를 할당할 수 있습니다. ^-^