목차
- Infra 환경 구성
- SpringBoot Project Local Test
- Remote Server 구성
- Jenkins Remote Server 등록
- Jenkins Repository 연동
- Jenkins 배포 Pipeline 구성
- Jenkins Build
- SpringBoot 서버 종료(Docker)
1. Infra 환경 구성
2. SpringBoot Project Local Test
Maven Project
- 프로젝트 빌드 : 프로젝트의 pom.xml 파일을 설정하고 Maven을 사용하여 프로젝트를 빌드합니다.
- JAR,WAR 파일 생성 : mvn package 명령어로 Spring 프로젝트를 빌드하여 JAR 파일을 생성합니다.
Gradle Project
1). 프로젝트 빌드
프로젝트 내에 gradlew파일이 있는 디렉토리에서 gradlew build 명령어를 실행하여 jar,war파일을 생성합니다.
# 명령어
gradlew build
Starting a Gradle Daemon, 5 incompatible and 1 stopped Daemons could not be reused, use --status for details
> Task :test
OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
BUILD SUCCESSFUL in 1m 21s
7 actionable tasks: 7 executed
2). jar,war파일 생성 확인
위 과정을 거치면 /build/libs 폴더 내에 war 혹은 jar파일이 생성됩니다.
3). 프로젝트 실행
/build/libs디렉토리로 이동하여 아래 명령어를 통해 로컬에서 프로젝트 구동을 확인합니다. 이클립스및 다른 툴을 이용하여 구동하는것도 좋습니다.
# 명령어
java -jar <project file name>.war
java -jar <project file name>.jar
# 8080외의 포트 지정 예) 6060포트
java -jar -Dserver.port=6060 demo-war-0.0.1-SNAPSHOT.war
3. Remote Server 구성
sudo apt update
sudo apt install openjdk-17-jdk -y
sudo apt install maven -y
sudo apt install gradle
4. Jenkins Remote Server 등록
1. Publish Over SSH Plugin 설치
1). Dashboard > Jenkins 관리로 이동 후 Plugins를 클릭한다.
2). Available plugins를 선택하고 Publish over ssh
를 검색하여 설치한다.
3). 설치가 끝나고 실행중인 작업이 없으면 Jenkins를 재시작한다.
2. 배포대상 원격서버 등록
아래 이미지와 같이 SSH Server를 등록하지 않은 경우 ssh서버등록을 해야한다.
1). Dashboard > Jenkins 관리 > System(시스템 설정)메뉴로 진입
2). SSH Servers에서 추가를 눌러 SSH Server를 추가
3). 다음과 같이 배포대상 VM정보를 입력하여 추가
- Name : 서버를 구분하기 위한 명칭
- Hostname : 서버 주소
- Username : 배포자명
Remote Directory
: 배포 원격 디렉토리[중요]- 원격 디렉토리에서 배포할 경로를 설정해준다.
- home/master/was/SpringBoot
4). 고급을 눌러 설정한 VM환경에 맞게 세팅해준다.
나같은 경우 Azure VM에 ID/Password방식으로 구성했기 때문에 Passphrase / Password
에서 해당 VM의 비밀번호만 넣어주면 된다. 토큰 인증방식으로 구성한 경우 별도의 인증키를 넣어주어야 한다.
5). 위 사항을 정확히 입력 후 Test Configuration을 클릭하면 왼쪽에 Success
라고 뜬다. 확인 후 저장을 누른다.
5. Jenkins Repository 연동(배포 job 생성)
1. 새로운 item 생성
2. 새로운 Job 생성: Jenkins 대시보드에서 새로운 Freestyle 프로젝트를 생성합니다.
3. 소스 코드 관리 > Subversion을 선택합니다.
Modules
-
Repository URL : SVN repository주소를 입력합니다.
-
Credentials
Jenkins 에서 빌드, 배포를 수행하려면 기본적으로 2가지 Credential 정보가 필요합니다. 소스를 Checkout 할 Git Repository 의 접속 계정 정보와 Docker Image를 Push 하기 위한 Registry 접속 계정 정보입니다. 여기서는 SVN에 접속할 SVN 계정정보를 등록합니다.
-
Add를 클릭 후 Jenkins를 눌러줍니다.
-
SVN관련 계정정보를 입력 후 Add로 추가합니다.
- 세팅 참고 예)
작성 완료 후 저장을 눌러 완료합니다.
6. Jenkins 배포 Pipeline 구성
1. Dashboard 에서 작업할 job을 선택합니다.
본 설명에서 Springboot-Demo-war 선택
2. 구성을 선택합니다.
3. Build Steps 구성
build를 하기위한 방식은 여러방식이 있는듯 하다. 각자 환경에 맞게 선택하면 된다.
1). script 명령어를 통해 build
# gradlew 파일의 위치로 이동
cd demo-war
ls -l
chmod +x gradlew
./gradlew clean build --info
2). [작성 예정]
4. 빌드 후 조치
빌드 후 조치 추가
> Send build artifacts over SSH
선택
SSH Server
- Name : 등록한 원격 서버를 선택한다.
-
고급
을 눌러Verbose output in console
에 체크해준다.배포단계에서 상세로그를 확인할 수 있다.
Transfers
- Source files :
- <프로젝트명>/<파일경로>/<.war or .jar> 파일형식으로 build된 파일경로를 입력한다. 파일경로>프로젝트명>
- 파일이 한개인 경우 */.war 와 같은 형식으로 입력하면 된다.
- SpringBoot build시 plain을 생성하게 되므로 확인필요.
- Remove prefix :
- <프로젝트명>/<파일경로>/ 파일경로>프로젝트명>
- 비워두면 쓸대없는 디렉토리가 생성된다고 한다. (직접 해보진 않음)
- Remote directory :
- 원격 서버에서 배포할 디렉토리를 입력한다.
- 단, 경로가 맞지않으면 자동으로 생성하지 않아 실패하게됨
- Exec command :
- war나 jar파일을 원격서버로 전달하고 해당 경로에서 진행할 작업 script를 작성한다.
Exec command에 들어갈 script 구성
# java -jar -Dserver.port=6060 demo-war-0.0.1-SNAPSHOT.war
echo "현재 디렉토리 출력"
pwd
cd was/SpringBoot
whoami
echo "현재 날짜와 시간으로 태그 생성"
TIMESTAMP=$(date +"%Y%m%d%H%M%S")
DOCKER_IMAGE="iiblackcode/springboot-6060"
TAG="$DOCKER_IMAGE:$TIMESTAMP"
echo "Docker 이미지 강제 삭제 (기존 이미지 태그가 있는 경우)"
# sudo docker rmi -f $TAG || true
sudo docker rmi $(sudo docker images -q)
echo "Docker 이미지 빌드"
sudo docker build -t $TAG .
echo "생성된 Docker image 확인"
sudo docker images
echo "Docker hub login or ACR 등록"
sudo docker login
echo "Docker 이미지 푸시"
sudo docker push $TAG
# sudo docker run -it -d -p 6060:8080 springboot-6060
# sudo docker ps -a
echo "yaml파일 경로로 이동"
cd ../../web/
ls
echo "deployment.yaml 파일 업데이트"
# sed -i "s|image: iiblackcode/springboot-6060:.*|image: \$TAG|" deployment.yaml
sed -i "s|image: iiblackcode/springboot-6060:.*|image: $TAG|" deployment.yaml
echo "업데이트된 deployment.yaml 파일 내용 확인"
cat deployment.yaml
echo "Deployment.yaml 재실행"
kubectl apply -f deployment.yaml
여기서 개인적으로 Remote Server
내에서 war/jar파일이 전송될 디렉토리와 yaml파일을 별도로 관리하기 위해 분리함
# build되는 war/jar파일 위치
master@master:~/was/SpringBoot$ ll
total 31764
drwxrwxr-x 2 master master 4096 Jul 23 06:23 ./
drwxrwxr-x 4 master master 4096 Jul 12 04:53 ../
-rw-rw-r-- 1 master master 149 Jul 23 07:09 Dockerfile
-rw-rw-r-- 1 master master 837 Jul 23 06:23 Jenkinsfile
-rw-rw-r-- 1 master master 32506960 Jul 24 05:55 demo-war-0.0.1-SNAPSHOT.war
# yaml파일 디렉토리
master@master:~/web$ ls
deployment.yaml metallb-config.yaml service.yaml
- service.yaml 파일
apiVersion: v1
kind: Service
metadata:
name: springboot-service
spec:
selector:
app: springboot
ports:
- protocol: TCP
port: 8080 # 외부에서 접근할 포트
targetPort: 8080 # Pod 내 컨테이너의 포트
nodePort: 30061 # NodePort를 유효 범위 내로 설정
type: LoadBalancer
# type: NodePort
- deployment.yaml 파일
apiVersion: apps/v1
kind: Deployment
metadata:
name: springboot-deployment
spec:
replicas: 3
selector:
matchLabels:
app: springboot
template:
metadata:
labels:
app: springboot
spec:
containers:
- name: springboot
image: iiblackcode/springboot-6060:latest
ports:
- containerPort: 8080
작성 참고
작성 완료 후 저장버튼을 눌러 저장을 완료합니다.
7. Jenkins Build
이후 전체적인 흐름으로
- SVN으로 SpringBoot Sourcecode
commit&push
진행 - SVN에서 Jenkins로 build(Gradle/Meaven)
- Jenkins에서 원격서버(kubernetes)에 war/jar파일 ssh전송
- Docker Container image build
- build 빌드전 기존 이미지 삭제
- Docker hub로 image push
- deployment 재배포를 통해 pod생성
이런 흐름으로 진행되지만 실제로 운영환경에서
개발자는 Code Commit&Push
만 하고
운영환경에서 Jenkins Build now
버튼 한번의 클릭으로 이 모든 과정이 이뤄지게 된다.