Spring 프로젝트 Jenkins와 Github로 자동 배포
CI / CD 란?
기존의 모놀리식 소프트웨어의 개발 접근 방식이 아닌 현대화된 애플리케이션은 마이크로서비스 아키텍처(MSA)를 사용하여 소프트웨어를 구축하고 API로 이러한 서비스를 함께 연결하는 경우가 많습니다. 서비스를 작은 단위의 API로 구성하고 연결하는 방식은 신속하고 지속적인 소프트웨어 제공을 해야하며 신뢰 가능한 수준의 버전을 유지할 수 있어야 합니다. 이를 위해 CI/CD(지속적인 통합 및 배포)가 중요합니다.
CI(Continuous Integration) : 지속적인 통합 통합 프로세스.
애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트되어 공유 리포지토리에 통합되도록 설정할 수 있기 때문에 여러 명의 개발자가 동시에 애플리케이션 개발과 관련된 코드 작업을 할 경우 서로 충돌할 수 있는 문제를 해결할 수 있습니다.
CD(Continuous Delivery or Continuous Deployment) : 지속적인 서비스 제공 또는 지속적인 배포
지속적인 제공(Continuous Delivery)이란 개발자들이 애플리케이션에 적용한 변경 사항이 버그 테스트를 거쳐 리포지토리(예: GitHub 또는 컨테이너 레지스트리)에 자동으로 업로드되는 것을 뜻하며, 운영팀은 이 리포지토리에서 애플리케이션을 실시간 프로덕션 환경으로 배포할 수 있습니다. 이는 개발팀과 비즈니스팀 간의 가시성과 커뮤니케이션 부족 문제를 해결해 줍니다. 지속적인 제공은 최소한의 노력으로 새로운 코드를 배포하는 것을 목표로 합니다.
지속적인 배포(Continuous Deployment)란 개발자의 변경 사항을 리포지토리에서 고객이 사용 가능한 프로덕션 환경까지 자동으로 릴리스하는 것을 의미합니다. 이는 애플리케이션 제공 속도를 저해하는 수동 프로세스로 인한 운영팀의 프로세스 과부하 문제를 해결합니다. 지속적인 배포는 파이프라인의 다음 단계를 자동화함으로써 지속적인 제공이 가진 장점을 활용합니다.
CI / CD으로 얻는 것은?
- 개발 및 운영팀에 발생하는 통합문제를 해결
- 개발단계에서 배포까지 자동화하므로서 주기적인 수동배포에 소요되는 시간을 절약.
- 휴면 에러를 방지.
CI/CD 파이프라인의 마지막 단계는 지속적 배포입니다. 프로덕션 준비가 완료된 빌드를 코드 리포지토리에 자동으로 릴리스하는 지속적 제공의 확장된 형태인 지속적 배포는 애플리케이션을 프로덕션으로 릴리스하는 작업을 자동화합니다. 프로덕션 이전의 파이프라인 단계에는 수동 작업 과정이 없으므로, 지속적 배포가 제대로 이루어지려면 테스트 자동화가 제대로 설계되어 있어야 합니다. 자동화된 테스트는 CI/CD 파이프라인의 여러 테스트 및 릴리스 단계를 수행할 수 있어야 하기 때문에 많은 선행 투자가 필요합니다.
CI / CD Tools
- Jenkins
- 무료 오픈소스.
- 서버 설치가 필요.
- 사용자 및 정보가 많음.
- 지원하는 플러그인이 많음.
- 설치 및 사용이 간단함.
- JIRA 등 Issue tracking과 연계가 완벽하지 않음.
- Travis CI
- 오픈소스용은 무료이고 Private는 유료.
- 서버 설치가 필요 없이 Travis에서 제공해줌.
- 설정이 간편하지만 Jenkins에 비해 플러그인이나 설정할 수 있는 범위가 적음.
- Private을 사용해야 된다면 꽤 비싼 비용을 지불 해야 함.
- Bamboo
- 직관적이고 이쁜 UI.
- Atlassian 제품군(JIRA, Confluence 등)과 완벽한 통합 제공.
- Jenkins 에 비해 프로젝트 권한 설정이나 분산 빌드가 쉬움.
- 유료이고 비싼 비용을 지불해야 함.
Jenkins 설치
목표
Github의 master 브랜치에 Spring 프로젝트를 push하면 Jenkins에서 Gradle로 빌드하고 운영(prod) 서버에 자동 배포.
Jenkins 서버 준비
Jenkins를 설치 및 운영할 서버 한대를 마련하여 Rucky Linux 8.5를 설치 하였습니다.
JAVA 설치
AdoptOpenJDK 설치가이드 CentOS RPM으로 AdoptOpenJDK를 설치합니다.
(직접 설치하려면 adoptium github에서 내려 받으세요.)
# cat <<'EOF' > /etc/yum.repos.d/adoptopenjdk.repo
[AdoptOpenJDK]
name=AdoptOpenJDK
baseurl=http://adoptopenjdk.jfrog.io/adoptopenjdk/rpm/centos/$releasever/$basearch
enabled=1
gpgcheck=1
gpgkey=https://adoptopenjdk.jfrog.io/adoptopenjdk/api/gpg/key/public
EOF
설치 가능 버전 확인
# yum --showduplicates list adoptopenjdk-11-hotspot
adoptopenjdk-11-hotspot.x86_64 11.0.3+7-1 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.4+11-1 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.5+10-1 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.6+10-1 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.7+10-1 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.8+10-1 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.8+10-2 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.8+10-3 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.9+11-3 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.9+11.1-3 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.9+11.2-3 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.10+9-3 AdoptOpenJDK
adoptopenjdk-11-hotspot.x86_64 11.0.11+9-3 AdoptOpenJDK
# yum install adoptopenjdk-11-hotspot-11.0.11+9-3.x86_64
java 원본 경로 확인
# which javac
/usr/bin/javac
# readlink -f /usr/bin/javac
/usr/lib/jvm/adoptopenjdk-11-hotspot/bin/javac
# vim /etc/profile
...
맨 아래에 JAVA_HOME은 Java설치 경로에서 bin/javac 경로를 제외하고 설정하고 path는 /bin을 포함 시켜준다.
export JAVA_HOME=/usr/lib/jvm/adoptopenjdk-11-hotspot
export PATH=$PATH:$JAVA_HOME/bin
재부팅
# shutdown -r now
# java -version
openjdk version "11.0.11" 2021-04-20
OpenJDK Runtime Environment AdoptOpenJDK-11.0.11+9 (build 11.0.11+9)
OpenJDK 64-Bit Server VM AdoptOpenJDK-11.0.11+9 (build 11.0.11+9, mixed mode)
# echo $JAVA_HOME
/usr/lib/jvm/adoptopenjdk-11-hotspot
# javac
Usage: javac <options> <source files>
where possible options include:
...
Java 17
cat <<EOF > /etc/yum.repos.d/adoptium.repo
[Adoptium]
name=Adoptium
baseurl=https://packages.adoptium.net/artifactory/rpm/centos/8/$(uname -m)
enabled=1
gpgcheck=1
gpgkey=https://packages.adoptium.net/artifactory/api/gpg/key/public
EOF
yum install temurin-17-jdk
Java 버전 선택
# alternatives --config java
There are 2 programs which provide 'java'.
Selection Command
-----------------------------------------------
1 /usr/lib/jvm/adoptopenjdk-11-hotspot/bin/java
*+ 2 /usr/lib/jvm/temurin-17-jdk/bin/java
Enter to keep the current selection[+], or type selection number:
Git 설치
# yum install git
# git --version
git version 1.8.3.1
# which git
/usr/bin/git
Gradle 설치
# yum install unzip
# wget https://services.gradle.org/distributions/gradle-7.4-bin.zip -P /opt
# unzip /opt/gradle-7.4-bin.zip
# rm -f /opt/gradle-7.4-bin.zip
# vim /etc/profile.d/gradle.sh
export GRADLE_HOME=/opt/gradle-7.4
export PATH=${GRADLE_HOME}/bin:${PATH}
# chmod +x /etc/profile.d/gradle.sh
# source /etc/profile.d/gradle.sh
# gradle -v
Welcome to Gradle 7.4!
...
8.1.1
wget https://services.gradle.org/distributions/gradle-8.1.1-bin.zip -P /opt
Jenkins 설치
jenkins 공식 홈페이지 설치 가이드를 참고합니다.
# sudo wget -O /etc/yum.repos.d/jenkins.repo \
https://pkg.jenkins.io/redhat-stable/jenkins.repo
# sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
# sudo yum upgrade
# sudo yum install jenkins
Error: Package: jenkins-2.319.3-1.1.noarch (jenkins)
Requires: daemonize
# cat <<'EOF' > /etc/yum.repos.d/epelfordaemonize.repo
[daemonize]
baseurl=https://download-ib01.fedoraproject.org/pub/epel/7/x86_64/
gpgcheck=no
enabled=yes
EOF
# yum install daemonize -y
# sudo yum install jenkins
# sudo systemctl daemon-reload
# sudo systemctl enable jenkins
# sudo systemctl start jenkins
방화벽 작업
개발PC에서 Jenkins 웹서버로 접근 및 Github Webhook 서버의 방화벽을 오픈합니다.
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address=xxx.xxx.xxx.0/24 port port="8080" protocol="tcp" accept'
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address=192.30.252.0/22 port port="8080" protocol="tcp" accept'
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address=185.199.108.0/22 port port="8080" protocol="tcp" accept'
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address=140.82.112.0/20 port port="8080" protocol="tcp" accept'
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address=143.55.64.0/20 port port="8080" protocol="tcp" accept'
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address=2a0a:a440::/29 port port="8080" protocol="tcp" accept'
# sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv6" source address=2606:50c0::/32 port port="8080" protocol="tcp" accept'
# firewall-cmd --reload
# firewall-cmd --list-all
호스트 추가
Spring test에서 메일 전송 테스트 같이 특정 host 정보를 사용한다면 /etc/hosts에 추가 해야 합니다. 그렇지 않으면 UnknownHost 오류가 발생합니다.
#vim /etc/hosts
xxx.xxx.xxx.xxx mail.test.net
개발PC에서 브라우저로 http://Jenkins서버IP:8080/ 접속 해보면 아래와 같은 화면이 나옵니다.
안내 문구에서 빨간색 부분을 출력하면 패스워드가 나오며 출력값을 input 박스에 붙여넣고 진행하면 됩니다.
# cat /var/lib/jenkins/secrets/initialAdminPassword
63d1901qa2323743ba91267cc0a58d7de
다음으로 플로그인 설정화면이 나옵니다.
Select plugins to install을 선택하면 기본적으로 추천하는 플러그인들이 선택되어 있으며 추가적으로 필요한 플러그인들을 선택할 수 있습니다.
플러그인 선택을 완료한 다음 아래 install 버튼을 클릭하면 플러그인이 설치 됩니다.
플러그인 설치가 완료되면 계정 등록 화면이 나오며, 계정 등록이 끝나면 Jenkins 메인 페이지를 볼 수 있습니다.
Jenkins 플러그인 추가
Github 관련된 추가로 플러그인을 설치하기 위해 Jenkins 관리 > 플러그인 관리에서 설치가능 탭에서 Github Integration을 검색하여 설치합니다.
추가로 원격 서버에 빌드 파일을 배포하기 위해 publish over ssh 플러그인을 사용하는데, 최신 버전에서는 보안의 이유로 제외되었습니다. 수동으로 플러그인을 설치 하기 위해 publish-over-ssh.hpi를 다운로드 받고 플러그인 고급탭에서 플러그인을 설치합니다.
설치 후 jenkins를 재시작하고 다시 플러그인 관리로 와서 설치된 플러그인 목록을 보면 Publish Over SSH가 추가된 것을 확인할 수 있습니다.
Jenkins 설정
Github 홈페이지 설정에서 Jenkins용 토큰을 생성합니다.
토큰을생성할 때 권한은 아래와 같이 설정합니다.
메인 좌측 메뉴 > Jenkins 관리 > 시스템 설정에서 아래로 내려보면 Github 항목에서 Credentials Add한 다음 Manage hooks를 체크하고 Test connnection 버튼을 클릭해보세요.
Credentials Add 팝업에서 Secret는 발급받은 토큰값을 넣으면 됩니다.
Credentials verified for user …, rate limit: 4999 으로 나오면 성공
하단에 저장 버튼을 누르면 메인으로 돌아옵니다.
Github WebHook 설정
Payload URL에서 Jenkins서버ip:포트는 Jenkins 관리자의 메인 좌측 메뉴 > Jenkins 관리 > 시스템 설정에서 Jenkins Location에 입력된 값을 넣어야 합니다.
예) http://Jenkins서버IP:포트/github-webhook/
Just the push event 옵션은 push 일 때 이벤트가 발생한다는 의미입니다.
Add webhook을 누르면 webhook이 추가됩니다.
메인 좌측 메뉴 > Jenkins 관리 > Global Tool Configuration에서 JDK, Git, Gradle을 설정합니다.
프로젝트에 맞는 Gradle 버전이 필요하면 install automatically 옵션으로 추가하면 간단하게 사용 가능합니다.
작업의 편리성을 위해 jenkins를 root 사용자로 작업합니다. (보안상 계정을 사용하시는걸 추천합니다.)
# vim /etc/sysconfig/jenkins
$JENKINS_USER="root"
# systemctl restart jenkins
배포(원격) 서버에 SSH 접속을 위한 SSH Key생성을 합니다.
[Jenkins 서버] jenkins를 root 사용자로 지정하였으므로 root 홈으로 이동하여 key를 생성합니다.
# cd /root
# ssh-keygen -t ecdsa -b 521 -m PEM
# ls /root/.ssh
id_ecdsa id_ecdsa.pub
[배포(원격) 서버]
# ssh-keygen -t ecdsa -b 521 -m PEM
#vim /root/.ssh/authorized_keys
Jenkins 서버의 id_ecdsa.pub값 추가 후 저장
[Jenkins 서버] SSH 서버 설정 및 접속 테스트
메인 좌측 메뉴 > Jenkins 관리 > 시스템 설정에서 아래로 내려보면 Publish over SSH 항목이 보이며 아래와 같이 내용을 편집하고 Test Configuration을 눌러서 Success가 나오는지 확인합니다.
Name: 임의의 이름
Hostname: /etc/hosts 파일에 명시된 호스트명 또는 ip
Username: 접속 계정명
Remote Directory: 애플리케이션 루트 경로( 접속 계정은 이 경로에 접근할 수 있는 권한이 있어야 함)
Rocky Linux 9버전에서 ssh 접속이 되지 않는 현상 발생
sshd[6172]: main: sshd: ssh-rsa algorithm is disabled
https://osg.kr/archives/718
openssh 버전은 openssh-8.7p1-29.el9_2 **버전이였고, 기존에 ssh 접속 가능한 서버는 **rockylinux 8 + openssh-8.0p1-10.el8.x86_64이였다.
Jenkins 작업 생성
✔메인 좌측 메뉴 > 새로운 Item > Freestyle project를 선택하고 작업 이름을 입력합니다.
✔ 연결할 Github Repository 주소를 입력합니다.
✔ Git 설정을 합니다.
ssh 연동 방법: https://osg.kr/archives/700
✔ Gradle 빌드 설정
✔ Junit 테스트 report 설정
빌드 후 조치에서 Publish Junit test result report를 선택합니다.
추가된 Publish Junit test result report에서 Test report XMLs 값을 build/test-results/test/*.xml로 지정합니다.
이 위치는 jenkins에서 빌드가 완료되면 project home path(/var/lib/jenkins/workspace/프로젝트명)가 생성되는데 그 하위에 build/test-results/test를 보면 다음과 같은 xml 파일들이 있습니다.
✔빌드 후 조치에서 Send build artifacts over SSH를 선택합니다.
빌드 후 조치에서 상세 항목을 편집합니다.
Name: 임의의 이름
Source files: 원격 서버에 배포할 파일을 지정합니다. Jenkins가 빌드를 완료하면 /var/lib/jenkins/workspace/solution-shop/build/libs 위치에 jar파일을 생성하는데 workspace 경로를 제외하고 입력합니다.
Remove prefix: jar 파일만 전송하기 위해 앞에 build/libs 폴더를 제외 시킵니다.
Remote directory: 원격 서버에 배포할 경로를 지정합니다. (생략하면 설정에서 등록한 web-app-server1의 remote directory경로로 설정됩니다.)
Exec command: 원격 서버에 배포한 다음 실행할 명령어를 등록합니다.
저장을 누르면 메인화면에서 작업이 추가된 것이 보입니다.
배포(원격) 서버에 서비스 설정을 합니다.
배포 서버에 접속하여 아래와 같은 설정을 합니다.
Java가 설치되어 있어야 합니다. (위에 Java 설치 참고)
서비스 경로 만들기
# mkdir /app
서비스 등록
# vim /etc/systemd/system/web-app-shop.service
[Unit]
Description=kdr solution shop web service
Wants=network-online.target
After=network-online.target
[Service]
User=root
ExecStart=/bin/bash -c "exec java -jar -DSpring.profiles.active=prod /app/shop/*.jar -XX:MinRAMPercentage=10 -XX:MaxRAMPercentage=15"
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
# systemctl daemon-reload
# systemctl enable web-app-shop
Spring 프로젝트를 커밋 하기 전에 몇가지 수정 및 추가를 합니다.
application-prod.yml (운영서버 배포 설정 파일)에서 서버 포트, shutdown,
server:
port: 9090
shutdown: graceful
spring:
lifecycle:
timeout-per-shutdown-phase: 30s
...
file:
path: /app/shop/logs
build.gradle에서 jar task를 skip하도록 설정을 추가합니다. 이것을 하지 않으면 빌드 후 xxx.jar, xxx-plain.jar 두개의 파일이 생성됩니다.
jar {
enabled(false)
}
배포 script를 작성합니다. (배포 서버 OS가 Rocky Linux입니다.)
프로젝트에 shell script 파일 하나를 추가합니다.
deploy.sh 파일에 다음과 같이 작성합니다.
#!/bin/bash
APP_NAME="solution"
SOURCE_PATH=/app
DEPLOY_PATH=/app/shop
LOG_PATH=/app/shop/logs
BACKUP_PATH=/app/shop/backup
HEALTH_CHECK_URL="http://localhost:9090/member/login"
today=`date`
if [ ! -d $LOG_PATH ] ;
then
mkdir $LOG_PATH
sleep 1
fi
if [ ! -d $DEPLOY_PATH ] ;
then
mkdir $DEPLOY_PATH
sleep 1
fi
if [ ! -d $BACKUP_PATH ] ;
then
mkdir $BACKUP_PATH
sleep 1
fi
echo "[$today] deploy start!!" >> $LOG_PATH/deploy.log
echo "[$today] copy backup jar" >> $LOG_PATH/deploy.log
cp -f $DEPLOY_PATH/*.jar ${BACKUP_PATH}
echo "[$today] stop systemctl stop web-app-shop" >> $LOG_PATH/deploy.log
systemctl stop web-app-shop
sleep 15
echo "[$today] source move to deploy path" >> $LOG_PATH/deploy.log
mv $SOURCE_PATH/$APP_NAME*.jar ${DEPLOY_PATH}
echo "[$today] systemctl start web-app-shop" >> $LOG_PATH/deploy.log
systemctl start web-app-shop
sleep 15
echo "[$today] start health check web-app-shop" >> $LOG_PATH/deploy.log
online=false
loopCount=1
while [ $loopCount -le 5 ]
do
code=$(curl -sL --connect-timeout 20 --max-time 30 -w "%{http_code}\\n" "$HEALTH_CHECK_URL" -o /dev/null)
echo "[$today] start health check web-app-shop $loopCount => code: $code" >> $LOG_PATH/deploy.log
if [ "$code" = "200" ];
then
online=true
break
else loopCount=$((loopCount + 1))
sleep 1
fi
done
echo "online : $online" >> $LOG_PATH/deploy.log
if $online; then
echo "[$today] web-app-shop is online." >> $LOG_PATH/deploy.log
exit 0 # Success
else
echo "[$today] web-app-shop start fail." >> $LOG_PATH/deploy.log
echo "[$today] web-app-shop recovery." >> $LOG_PATH/deploy.log
cp -f $BACKUP_PATH/*.jar ${DEPLOY_PATH}
sleep 1
systemctl restart web-app-shop
exit 1 # Failed
fi
수정이 완료 되었다면 merge 후 master에 push를 날려봅니다.
Jenkins 웹화면을 보면 좌측에 빌드 실행상태에 빌드가 진행중인 것이 보이고 Console Output을 클릭해보면 현재 진행상태를 알 수 있습니다.
좌측 메뉴에 Test Result를 눌러보면 테스트 결과도 확인할 수 있습니다.
빌드가 완료되면 /var/lib/jenkins/workspace 경로 아래에 파일이 생성됩니다.
# ls /var/lib/jenkins/workspace/solution-shop/build/libs
solution-1.0.1.jar
빌드 후 배포(원격) 서버의 서비스 상태를 확인 해봅니다.
# ls /app/shop
backup deploy.sh logs solution-1.0.1.jar
# systemctl status web-app-shop
● web-app-shop.service - kdr solution shop web service
Loaded: loaded (/etc/systemd/system/web-app-shop.service; enabled; vendor preset: disabled)
Active: active (running) since Mon 2022-02-14 19:33:11 KST; 3min 46s ago
Main PID: 12050 (java)
Tasks: 50 (limit: 49488)
Memory: 720.4M
CGroup: /system.slice/web-app-shop.service
└─12050 java -jar -DSpring.profiles.active=prod /app/shop/solution-1.0.1.jar
# vim /app/shop/logs/application.log
22-02-14 19:10:12.621 INFO o.s.b.w.e.tomcat.GracefulShutdown - Commencing graceful shutdown. Waiting for active requests to complete
22-02-14 19:10:12.625 INFO o.s.b.w.e.tomcat.GracefulShutdown - Graceful shutdown complete
22-02-14 19:10:12.652 INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
22-02-14 19:10:12.654 INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown initiated...
22-02-14 19:10:12.660 INFO com.zaxxer.hikari.HikariDataSource - HikariPool-2 - Shutdown completed.
22-02-14 19:10:12.660 INFO o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
22-02-14 19:10:12.661 INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
22-02-14 19:10:12.667 INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
22-02-14 19:10:14.402 INFO o.h.validator.internal.util.Version - HV000001: Hibernate Validator 6.2.0.Final
22-02-14 19:10:14.413 INFO n.kdrco.solution.SolutionApplication - Starting SolutionApplication using Java 11.0.11 on web-app-server1 with PID 12050 (/app/shop/solution-1.0.1.jar started by root in /)
22-02-14 19:10:14.421 INFO n.kdrco.solution.SolutionApplication - The following profiles are active: prod
...
22-02-14 19:33:21.376 INFO o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 9090 (http) with context path ''
22-02-14 19:33:21.996 INFO o.s.s.a.ScheduledAnnotationBeanPostProcessor - No TaskScheduler/ScheduledExecutorService bean found for scheduled processing
22-02-14 19:33:22.010 INFO n.kdrco.solution.SolutionApplication - Started SolutionApplication in 10.228 seconds (JVM running for 10.878)
Slack으로 알림 받기
Slack 앱에서 Jenkins를 설치합니다.
설치가 완료되면 안내 페이지가 나오는데 아래로 내려보면 토큰 값이 있습니다. 이것을 복사 해둡니다.
Jenkins 웹 > Jenkins 관리 > 플러그인 관리에서 Slack Notification을 설치합니다.
Jenkins 관리 > Manage Credential Add credentials에서 Slack 을 추가합니다.
Secret에 복사 해둔 slack 토큰 값을 입력합니다.
이전에 생성해둔 작업 설정에서 빌드 조치에 Slack Notifications를 추가합니다.
성공, 실패, Unstable( 등록해둔 shell script가 실패한 경우) 등을 추가합니다.
고급을 눌러 slack 정보를 기입합니다.
workspace: Slack의 team’s workspace name(예: kdr-company)
Credential: Manage Credential에서 추가한 slack을 선택합니다.
Channel: 알림을 받을 채널명을 적어줍니다. (예 #jenkins-build)
Jenkins 빌드를 다시 해보면 아래와 같이 Slack으로 알림이 옵니다.
기타 / 참고
카나리(canary) 배포 전략
새로운 버전을 모든 서버가 아닌 일부 서버에만 배포해서 긴 시간 충분히 모니터링하며 이상 여부를 판단한 후에 나머지 서버에 배포하는 방법으로, 문제 발생 여부를 빠르게 판단할 수 있다는 장점이 있습니다. 아래 그림과 같이 처음에는 서버 한 대에만 배포하고, 모니터링을 완료하면 서버의 3분의 1부터 전체에 이르기까지 여러 번에 나누어 배포를 진행합니다.
배포하다가 장애가 발생하면 먼저 배포 공지 스레드에 현재 상황을 공유하고 배포 도구에 남아 있는 이전 버전의 결과물로 재배포를 진행합니다. 롤백 과정을 완료하면 장애가 발생한 내용의 PR을 되돌리고(revert) 새로운 버전의 태그를 추가로 발급한 다음 장애가 발생한 버전의 태그를 Git에서 제거합니다. 이렇게 하면 나중에 잘못된 버전으로 롤백하는 것을 방지할 수 있습니다.
참고:
https://www.jenkins.io/doc/
https://www.redhat.com/ko/topics/devops/what-is-ci-cd
https://engineering.linecorp.com/ko/blog/build-a-continuous-cicd-environment-based-on-data/
https://engineering.linecorp.com/ko/blog/line-ads-devops-culture/
댓글남기기