서론
SpringBoot 프레임워크로 제작한 API Application을 cluster에 배포하는 일련의 과정을 포스팅하고자 합니다. 본 포스팅은 NCP 서비스를 기반으로 작성되는 점 참고 부탁드립니다. 빌드는 NCP의 SourceBuild, 배포는 SourceDeploy, 파이프라인은 SourcePipeLine을 사용하며 Kubernetes는 NKS로 작성하였습니다.
[이전글]
[Kubernetes 도입] 개발환경 없는 회사에서 NKS로 개발환경 구성하기 Chapter 1. 개발 환경이 없었다
서론우리 회사에는 개발환경이 존재하지 않았습니다. 입사하고 나서 가장 놀랐던 것은 local에서 개발하고, production에 바로 배포하고 오류가 발생하면 롤백하며 프로덕션 서비스를 운영하는 것
min-nine.tistory.com
본론
1. CI/CD 파이프라인 설계
처음부터 GitOps와 ArgoCd를 사용한 쿠버 파이프라인을 설계한다면 너무 좋겠지만, 현재 사용하고 있는 운영 서비스와 최대한 비슷하면서도 같게 설계하기 위해 NCP에서 제공하는 서비스인 Source Service(Commit, Build, Deploy, PipeLine)를 사용해서 파이프라인을 설계해 보았습니다.
SourceCommit : git repository 역할
SourceBuild : 각기 다른 언어로 구성된 application들을 알맞게 build해주는 build tool
SourceDeploy : build 된 application을 알맞게 배포해 주는 deploy tool
SourcePipeline : trigger를 받아서 build와 deploy의 순서 및 연동을 도와주는 pipeline tool
SpringBoot 단일 Application 경우 Build 이후 Deploy가 되도록 파이프라인을 설계하였습니다.
2. SourceBuild
SourceBuild 메뉴에 접속하여 빌드 프로젝트 생성하기를 클릭하면 아래와 같이 빌드 프로젝트를 생성하는 설정창을 볼 수 있습니다. 프로젝트 이름과 설명은 애플리케이션에 맞게 api-k8s-dev라고 설정하였습니다.
빌드 대상에서 저는 SourceCommit을 사용하기 때문에 SourceCommit을 선택한 후, 리포지토리에서 빌드하고 싶은 repository name을 설정하면 됩니다. 현재는 SpringBoot 기반의 Application Source를 관리하는 api repository를 입력합니다.
빌드환경은 SourceBuild에서 관리되는 이미지 중 기본 Ubuntu 운영체제에 Base 런타임 이미지를 활용하였습니다. Docker build 명령을 수행하여야 하는데, 설치 패키지 목록에서 Docker가 설치되어 있는 이미지를 활용하면 어떤 빌드 런타임 이미지이건 무방합니다.
그리고 우리는 도커 이미지 빌드를 사용하기 때문에 docker build 체크박스를 선택해 줍니다. 그리고 빌드 명령어 보기 버튼을 클릭합니다.
빌드는 빌드 전 명령어 > 빌드 명령어 > 도커 이미지 빌드 설정 > 빌드 후 명령어 순서로 실행됩니다. 저희는 이전에 생성해 두었던 도커 파일을 사용하여 빌드를 진행할 것이고, 빌드가 완료된 이미지를 ContainerRegistry(container image를 저장 및 관리할 수 있는 ncp service 중 하나)에 자동으로 push 해줄 수 있습니다. 때문에 Conainer Registry를 지정하고 이미지 이름과 태그를 설정합니다. 이미지 태그의 경우 "*" 키워드를 입력하면 ncp가 자동 증가를 시켜주지만, dev 환경 구성이기에 이전 이미지를 관리하고 싶지 않아서 저는 1.0.1 1개의 태그만 생성 및 관리하기로 하였습니다.
도커파일은 아래 포스팅을 참고해 주시기 바랍니다.
2025.02.13 - [Docker] - Docker을 이용해 SpringBoot Application 빌드하기
Docker을 이용해 SpringBoot Application 빌드하기
서론SpringBoot Framwork 기반의 Application을 build하는 방법은 많이 있습니다. 그 중 Docker를 활용하여 빌드 및 이미지화 하는 방법을 포스팅하려 합니다. 본 포스팅에서는 gradle build tool을 활용합니다.
min-nine.tistory.com
3. Source Deploy
SourceDeploy에서는 배포 Stage를 기준으로 실제 환경에 배포되는 내용, 개발 환경에 배포되는 내용 등을 구분할 수 있습니다. 저는 k8s-dev cluster에 배포되게 하기 위해서 k8s-dev 라는 명칭의 배포 Stage를 생성하였습니다.
배포 타겟은 일반 Instance Server부터 ObjectStorage까지 본인의 환경 구성에 맞게 고르실 수 있습니다. 저는 k8s cluster에 배포하기 위해 Ncloud Kubernetes Service를 배포 타겟으로 잡았고, Cluster는 dev-cluster로 구성하였습니다.
배포 시나리오는 SourceCommit의 api application repository의 develop 브랜치를 토대로 프로젝트의 root 디렉토리에 있는 deployment-dev.yaml 파일을 실행하게 구성하였습니다. 그로인해 kubernetes의 deployment 오브젝트를 통해 클러스터에 어플리케이션이 배포될 수 있도록 설정하였습니다.
4. deployment-dev.yaml 작성하기
deployment-dev.yaml 파일이라고 설정했지만, Service까지 함께 작성해줬습니다. 지금보니 분리가 필요할 것 같습니다.
우선 아래의 deployment 파일이 실행되려면 선행조건이 필요합니다. cluster에 test 라는 이름의 namespace가 생성되어 있어야 하고, 이미지를 가져오기 위해 ncp의 ContainerRegistry에 접근해야하기 때문에 test namespace에 Secret을 생성해줘야 합니다.
kubectl --kubeconfig ~/config/ncpDevKubeconfig.yaml create -n test
kubectl --kubeconfig ~/config/ncpDevKubeconfig.yaml create secret docker-registry regcred -n test --docker-server=vjnibbzs.kr.private-ncr.ntruss.com --docker-username={iamKey} --docker-password={iamSecret}
apiVersion: apps/v1
kind: Deployment
metadata:
name: mingyu-api-deployment # deployment의 이름
namespace: test
labels:
app: mingyu-api-deployment # deployment의 라벨
spec:
replicas: 1
selector:
matchLabels:
app: mingyu-api-deployment # replicaset이 관리할 pod 라벨
template: # 하위에 pod 정보 설정
metadata:
labels:
app: mingyu-api-deployment # pod의 라벨
spec: # 컨테이너 설정
containers:
- name: mingyu-api
image: vjnibbzs.kr.private-ncr.ntruss.com/mingyu-api-dev:latest
command: ["/bin/sh","-c","java -Dspring.profiles.active=dev -jar app.jar"]
imagePullPolicy: Always
ports:
- containerPort: 8080 # 애플리케이션이 동작하는 포트로 스프링 기본포트는 8080
protocol: TCP
envFrom:
- configMapRef:
name: mingyu-api-config-dev
imagePullSecrets:
- name: regcred
---
apiVersion: v1
kind: Service
metadata:
name: mingyu-api-service
namespace: test
spec:
type: NodePort
selector:
app: mingyu-api-deployment
ports:
- name: http
port: 80 # 클러스터 내부에서의 접근 포트
protocol: TCP
targetPort: 10080 # Pod에서 실행중인 포트
결과
이제 develop 브랜치를 origin으로 push하게되면 아래와 같이 pipeline이 성공한 것을 확인할 수 있습니다.
그리고 dev-cluster의 dashboard에 접속해보면 아래와 같이 deployment, replicaset, pod가 정상적으로 생성된 것을 확인할 수 있습니다.