포스트

Kubernetes에서 사용 가능한 CRI 비교

containerd vs CRI-O vs cri-dockerd

Kubernetes에서 사용 가능한 CRI 비교

쿠버네티스에서 컨테이너를 실행하려면 반드시 CRI(Container Runtime Interface)가 필요하다. 현재 쿠버네티스 환경에서 가장 널리 선택되는 옵션은 다음 세 가지다.

  • containerd
  • CRI-O
  • cri-dockerd

각 런타임은 태생적 배경과 목표가 다르기 때문에 구조, 성능, 운영 방식에도 차이가 있다.
이 글에서는 세 런타임을 비교하고, 어떤 환경에서 어떤 런타임을 선택해야 하는지 정리한다.

1. containerd


containerd는 원래 Docker 내부의 핵심 엔진이었지만, 컨테이너 표준화를 위해 CNCF 독립 프로젝트로 분리된 런타임이다.
현재 Kubernetes에서 가장 널리 사용되며, 쿠버네티스 공식 문서에서도 권장하는 런타임이다.

containerd의 역할

  • 컨테이너 생성·시작·중지
  • 이미지 Pull/Push
  • snapshotter를 통한 루트 파일시스템 관리
  • OCI 런타임(runc) 실행
  • 내장된 CRI 플러그인으로 kubelet과 직접 통신

containerd 구조:

1
2
3
4
5
6
7
8
9
      Kubernetes (kubelet)
             
             
   ┌──────────────────────┐
         containerd        CRI 플러그인 내장 (Containerd 자체가 CRI 서버)
   └──────────────────────┘
             
             
           runc (OCI)

2. CRI-O


CRI-O는 Red Hat이 중심이 되어 개발한, 오직 Kubernetes만을 위한 컨테이너 런타임이다.
containerd가 범용 컨테이너 런타임이라면, CRI-O는 Kubernetes 최적화에 초점을 두고 있다.

CRI-O의 특징

  • 쿠버네티스 CRI 구현을 최소한의 구성요소로 설계
  • containerd보다 컴포넌트가 더 단순함
  • 이미지 레이어 관리에 OverlayFS 기반 사용
  • 보안을 위해 SELinux, seccomp, AppArmor 등과 높은 통합성
  • PodSandbox 개념을 K8s CRI에 맞춰 구현

CRI-O 구조

1
2
3
4
5
6
7
8
9
	Kubernetes (kubelet)
	       
	       
	┌──────────────────────┐
	        CRI-O             K8s 전용 CRI 런타임
	└──────────────────────┘
	       
	       
	      runc

containerd와의 차이

  • containerd는 범용 런타임 / CRI-O는 Kubernetes 전용
  • CRI-O는 Docker 생태계 기능이 없음
  • containerd보다 구성이 더 단순
  • RHEL, OpenShift 계열에서 기본 선택지

3. cri-dockerd


쿠버네티스 1.24 이전에는 kubelet 내부에서 dockershim이 포함되어 Docker를 직접 사용할 수 있었다.
dockershim 제거 이후, Docker를 계속 Kubernetes에서 쓰기 위해 탄생한 것이 cri-dockerd다.

cri-dockerd의 역할

  • Kubernetes의 CRI 요청 ↔ Docker API로 매핑
  • Docker 기반 워크로드를 그대로 K8s에서 유지

cri-dockerd 구조

1
2
3
4
5
6
7
8
9
10
11
12
13
14
	Kubernetes (kubelet)
	       
	       
	┌──────────────────────┐
	     cri-dockerd          CRI 어댑터
	└──────────────────────┘
	        Docker API
	       
	┌──────────────────────┐
	    Docker Engine         containerd 내부 포함
	└──────────────────────┘
	       
	       
	 containerd  runc

즉, 가장 레이어가 많고 가장 복잡한 구조다.

4. 기능 및 구조 비교


성능 비교

항목containerdCRI-Ocri-dockerd
오버헤드낮음낮음중간~높음
컨테이너 실행 속도빠름가장 빠름(단순 구조)Docker API 경유로 느림
이미지 관리다양한 snapshotterOverlayFS 중심Docker 방식

보안 기능

기능containerdCRI-Ocri-dockerd
seccomp지원강화됨 (K8s 기본 프로필)Docker 의존
AppArmor지원지원Docker 의존
SELinux제한적최적화Docker 의존

운영 난이도

런타임운영 난이도
CRI-O가장 단순
containerd단순하지만 설정 옵션 다양
cri-dockerdDocker까지 관리해야 해서 가장 복잡

호환성

항목containerdCRI-Ocri-dockerd
Kubernetes 공식 권장
Docker CLI 사용
기존 Docker 워크로드 재사용✔ 강점

5. 핵심 차이 정리


항목containerdCRI-Ocri-dockerd
역할K8s가 직접 사용하는 범용 컨테이너 런타임K8s 전용으로 설계된 경량 컨테이너 런타임Docker를 K8s에서 쓰기 위한 CRI 어댑터
K8s CRI 지원네이티브 지원네이티브 지원 (CRI만을 위해 개발됨)Docker는 CRI 미지원 → 중간 어댑터 필요
의존성독립 실행독립 실행Docker Engine 필수
실행 경로kubelet → containerd → runckubelet → CRI-O → runckubelet → cri-dockerd → Docker → containerd → runc
설치 복잡도단독; 비교적 단순단독; 가장 단순Docker + cri-dockerd 두 가지 설치 필요
오버헤드낮음가장 낮음 (K8s 전용 구조)Docker API 경유로 가장 많음
보안AppArmor / Seccomp / SELinux 일부 지원SELinux·Seccomp 통합 강화Docker 보안 모델 의존
권장 여부Kubernetes 기본 런타임로 가장 많이 사용됨RHEL/OpenShift 또는 보안·단순성 중시 환경에 적합기존 Docker 중심 환경만 유지용