Docker

start container

euidong 2021. 4. 11. 22:36

Docker의 구조

Docker는 초기에는 하나의 daemon에 모든 기능이 합쳐져 있었지만, refactoring을 거치며 다음과 같은 구조를 가지게 되었다.

 

docker의 구조

 

Container start

따라서, docker에서 container를 시작한다는 것은 다음과 같은 수행한다는 것을 의미합니다.

 

  1. 사용자가 docker client에 CLI로 docker container run 명령어를 입력합니다.
  2. docker client는 이를 Docker daemon이 제공하는 Docker API로 변환합니다.
  3. docker daemon의 API Endpoint로 요청이오면, containerd에게 OCI bundle과 제공된 ID에 기반하여 새로운 container를 실행시킬 것을 명령합니다.
  4. containerd는 이를 받아서 runc에게 명령을 내립니다.
  5. container를 build하고 실행시킵니다. (runc는 container가 시작되면 종료되고, shim이 container의 부모 process가 됩니다.

 

단어 설명

LXC

Linux container의 줄임말로, container의 cgroup과 같은 작업을 수행하는 docker의 필수도구이다.
초기에 Docker는 LXC에 대한 의존성으로 인해 문제를 겪고 있었다. 이러한 구조는 다양한 platform을 동시에 제공하기에 문제가 될 가능성이 컸고, 개발 전역에 걸쳐 외부 tool에 의존하는 환경은 큰 위험으로 작용할 수 밖에 없었다. 따라서, docker는 libcontainer라는 자체 기술을 만들었다.

OCI

Open Container Initiative(OCI)는 container와 관련된 2가지 세부 사항을 정의합니다.

  • Image Spec
  • Container runtime Spec

계속해서 표준이 업데이트 되고 있으며, 2016년도 부터 이 표준에 따라서 Docker가 설계되고 있다. 이에 따라 다른 container 기술도 이 표준에 맞춰 개발하고 있다. 이러한 표준을 맞춰주는 역할을 docker에서는 runc가 수행한다.

runc

runc는 작고, 가벼운 libcontainer를 위한 CLI wrapper이다. 이는 container 생성이라는 단일한 목적을 갖고 탄생했다. 생성된 container는 runc의 child가 된다.

shim

runc는 container를 생성하고, 종료된다. runc의 child인 container는 shim에게 넘겨진다. 이에 따라 shim은 container에 대한 STDIN과 STDOUT를 open을 유지하며, 재실행 시에도 pipe가 종료로 인해서 종료되지 않게 된다. 그리고 daemon에게 container의 상태를 보고 한다.

containerd

docker daemon으로 부터 container 실행 로직을 분리하여 만든 모듈이다. 이것의 존재 목적은 container의 실행 lifecycle을 관리하는 것이었다. 하지만, 시간이 지나며 image pull, volum, 그리고 network 등을 관리하는 기능까지 추가되었다. 이러한 기능이 추가된 것은 후에 kubernetes와 같은 장치들에 의해서 docker를 거치지 않고 쉽게 사용하기 위해서이다.