구글 클라우드(GKE), 쿠버네티스, 도커 사용하여 스프링부트 프로젝트 배포하기(맥os M3 기준)
들어가며
개념 설명보다는 제가 진행했던 부분 위주로 복기하며 포스팅을 해보려 합니다. 기본 스프링부트 프로젝트에 테스트용 restAPI 만든 뒤 도커용 이미지를 생성하고 쿠버네티스에 배포하여 클라우드 환경을 구성하는 과정입니다. 원래 제로에서 시작하면 설정을 하나하나 만져줘야 해서 더 어렵다고 하는데 저는 구글에서 제공하는 엔진을 사용하였기 때문에 어느정도 난이도는 내려가지 않았나 생각합니다. 처음 실습하시는 분들께도 3개월 무료 체험판(?)을 제공하기 때문에 무리없이 구현이 가능합니다.
GKE
해당 홈페이지에 접속하여 구글 클라우드에 회원가입 해줍니다.
회사 메일로 하면 회사 프로젝트에 귀속될 수도 있다고 합니다. 개인 메일로 가입합니다.
회원가입이 완료되면 다음과 같은 홈화면을 볼 수 있습니다. 3개월동안 40만원가량의 서버비를 지원해준다고 보면 됩니다. 지금와서 생각해보니 토이 프로젝트 같은 것을 진행하신다면 개발을 완료하고 세팅해보는게 더 이득이겠네요. 저는 테스트용으로 하는거라 기간이 아깝습니다.
각설하고 홈에서 좌측 상단에 구글 로고 옆에 프로젝트 목록을 확인할 수 있습니다.
저는 이름-날짜 형태로 프로젝트명을 만들었습니다. 중복되지 않게 만들어줍니다.
다음은 클러스터를 만들어줍니다. 클러스터는 제 프로젝트가 잘 배포될 수 있도록 클라우드 내 서버의 조합이라고 보면 됩니다.
좌측 상단의 햄버거 메뉴 버튼을 클릭하고 kubernetes engine을 찾아줍니다.
없으면 고정된 제품 옆에 연필 버튼 클릭해서 메뉴를 고정시킬 수 있습니다. Kubernetes Engine - 클러스터를 클릭해줍니다.
그리고 만들기 버튼을 눌러줍니다. 그러면 Autopilot 모드와 Standard 모드가 있습니다. Autopilot 은 구글에서 노드를 관리해주고 저희는 컨테이너만 관리하면 돼서 더 편합니다. Standard는 가상머신 내에 노드를 직접 관리합니다. 노드에 직접 접속하여 관리가 가능합니다. 저는 공부의 목적이 있기 때문에 standard로 선택했습니다.
위치 유형은 영역, 리전이 있는데 이것은 클라우드가(구글이) 가진 서버의 위치라고 보면 됩니다. 영역이 ZONE 개념이고 리전은 지역 개념입니다. 아무래도 내가 서비스하고 있는 지역에 가까이에 서버가 위치하고 있는게 속도면에서 유리합니다. 영역은 데이터 센터 하나에 보관하고 리전은 그 지역의 데이터 센터에 분산 보관하기 때문에 비용적인 면에서 더 불리하나 속도는 유리합니다.
출시 채널은 버전 관리를 자동, 수동으로 할건지 물어봅니다. 기본으로 합니다.
클러스터를 만들었으면 이제 스프링 부트 프로젝트를 이미지로 만듭니다.
도커
맥os는 도커 맥버전이 있습니다. homebrew를 통해 간편하게 다운로드해줍니다.
그리고 스프링부트 프로젝트 경로 내에 Dockerfile을 만들어줍니다.
nano Dockerfile
다음과 같이 입력합니다. '--platform=linux/amd64' 부분을 주의합니다. 맥os 사용자들은 아키텍처가 arm64여서 저렇게 아키텍처를 지정해주지 않으면 서버가 실행이 안됩니다.
그리고 openjdk 버전도 주의합니다. 버전에 맞게 적어주세요.
그 다음 클라우드의 가상머신 내 노드의 cmd창에 접근할 수 있게 gcloud를 설치합니다.
# gcloud CLI 설치
curl https://sdk.cloud.google.com | bash
# gcloud CLI 초기화
gcloud init
다음 도커의 이미지가 접근할 수 있게 해줍니다.
gcloud auth configure-docker
이제 도커에 이미지를 빌드합니다.
# 맨 뒤에 . 을 찍어주세요
docker build -t [project-name] .
구글 클라우드 내 이미지를 푸쉬합니다. 이때 이름 앞에 폴더명에 주의합니다.
docker tag [project-name] gcr.io/[PROJECT_ID]/[project-name] # 빌드된 이미지 이름 추가하기(gcr.io가 있어야 클라우드가 인식)
docker push gcr.io/[PROJECT_ID]/[project-name] #이미지 푸쉬
이미지가 푸쉬되면 도커 앱에서 이미지 탭에 다음과 같이 이미지가 들어있는 것을 확인할 수 있습니다.
쿠버네티스
이제 클라우드의 쿠버네티스를 실행할 차례입니다. 클러스터는 생성하였으니 쿠버네티스 CLI 도구인 kubectl 을 설정해줍니다.
gcloud container clusters get-credentials [cluster-name] --zone [zone-name]
그 다음 쿠버네티스에 배포하기 위해서는 배포, 서비스 관련 설정 파일이 필요합니다. .yaml 형식의 파일로 정의합니다. nano 편집기로 작성해줍니다.
nano deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: [project-name]
spec:
replicas: 2 //프로젝트 장애 시 대응할 백업서버 개수
selector:
matchLabels:
app: [project-name]
template:
metadata:
labels:
app: [project-name]
spec:
containers:
- name: [project-name]
image: gcr.io/[PROJECT_ID]/[project-name]
ports:
- containerPort: 8080
뒤에 서비스 설정에서 나오겠지만 deployment.yaml의 containerPort와 service.yaml의 targetPort를 맞춰주는것에 유의합니다.
nano service.yaml
apiVersion: v1
kind: Service
metadata:
name: [project-name]-service
spec:
type: LoadBalancer
selector:
app: [project-name]
ports:
- protocol: TCP
port: 80
targetPort: 8080
deployment와 service간 통신 포트는 8080으로 맞춰줬고 외부에서 서비스에 접근하는 포트는 80으로 설정했습니다.
type같은 경우에는 LoadBalancer로 설정할 경우 쿠버네티스에 배포할 시 ExternalIP(외부 IP)를 부여받아 웹에서 접속이 가능합니다. 기본값은 ClusterIP이며 별도의 ExternalIP를 할당받지 않고 내부에서 접근하여(EX: RESTAPI) 사용할 수 있습니다.
이제 설정한 두개의 파일을 쿠버네티스에 올려줍니다.
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
그리고 잘 올라갔는지 확인해줍니다.
kubectl get pods
배포가 잘 됐다면 다음과 같이 running상태가 되어야 합니다. 오류가 난다면 전에 설정한 아키텍처 부분을 다시 확인해주세요.
kubectl get services
서비스도 잘 배포가 됐는지 확인해줍니다. 조금만 기다리면 ExternalIP에 IP주소가 할당됩니다. IP주소:포트번호를 url에 입력하면 웹페이지에서 내 프로젝트가 잘 배포되었는지 확인됩니다.
마치며
클라우드에 대해 1도 몰랐던 저조차도 며칠 이것저것 시도해보니까 쉽게 구축할 수 있을 정도로 구글 클라우드 엔진에서 쉽게 배포환경을 만들 수 있었습니다. 하지만 역시 문제는 비용이겠죠. 요금이 어느새 몇천원 단위로 금방 오르더라구요. 만약 도메인을 만들고 사람들이 서비스가 가능한 배포 환경을 구축한다면 꽤 많은 비용 지출이 될 것 같은데 효율적으로 자원을 분배하여 요금을 줄이는 것도 알아볼 수 있는 기회가 있다면 좋겠습니다.