이번 포스팅에서는 Docker와 ContainerD의 차이점, 그리고 관련된 CLI 도구들(ctr, crictl, nerdctl)에 대해 설명하겠습니다.
초기에는 Docker가 유일한 주요 컨테이너 도구였습니다. Rocket과 같은 다른 도구들도 있었지만, Docker의 사용자 경험이 컨테이너 작업을 매우 간단하게 만들어주었기 때문에 Docker가 가장 지배적인 컨테이너 도구로 자리 잡았습니다. 그 후, Docker를 오케스트레이션하기 위해 Kubernetes가 등장했습니다. 초기 Kubernetes는 Docker만을 오케스트레이션하기 위해 설계되었고, 둘은 긴밀하게 결합되어 있었습니다.
Kubernetes가 인기를 끌면서 다른 컨테이너 런타임들도 Kubernetes와 함께 작동하기를 원하게 되었습니다. 그래서 Kubernetes는 CRI(Container Runtime Interface)라는 인터페이스를 도입했습니다. CRI는 OCI(Open Container Initiative) 표준을 준수하는 모든 컨테이너 런타임이 Kubernetes와 함께 작동할 수 있게 해줍니다.
OCI는 이미지 사양과 런타임 사양으로 구성됩니다. 이미지 사양은 이미지가 어떻게 빌드되어야 하는지에 대한 기준을 정의하고, 런타임 사양은 컨테이너 런타임이 어떻게 개발되어야 하는지에 대한 기준을 정의합니다. 이 표준을 따르면 누구나 Kubernetes와 호환되는 컨테이너 런타임을 만들 수 있습니다.
Docker는 CRI가 도입되기 전에 만들어졌기 때문에 CRI 표준을 지원하지 않았습니다. 하지만 Docker는 여전히 지배적인 컨테이너 도구였기 때문에 Kubernetes는 Docker도 계속 지원해야 했습니다. 이를 위해 Kubernetes는 Docker Shim이라는 임시 방법을 도입했습니다. Docker Shim은 CRI 없이도 Docker를 지원할 수 있도록 해주었지만, 이는 불필요한 노력과 복잡성을 추가했습니다.
결국 Kubernetes 1.24 버전에서는 Docker Shim을 완전히 제거하고 Docker에 대한 지원을 중단하기로 결정했습니다. 하지만 Docker가 빌드한 이미지는 OCI 표준을 따르기 때문에 계속해서 사용할 수 있습니다.
ContainerD는 Docker의 일부였지만, 이제는 독립적인 프로젝트로 CNCF의 정회원으로 졸업 상태입니다. ContainerD는 CRI 호환 가능하며, Kubernetes와 직접 작동할 수 있습니다. Docker를 설치하지 않고도 ContainerD를 단독으로 설치할 수 있으며, Docker의 다른 기능이 필요하지 않다면 ContainerD만 설치해도 됩니다.
ContainerD를 설치하면 CTR이라는 명령줄 도구가 함께 제공됩니다. 이 도구는 ContainerD를 디버깅하기 위해 만들어졌으며, 기능이 제한적이고 사용자 친화적이지 않습니다. CTR 명령은 기본적인 컨테이너 관련 작업을 수행하는 데 사용되지만, 프로덕션 환경에서는 사용되지 않습니다.
CTR보다 더 나은 대안으로 추천되는 도구는 nerdctl입니다. Nerdctl은 ContainerD를 위한 Docker와 유사한 명령줄 도구로, Docker가 지원하는 대부분의 옵션을 지원하며 ContainerD의 새로운 기능에 접근할 수 있는 추가 이점이 있습니다. Nerdctl은 Docker CLI와 매우 유사하게 작동하므로, Docker 대신 nerdctl을 사용하면 됩니다.
Crictl은 Kubernetes 커뮤니티에서 제공하는 명령줄 유틸리티로, 주로 CRI 호환 컨테이너 런타임과 상호작용하기 위해 사용됩니다. 이는 디버깅 목적으로 주로 사용되며, Kubernetes 노드에서 컨테이너를 문제 해결하고 로그를 확인하는 데 유용합니다.
Docker와 ContainerD, 그리고 관련 CLI 도구들 간의 차이점을 정리하면 다음과 같습니다: