728x90
Docker vs containerd vs CRI, 그리고 CLI 도구들 정리
💡 결론부터:
Kubernetes 런타임은 Docker 엔진이 아니라 containerd 같은 CRI 런타임을 사용하고,
운영/일반 사용은 nerdctl, 디버깅은 crictl 쪽이 핵심이다.
▶️ 컨테이너 런타임 흐름 (역사)
- 초창기 컨테이너 시대엔 Docker가 사실상 표준처럼 널리 쓰임
- Kubernetes도 처음엔 Docker를 오케스트레이션하도록 설계되어 K8s ↔ Docker가 강결합됨
- 이후 Rocket(rkt) 등 다른 런타임들도 Kubernetes에서 쓰고 싶어짐
- 그래서 Kubernetes가 CRI(Container Runtime Interface) 를 도입
- → “Kubernetes가 어떤 런타임이든 동일한 인터페이스로 붙을 수 있게” 표준화
▶️ OCI 표준이란?
- OCI(Open Container Initiative): 컨테이너 생태계의 표준
- 크게 2가지 스펙
- Image Spec: 이미지를 어떻게 만들고 표현할지
- Runtime Spec: 컨테이너 런타임이 어떻게 동작해야 하는지
✅ 핵심: Docker로 만든 이미지도 OCI 이미지 스펙을 따르므로,
Kubernetes에서 Docker 런타임 지원이 빠져도 이미지는 계속 잘 돈다.
▶️ CRI 도입 후 Docker는 어떻게 됐나? (Dockershim)
- Docker는 CRI 도입 이전에 만들어져서 CRI 표준을 직접 지원하지 않음
- 그런데 당시엔 Docker 사용자가 너무 많아서 Kubernetes가 Docker를 바로 버릴 수 없었음
- 그래서 임시로 Dockershim(도커 심)을 두고 Docker를 계속 지원
- 하지만 Dockershim 유지가 불필요한 복잡성을 만들었고,
- Kubernetes v1.24에서 Dockershim이 완전히 제거
- 결과: Docker “엔진(runtime)”은 Kubernetes에서 공식 지원 대상에서 빠짐
- 단, Docker로 빌드한 이미지(OCI 기반)는 계속 사용 가능
▶️ Docker vs containerd 관계
- Docker는 단순 런타임이 아니라 “여러 구성요소 묶음”
- Docker CLI, Docker API, 이미지 빌드 도구 등
- 내부적으로 실제 런타임 계층은 runc 같은 걸 사용
- containerd는 원래 Docker 내부 구성요소였지만,
- 지금은 독립 프로젝트
- CNCF 졸업(Graduated) 프로젝트
- 그래서 요즘은 Docker 전체를 설치하지 않고 containerd만 설치하는 구성이 흔함
- (Docker의 빌드/CLI 기능이 꼭 필요하지 않다면)
CLI 도구 3종 비교 (CTR / nerdctl / crictl)
✅ 한 번에 보는 표
도구 누가 만듦 무엇과 대화함 목적 추천 사용처
| ctr | containerd 커뮤니티 | containerd 직접 | 디버깅용(기능 제한/불친절) | 되도록 안 씀(내부 점검/디버깅용) |
| nerdctl | containerd 커뮤니티 | containerd 직접 | Docker CLI 대체(일반 사용) | 노드에서 컨테이너 직접 다룰 때 “실사용” |
| crictl | Kubernetes 커뮤니티 | CRI 런타임 전반 | K8s 관점 디버깅/점검 | 노드 트러블슈팅(로그/컨테이너/파드 확인) |
▶️ ctr (containerd 기본 제공)
- containerd 설치하면 같이 들어오는 CLI
- containerd 디버깅 전용
- 기능 제한 + 사용자 친화적이지 않음
- 이미지 pull, 컨테이너 실행 같은 건 가능하지만 운영/일반 사용 비추
✅ 결론: “있긴 한데 디버깅용, 평소엔 거의 안 씀”
▶️ nerdctl (Docker 대체용, 실사용 추천)
- containerd용 Docker 같은 CLI
- Docker와 명령 형태가 매우 유사함
- 예: docker run ↔ nerdctl run
- 장점
- Docker 옵션 대부분 지원
- containerd의 최신 기능(예: lazy pulling, P2P 배포, 이미지 서명/검증 등) 접근 가능
- Kubernetes 네임스페이스 등 Docker에 없는 부분도 지원
✅ 결론: “노드에서 Docker 대신 쓰기 가장 좋은 실사용 CLI”
▶️ crictl (Kubernetes 관점 디버깅 도구)
- CRI 호환 런타임과 상호작용하는 CLI
- Kubernetes 커뮤니티에서 개발/유지
- 특징
- 컨테이너뿐 아니라 Pod도 인식 (crictl pods 같은 식)
- 문제 해결할 때(로그, 상태 확인) 유용
주의점 (중요)
- crictl로 컨테이너를 직접 만들면
- Kubelet이 “내가 만든 게 아닌 컨테이너/파드”로 인지해서
- 정책에 따라 삭제해버릴 수 있음
- 그래서 crictl은 디버깅/점검 용도로만 쓰는 게 안전
✅ 결론: “운영에서 장애 분석/노드 점검용 도구”
▶️ crictl 런타임 엔드포인트(소켓) 설정
- 환경에 런타임이 여러 개 있거나 특정 런타임을 찍고 싶으면 설정 필요
- 방법
- -runtime-endpoint 옵션 사용
- 또는 환경변수 CONTAINER_RUNTIME_ENDPOINT 설정
✅ 포인트: “어느 런타임 소켓에 붙을지 지정해줘야 한다”
OCI / CRI / containerd / OCI runtime 비교표
구분 정체 누가/어디서 씀 역할(무엇을 함) 쿠버네티스에서 위치
| OCI | 표준(Spec) | 컨테이너 생태계 전반 | 이미지 포맷(이미지 스펙) + 컨테이너 실행 방식(런타임 스펙) 표준을 정의 | “규칙/규격” (실행 주체는 아님) |
| CRI | 인터페이스(API 규격) | Kubernetes(kubelet) ↔ 런타임 | kubelet이 런타임에게 Pod/컨테이너 생성·삭제·로그 등 요청하는 통신 규격 | kubelet과 런타임 사이 |
| containerd | 런타임(관리자, 구현체) | Kubernetes, 서버/노드 런타임 | 이미지 pull/저장, 스냅샷 준비, 컨테이너 lifecycle 관리, 아래 OCI runtime 호출 | CRI를 받아 실행 준비 후 OCI runtime 호출 |
| OCI runtime (runc/crun/kata/runsc) | 실행기(저수준 런타임) | containerd/CRI-O 등 | 커널 기능(cgroups/namespaces 등)으로 프로세스를 실제 “컨테이너”로 실행 | containerd 아래에서 최종 실행 담당 |
쿠버네티스 내 실제 호출 흐름
kubelet → (CRI) → containerd → (OCI Runtime Spec) → runc(등) → 컨테이너 실행
실무 메모 (중요 포인트 요약)
🧩 예전엔 워커 노드에 Docker 깔고 docker로 트러블슈팅했지만,
지금은 런타임이 containerd 기반인 경우가 많아서 crictl로 점검하는 흐름이 자연스럽다.
728x90
'Kubernetes' 카테고리의 다른 글
| 5.Pod (0) | 2026.02.15 |
|---|---|
| 4. Node, Service, Pod, NodePort (0) | 2026.02.11 |
| 2. Kubernetes 기본 개념 (0) | 2026.02.11 |
| 1. 컨테이너와 쿠버네티스 (0) | 2026.02.11 |