이번 포스팅에서는 spring boot 기반의 hello 애플리케이션을 지난번 포스팅에서 설치했었던 minikube(미니큐브) 시스템에 배포하고 호출하는 예제를 실행해 보고자 한다. (*PC에 minikube가 이미 설치되어있다면 이전 포스팅을 참조하지 않아도 된다.)
예제에 사용될 앱은 http://[ip:port]/hello/[이름]의 형식으로 호출되며 이름을 넘기면 리턴해주는 심플한 앱이다.
예제에 사용된 환경
- JDK 11
- Spring Boot 2.6.0
- gradle
- git
- Docker for mac(windows라도 상관없다) 및 Docker hub 계정
- Minikube
Hello Minikube2 앱 작성
https://start.spring.io/에 방문해 아래와 같은 옵션으로 앱을 만들어 다운로드 하도록 한다. 이때 dependency에는 web dependency만 추가하도록 한다.
생성된 앱 템플릿을 다운받아 압축을 풀고 IDE(여기선 intelliJ를 예제로 든다)를 통해 읽어 들이도록 한다.
- dependency에 spring-boot-starter-web이 추가되어 있다.
예제용 RestController 작성
Controller 파일은 HelloController.java 파일을 하나 만들고 아래와 같이 심플하게 작성하도록 한다.
- URL을 통해 {name}이 입력되면 "Hello " + {name}을 리턴한다.
docker hub에 container image push를 위한 registry 생성
Kubernetes 클러스터에 배포를 위한 Pod를 생성하기 위해서는 반드시 배포를 위한 Container Image가 Repository에 저정되어 있어야 한다. 대부분의 Public Cloud 회사들은 자사 Container Image를 위한 Repository를 가지고 있으며(e.g. AWS의 ECR) Private Cloud의 경우 Container Image Repository를 직접 구축해야 한다.(e.g. NEXUS, Gitlab 등)
이 예제에서는 간단하게 Docker Hub의 Image Repository를 이용해 Cotainer Image Repository를 활용해 보도록 하겠다.
먼저 http://hub.docker.com으로 접속해 계정을 만들도록 한다(무료).
계정이 생성되면 로그인 후 아래 그림의 'Create Repository'버튼을 클릭해 이번 예제에서 사용할 Repository를 미리 생성하도록 한다.
이 예제의 Repository명은 hello-minikube2라는 이름을 사용할 예정이다.
아래와 같이 본인 계정에 hello-minikube2라는 레포지토리를 만들도록 한다.
본인 계정에 Docker Image Repository가 생성되고 나면 아래와 같은 이미지를 볼 수 있다.
이때 생성된 Repository에 push하는 명령어를 확인해 보도록 한다.
e.g. docker push sharplee7/hello-minikube2:tagname
Docker Image 생성을 위한 Dockerfile 작성
build.gradle 파일이 있는 디렉토리에 Dockerfile이라는 이름의 파일을 만들과 아래와 같이 작성한다.
- FROM - Docker Image를 만들 베이스 이미지, 예제는 openjdk 11버전 이미지를 이용해 베이스 이미지를 만들었다.
- EXPOSE - 응용 프로그램에서 사용하는 PORT 번호로 외부에 노출시킬 PORT가 된다.
- ARG - Dockerfile 내부에서 사용할 환경 변수 선언
- COPY - COPY [SOURCE][DESTINATION] 의 구조로 사용, SOURCE는 Dockerfile이 실행되는 PC의 디스크 주소이고 DESTINATION은 Docker Image 내부에서 사용하는 시스템의 PATH이다.
- ENTRYPOINT - 프로그램 실행 명령어
Docker Image 생성
작성한 Dockerfile을 기준으로 아래의 명령어를 실행해 Docker Image를 생성하도록 한다.
docker build -t [새로 만들 이미지 이름][Dockerfile 위치]
이때 [새로 만들 이미지 이름]은 위 docker hub에서 push할 계정명을 고려해 "docker-hub 계정명/Container Image명:버전" 의 형식으로 생성하도록 한다.
e.g. sharplee7/hello-minikube2:1.0 (여기서 sharplee7은 docker-hub의 내 계정명이다.)
Docker Image 생성이 완료되었으면 정상적인 생성이 되었는지 docker images 명령어를 입력해 확인하도록 한다.
Docker Hub에 Docker Image 파일 push
이제 쿠버네티스의 deployment.yaml 파일에서 Docker Image를 끌고(pull) 올 수 있도록 좀 전에 docker hub에 생성한 hello-minikube2 Repository에 Docker Image를 Push 하도록 한다.
먼저 콘솔에서 Docker Hub 로그인 하도록 한다. 명령어는 다음과 같은 순서로 입력한다.
- docker login
- 사용자 id
- 사용자 password
아래의 push 명령어를 통해 앞서 생성했던 docker image push 한다.
docker push [이미지 파일 명]
e.g. docker push sharplee7/hello-minikube2:1.0
Docker Hub 사이트에 접속해 본인의 계정으로 들어가 보면 아래와 같이 우리가 만든 docker image가 push 된 것을 볼 수 있다.
deployment.yaml 파일 작성
Kubernetes는 Container를 등록하고 관리하기 위해 Pod라는 오브젝트를 사용한다. Pod는 다시 Pod의 단위를 그룹으로 만들어 관리하는데 Pod의 복제 단위인 Replica와 Replica의 배포 단위인 Deployment가 바로 그것들이다. 이들의 관계는 다음과 같다.
즉, 우리가 만든 hello-minikube2 어플리케이션은 컨테이너 이미지화되어 있고 이 컨테이너 이미지는 Pod에 탑재되어 관리된다. Kubernetes에 이러한 Pod를 몇 쌍의 복제로 만들어(Replica) 배포(Deployment) 할 것인지 지정하는 것이 delploymet.yaml 파일이다.
아래와 같이 deployment.yaml파일을 작성하도록 한다.
작성이 완료되면 deployment.yaml 파일을 아래의 kubectl 명령어를 통해 실행하도록 한다.
kubectl apply -f [yaml 파일명]
생성된 deployment 오브젝트를 아래의 kubectl 명령어를 통해 확인하도록 한다.
kubectl get deployements
hello-service.yaml 작성 및 배포
이제 우리가 생성한 deployment 된 pod들을 외부에서 접속할 수 있게 ip와 port를 노출해 주어야 한다. 이를 위해 사용하는 것이 service.yaml이다. hello-service.yaml을 아래와 같이 작성하도록 한다.
컨테이너 이미지에서 8080으로 expose 한 port를 30090으로 nodePort를 이용해 expose 시켰다.
마찬가지로 다음의 명령어를 통해 hello-service.yaml을 적용하도록 한다.
kubectl apply -f hello-service.yaml
이 서비스가 정상 등록되었는지 아래의 kubectl 명령어를 통해 확인한다.
kubectl get service
웹 브라우저를 통한 접속
우리가 nodePort를 통해 생성한 hello-minikube2 서비스에 접근하는 IP 및 Port를 아래의 명령어를 통해 확인해 보도록 한다.
minikube service hello-minikube2
PC 환경에따라 minikube service hello-minikube2 명령어를 실행시키면 접속할 수 있는 IP와 PORT가 표시되며 시스템의 기본 웹브라우저를 자동으로 실행시켜준다.(웹 브라우저가 뜨지 않는다면 위 URL을 참조해 별도로 실행시키면 된다.)
URL을 http://yourip:yourport/hello/[yourname] 형식으로 입력해 본다.
지금까지의 과정이 이상이 없었다면 어렵지 않게 메시지가 아래와 같이 실행되는 것을 볼 수 있다.
정리
지금까지의 과정을 이미지로 표시해 보면 아래의 그림과 같다.
- hello-minikube2 앱을 spring boot에 gradle 기반으로 작성한다.
- build.gradle을 통해 컴파일 한다.
- hello-minikube2.jar 파일 생성
- Dockerfile 작성
- 생성한 Dockerfile을 이용해 sharplee7/hello-minikube2:1.0 이미지를 만든다.
- docker hub(http://hub.docker.com)에 사용자 계정을 만들도록 한다.(이미 만들어져 있으면 skip한다.)
- docker push 명령어를 통해 5. 에서 생성한 sharplee7/hello-minikube2:1.0 이미지를 docker hub의 Repository에 push 한다.
- Minikube에 배포를 위해 hello-deployment.yaml 파일을 작성한다.
- kubectl 명령어를 이용해 Minikube 클러스터에 hello-minikube2 이미지를 배포한다.
- hello-deployment.yaml 파일에 표시되어 있는 Image Repository에서 Container Image를 Pull 해온다.
- 배포된 hello-minikube2 앱을 외부에서 접속할 수 있도록 IP:Port를 노출하기 위해 hello-service.yaml 파일을 작성한다.
- kubectl -f 명령어를 통해 정의된 서비스 타입으로 배포된 hello-minikube2 애플리케이션의 IP:Port를 노출시킨다.
- minikube service hello-minikube2 명령어를 통해 외부에서 접속 가능한 IP:Port를 확인 후 웹브라우저를 기동시켜 hello API를 테스트 해본다.
이 예제에서 사용한 원본 소스는 아래의 git에서 확인 할 수 있다.
이번 포스팅은 여기까지
끝~
P.S: 배포용 yaml 파일 통합
--- 태그를 이용해 여러 종류의 yaml 파일을 하나의 파일로 통합해 만들 수 있다.
'Application Modernization > Container & PaaS' 카테고리의 다른 글
EKS, Ingress, AWS API Gateway (0) | 2021.10.07 |
---|---|
NodePort vs LoadBalancer vs Ingress (0) | 2021.10.07 |
Minikube(미니큐브) (0) | 2021.10.01 |
Kubernetes (쿠버네티스) 란? (0) | 2021.09.30 |
Docker Image Repository (0) | 2021.09.29 |