개발/backend

[Kubernates] 쿠버네티스에서 Local Docker image 사용하기

나인에스 2022. 5. 1. 16:19

개요

pod image pull 실패

docker build command를 이용해서 local에 docker image를 생성하고 minikube를 이용해서 pod를 deploy를 하는 경우 위와같이 "ErrImagePull" 메세지와 함께 container생성에 실패하는 현상을 볼수 있습니다. 특히 초기에 kubernates를 스터디 하는 경우나 로컬에서 개발 혹은 테스트 하는 경우 대부분 이미지를 로컬에만 두고 테스트를 하는데 이때 kubernates상에서의 테스트를 할 수 없어서 찾아 보는 도중 로컬에 있는 docker image를 minikube에서 사용할 수 있는 방법이 있어서 소개합니다.


왜 에러가 발생하는 거지??

minikube를 사용해서 로컬에 pod를 deploy하는 경우 기본적으로 minikube내부의 image를 검색하거나 image가 없는 경우 dockerhub로 부터 download해서 배치를 하게 되는데 이때 로컬에서 build된 docker image는 minikube내부에 있지 않기 때문에 image를 찾을 수 없어서 발생하는 에러 입니다. (minikube 또한 local host에서 실행중인 하나의 vm이고, 해당 vm내부에 image들을 download 후 사용합니다.)

minikube를 사용할때에 대부분 docker image를 dockerhub에 push를 하고 난 후에 push된 이미지를 kubernates에서 pull 하고, 이 image를 배치하는 형태로 동작합니다. 하지만 개발중인 경우 매번 생성된 docker image를 docker hub에 push해야하는 번거로움이 있고, 생성된 image에 문제가 있는 경우 혹은 필요없어진 image가 많은 경우 이를 관리해야하는 번거로움 또한 있습니다. 따라서, 개발시 혹은 스터디 할때에는 local에서 Docker build command를 이용해서 내가 직접 만든 이미지를 이용해서 pod에 배포를 하고 싶은데 이때 위와 같은 문제가 발생하는 거죠.


어떻게 해결해야 할까?

대략적인 순서는 local docker image 저장소와 minikube image 저장소를 sync한 다음, docker image build시 local과 minikube양쪽에 모두 업로드를 하게 되면 container를 굳이 dockerhub에 업로드 할 필요없이 사용할 수 있습니다.

local docker와 minikube docker-daemon 의 연결

아래와 같이 "minikube docker-env" 명령어를 실행하면 아래쪽에 minikube docker-daemon과 연결할 수 있는 명령어 "eval $(minikube -p minikube docker-env)" 를 확인 할 수있고 이를 실행 후 docker ps로 확인하면 minikube에 의해서 활성화된 kubernates 들을 확인 할 수 있습니다.

# minikube의 설정 및 command 확인
$>minikube docker-env

# minikube docker-daemon 과 연결
$>eval $(minikube -p minikube docker-env)

실행 및 결과 확인

minikube docker-env 실행 결과
docker와 연결 후 docker ps 결과 확인

주의 : docker와 minikube docker-daemon을 연결하는 command는 해당 terminal에만 적용 됩니다. 이말은 terminal을 생성하게 되면 매번 위의 명령어를 입력해야만 정상동작 합니다.

 

docker image 생성

위와같이 연결이 되면 일단 거의 준비가 완료된 상태입니다. 이제 docker를 생성해서 local과 minikube양쪽에 모두 생성된 이미지를 등록합니다. 여기서 주의 할 점은 기존에 docker image를 만들었다고 해도 다시 build해서 minikube에 등록을 해야 한다는 점입니다.

$>docker build -t {image_name} .

 

imag pull policy 설정

아래는 간단한 Deployment.yml파일의 내용입니다. 중요한점은 사용할 image의 pull policy를 

imagePullPolicy: Never

와 같이 꼭 Never로 명시적으로 설정해야 합니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-example-docker
spec:
  replicas: 3
  selector:
    matchLabels:
      app: go-example-docker
      tier: web-app
  template:
    metadata:
      labels:
        app: go-example-docker
        tier: web-app
    spec:
      containers:
      # To use local docker images, see link blog :
        - name: go-example-docker
          image: example-docker-img:latest
          imagePullPolicy: Never
          resources:
            limits:
              memory: "128M"
              cpu: "500m"
          ports:
            - containerPort: 8080
              protocol: TCP

 

실행 결과

모든 설정이 완료 된후 "kubectl create -f deployment.yml"을 이용해서 배포를 하면 아래와 같이 정상적으로 pod가 동작하는 것을 확인 할 수 있습니다.