Cloud발행일 2026. 1. 4.원본 https://blog.naver.com/jword_/224134079241 ↗

[CKA] Appendix 1. Docker vs ContainerD

[CKA] Appendix 1. Docker vs ContainerD — #Docker #ContainerD #개발자의도구들 Docker와 쿠버네티스 Docker 컨테이너 시장을 장악하다. 컨테이...

#Cloud#Naver Blog

#Docker #ContainerD #개발자의도구들

​

Docker와 쿠버네티스

Docker 컨테이너 시장을 장악하다.

컨테이너 기술의 초창기로 돌아가 봅시다.당시에도 rkt(Rocket) 같은 다른 컨테이너 도구들이 있었지만, Docker의 사용자 경험이 워낙 좋았습니다. 컨테이너를 다루는 게 정말 간단해졌거든요. 그 결과 Docker는 컨테이너 시장을 사실상 장악하게 됩니다.

​

​

이후 쿠버네티스가 등장했습니다. 쿠버네티스는 처음부터 Docker를 오케스트레이션하기 위해 만들어졌습니다. 그래서 초기의 쿠버네티스는 Docker하고만 작동하며 이 둘은 매우 긴밀한 관계에 있었습니다.

​

다른 런타임들도 쿠버네티스를 쓰고 싶어졌다.

쿠버네티스가 컨테이너 오케스트레이션 솔루션을 장악해가면서 문제가 생깁니다. 당시 시장에는 도커뿐 아니라 rkt같은 다른 컨테이너 런타임들도 있었습니다. 쿠버네티스는 시장이 커져감에 따라 다양한 컨테이너 런타임들을 지원하고자 하였습니다.

​

그래서 쿠버네티스는 CRI(Container Runtime Interface)라는 표준 인터페이스를 만들었습니다. 표준 인터페이스를 만들었기 때문에 규격만 맞추면 누구든 쿠버네티스의 컨테이너 런타임으로 참여할 수 있게 되었습니다.

​

CRI는 쿠버네티스가 컨테이너 런타임과 통신하는 방식(gRPC API)을 정의한 인터페이스입니다. 런타임이 이 CRI 인터페이스를 구현한 어떤 런타임이든 쿠버네티스 컨테이너 런타임으로 작동할 수 있게됩니다.

​

Docker의 고집

Docker는 CRI가 만들어지기 훨씬 전부터 존재했습니다. 당연히 CRI 표준을 따르지 않았습니다. 그런데 대부분의 사람들이 여전히 Docker를 쓰고 있었기 때문에, 쿠버네티스는 Docker도 계속 지원해야 했습니다. 그래서 쿠버네티스는 DockerShim이라는 것을 만들었습니다.

​

DockerShim은 어댑터로 작동했습니다. Docker가 CRI를 지원하지 않으니, 중간에서 변역만 해주는 역할만 했습니다. 하지만 쿠버네티스 입장에서는 DockerShim을 지속적으로 운영하는 것이 부담이었습니다.

​

DockerShim의 퇴장

쿠버네티스 입장에서는 다른 런타임은 CRI로 잘 작동하는데, Docker만을 위해서 DockerShim을 따로 유지/관리해줘야 했습니다. 이것은 쿠버네티스 입장에서 큰 부담이었습니다.

​

결국 쿠버네티스는 v1.24 버전에서 DockerShim을 완전히 제거하기로 결정합니다.

​

기존 Docker 이미지는?​

쿠버네티스가 DockerShim을 완전히 제거해서 기존 사용자들은 "지금껏 만든 이미지는 어떻게 되는거지?"라는 의문을 품었을 것 입니다.

​

하지만, Docker역시 컨테이너 업계 규격인 OCI를 따르고 있었기 때문에 다른 런타임에서도 이미지는 그대로 사용할 수 있었습니다.

​

ContainerD에 대하여

자, 그러면 Docker 대신 뭘 쓰면 될까요?

사실 Docker는 단순한 컨테이너 런타임이 아닙니다. 여러 도구들의 집합체예요.

javascript 코드 예제
                                    Docker
├── Docker CLI (명령어 도구)
├── Docker API
├── 이미지 빌드 도구
├── 보안 기능
├── ContainerD  ← 실제로 컨테이너를 돌리는 핵심 엔진
└── runC

이 중에서 ContainerD가 바로 컨테이너를 실행하는 핵심 부분입니다. ContainerD는 원래 Docker 안에 포함되어 있었는데, 지금은 독립된 프로젝트로 분리되었습니다. CNCF(Cloud Native Computing Foundation)의 졸업 프로젝트이기도 해요.

​

이 ContainerD는 CRI 표준을 지원합니다. 그렇기에 기존의 DockerShim을 쓰는 구조에서 바로 CotainerD를 쓰는 구조로 변경되었습니다.

javascript 코드 예제
                                    [현재] Kubernetes → DockerShim → Docker → ContainerD → 컨테이너 실행

[현재] Kubernetes → CRI → ContainerD → 컨테이너 실행

CLI 들에 대하여

헷갈리는 CLI 도구들

예전에는 Docker를 설치하여 사용했기 때문에 직접 docker 명령어로 모든 걸 수행했습니다. 하지만, 이제 Docker 없이 ContainerD만 설치하여 사용하는 구조가 되었습니다. 이 경우 어떻게 컨테이너를 제어할 수 있을까요? Docker 명령어를 사용할 수 있을까요?

​

여기서 ctr, nerdctl, crictl 세 가지 도구가 등장합니다.

​

ctr

ContainerD를 설치하면 기본적으로 ctr명령어가 함께 설치됩니다.

javascript 코드 예제
                                    ctr images pull docker.io/library/redis:latest ctr run docker.io/library/redis:latest redis

​

하지만, 이 도구는 거의 쓸 일이 없습니다. ctr은 ContainerD 디버깅 전용으로 만들어졌습니다..그래서 기능이 매우 제한적이며 사용자 친화적이지도 않습니다.

​

nerdctl

nerdctl은 ContainerD 커뮤니티에서 만든 CLI 도구입니다. 이 도구의 가장 큰 장점은 Docker CLI와 거의 동일하게 사용할 수 있습니다.

javascript 코드 예제
                                    # Docker 명령어
docker run -d -p 8080:80 nginx docker ps docker logs <컨테이너>

# nerdctl 명령어
nerdctl run -d -p 8080:80 nginx nerdctl ps nerdctl logs <컨테이너>

기존 docker에서 사용하던 명령어를 nerdctl로 대체하기만 하면 됩니다.

​

crictl

이 도구는 앞의 도구와는 조금 다른 성격을 지니고 있습니다.

​

ContainerD 커뮤니티가 아닌, 쿠버네티스 커뮤니티에서 만들어졌습니다. crictl의 특징은 모든 CRI호환 런타임에서 작동합니다.

​

그리고 가장 중요한 차이점은 crictl은 Pod를 인식할 수 있습니다.

javascript 코드 예제
                                    crictl pods

Docker나 nerdctl은 컨테이너 단위로만 생각하기 때문에 Pod라는 개념 자체가 없습니다. 하지만 crictl은 쿠버네티스용으로 만들어졌기 때문에 Pod 단위로 조회하고 관리할 수 있습니다.

​

​