Kind에서 로컬 Docker 이미지를 사용하는 방법 완벽 정리
|AI Summary
- kind는 Kubernetes 클러스터를 Docker 컨테이너 내부에 생성해 로컬 Docker 데몬과 kind 노드의 containerd가 완전히 분리된 환경이다.
- Pod가 로컬 이미지를 바로 사용하지 못하는 이유는 kind 노드에 이미지가 없으면 원격 레지스트리에서 pull을 시도하기 때문이다.
- 로컬 이미지를 사용하려면
kind load docker-image <이미지명>명령어로 이미지를 kind 노드에 직접 로드해야 한다. - imagePullPolicy 기본값이
Always이므로, 로컬 이미지를 사용하려면 명시적 버전 태그와IfNotPresent정책을 설정하는 것이 좋다. - kind 노드 내부 이미지 목록 확인과 삭제는
docker exec kind-control-plane crictl images및crictl rmi명령어로 containerd 기준으로 수행해야 한다. - 이 과정을 이해하면 로컬에서 빌드한 이미지를 kind 노드에 로드하고 Kubernetes에서 안정적으로 테스트할 수 있다.
들어가며
Kubernetes를 로컬에서 학습할 때 가장 많이 사용하는 도구가 바로 kind(Kubernetes in Docker) 이다.
kind는 간단한 명령으로 로컬 Kubernetes 클러스터를 만들 수 있고, 강의나 실습 환경에서 널리 활용된다.
그런데 많은 초심자들이 공통적으로 겪는 문제가 있다.
“내 로컬 Docker 이미지가 Pod에서 바로 실행되지 않는다”
“ErrImagePull / ImagePullBackOff 에러가 난다”
왜 이런 문제가 발생하는지, 어떻게 해결하는지, 그리고 kind 노드의 이미지 관리 방법까지 그림과 함께 정리해본다.
1. 왜 로컬 Docker 이미지가 Pod에서 바로 사용되지 않을까?
kind는 Kubernetes 클러스터를 Docker 컨테이너 내부에 생성한다.
즉, PC의 Docker 데몬과 kind 노드 내부의 Docker 엔진(containerd)은 전혀 다른 환경이다.
⚠️ 개념적으로 이렇게 분리되어 있다:
flowchart LR
subgraph Host["호스트 (내 PC)"]
A[로컬 Docker 데몬<br/>docker images]
end
subgraph KindNode["kind 노드 (containerd)"]
B[containerd 이미지 저장소<br/>crictl images]
C[kubelet<br/>Pod 생성]
end
C --> B
즉:
내 컴퓨터 Docker 이미지 목록 != kind 노드의 Docker 이미지 목록
따라서 Pod를 생성하면 Kubernetes는 다음 순서로 동작한다:
- kind 노드(containerd)에 이미지가 존재하는지 확인
- 없으면 원격 레지스트리에서 pull 시도
- 로컬 빌드 이미지라면 당연히 pull 실패 → ErrImagePull
2. 해결 방법: kind 노드에 이미지 직접 로드하기
kind는 로컬에서 빌드한 이미지를 노드(containerd)로 직접 복사(load) 하는 기능을 제공한다.
| |
이미지 로드 흐름:
flowchart LR
A[로컬 Docker 이미지] --> B[kind load docker-image]
B --> C[kind 노드 containerd<br/>crictl images]
C --> D[Pod 실행 시 이 이미지 사용]
이미지를 로드한 후 Pod를 생성하면 정상적으로 로컬 이미지를 사용한다.
3. Pull 정책(imagePullPolicy) 확인하기
이미지 태그가 latest이면 Kubernetes는 기본적으로:
| |
즉, 항상 원격 레지스트리에서 pull 하려고 한다.
→ 로컬 이미지를 사용하려면 pull을 끄는 게 중요하다.
⭐ best practice
- 태그는 latest 대신 1.0.0, 0.1.2 등 명시적 버전 사용
- imagePullPolicy는 기본값 IfNotPresent 유지
4. kubectl run 으로도 로컬 이미지를 사용할 수 있을까?
가능하다.
kind 노드에 이미지를 로드했다면 Pod 생성 방식과 상관없이 모두 사용 가능하다.
| |
단, 이미지 이름과 태그가 정확히 일치해야 한다.
5. kind 노드 내부 이미지 목록 확인하기
로컬 Docker의 docker images는 아무 소용이 없다.
kind는 containerd 기반이므로 다음으로 조회해야 한다:
| |
특정 이미지를 확인하려면:
| |
구조적으로 이렇게 동작한다:
graph TD
A[docker images<br/>호스트 PC] --> B[Docker 데몬]
C[crictl images<br/>kind 노드] --> D[containerd]
B -. "연결되지 않음" .- D
호스트의 Docker 데몬과 kind 노드의 containerd는 완전히 분리된 공간임을 의미한다.
6. kind 노드 내부 이미지 삭제하기
삭제 역시 containerd 기준으로 처리해야 한다.
✔ 단일 노드 삭제
| |
✔ 멀티 노드 클러스터 삭제 (worker 노드 포함)
삭제 흐름:
flowchart LR
A[kind 노드 containerd<br/>crictl images] --> B[crictl rmi 이미지 삭제]
B --> C[이미지 없음]
C --> D[Pod 생성 시 원격 레지스트리 pull 시도]
7. 요약
| 작업 | 명령 |
|---|---|
| 로컬 이미지 kind 노드로 로드 | kind load docker-image hello-server:1.0.0 |
| 노드 이미지 목록 확인 | docker exec kind-control-plane crictl images |
| 노드 이미지 삭제 | docker exec kind-control-plane crictl rmi <이미지> |
| Pod에서 로컬 이미지 사용 | image: hello-server:1.0.0 + IfNotPresent |
| kubectl run 으로도 사용 가능 | kubectl run test –image=hello-server:1.0.0 |
마무리
kind는 Kubernetes 실습에 매우 좋은 도구지만,
로컬 Docker 이미지와 kind 노드의 containerd 이미지가 서로 완전히 독립된 환경이라는 점 때문에 처음에 혼란이 올 수 있다.
이번 글에서 정리한 흐름만 이해하면:
- 로컬에서 docker build
- kind로 kind load docker-image
- Kubernetes에서 Pod 실행
- 이미지 목록 조회/삭제 관리
이 흐름을 완전히 이해할 수 있고, 로컬에서 Kubernetes 테스트 작업을 훨씬 빠르고 안정적으로 수행할 수 있다.