[ 구성 흐름도]
![](https://blog.kakaocdn.net/dn/RNnMB/btsAF0jcogq/RgeqbjxQEPsZs8zDpOqja0/img.png)
[1] 젠킨스 서버 생성 (마스터 & 에이전트)
![](https://blog.kakaocdn.net/dn/bJn2im/btsAD4GnJD7/kiQznBNRIhj3jxtfaDl2p0/img.png)
- sudo apt update
- sudo apt upgrade
- sudo apt install openjdk-17-jre (자바17 설치)
- java -version
![](https://blog.kakaocdn.net/dn/ptl6l/btsAF2OQGFv/fLlwcx41foo9kGCM78tcl0/img.png)
![](https://blog.kakaocdn.net/dn/0dEmJ/btsAD2oizUw/eIG7J0xVDGkV4Ze8bbVkc1/img.png)
- 젠킨스 사이트 이동 (복사 및 설치)
https://www.jenkins.io/doc/book/installing/linux/
![](https://blog.kakaocdn.net/dn/byec4F/btsAxUdZPo7/G8KcD8Yqt78Xs1ErW3deF0/img.png)
![](https://blog.kakaocdn.net/dn/OjOSQ/btsAGUwfGwf/rzLBSdMhIGt4NmiU9ok1Ok/img.png)
- sudo systemctl enable jenkins
- sudo systemctl start jenkins
- sudo systemctl status jenkins
![](https://blog.kakaocdn.net/dn/bPf4sx/btsAGP2M6WC/WmjB6sXHdJy5mDZkGqKDjk/img.png)
[1-1] 젠킨스 에이전트 서버 추가 구성 (마스터 서버와 동일 하게 설치)
![](https://blog.kakaocdn.net/dn/dvGvQ2/btsAzD399ju/fkLRsvLA59eba7Y1lCUYc0/img.png)
![](https://blog.kakaocdn.net/dn/G5yqD/btsAzDpyyIH/ndTiVKDqkQe22abi3Rkb71/img.png)
- (젠킨스 에이전트 서버) 모든 빌드가 여기서 수행되므로 도커 설치 필요
- sudo apt install docker.io
![](https://blog.kakaocdn.net/dn/bfsTQp/btsAEnlXLBl/DWnqqwTDcSGSR1oF93k0t0/img.png)
- 현재 사용자 (ubuntu) 도커사용 권한 부여
- sudo usermod -aG docker $USER
(vi /etc/group 확인)
![](https://blog.kakaocdn.net/dn/dgp3Db/btsAG1WJpPX/Dz4MB8TRpnvLwrWMAb8Dkk/img.png)
- sudo init 6 (서버 리부팅)
![](https://blog.kakaocdn.net/dn/bjd1Dd/btsAGRmafZW/HpfIDOjKFcQa7dXL8nQloK/img.png)
- (젠킨스 에이전트 서버) /etc/ssh/sshd_config 파일 수정 --> 젠킨스 에이전트와 서버간 통신을 위한 설정
- sudo service sshd reload
![](https://blog.kakaocdn.net/dn/OnfsG/btsAHZqSEd8/bCFQ6PTMge56KiJCvOVZN0/img.png)
![](https://blog.kakaocdn.net/dn/Ea0Q0/btsAFytSB8a/VMXe6xDy5ELI2z0xNmKImK/img.png)
![](https://blog.kakaocdn.net/dn/5Z5qe/btsAD3gGqzo/E39tKGqnmhTfSj9TQtwhek/img.png)
[1-2] 젠킨스 마스터 서버
![](https://blog.kakaocdn.net/dn/bqd0NP/btsAGWHNsqt/BJQXDuQplysT7it66MsSo1/img.png)
![](https://blog.kakaocdn.net/dn/U3HGn/btsAy7RD0RJ/tmuWa7EdXxmKHS6JIMpLhK/img.png)
- sudo service sshd reload
![](https://blog.kakaocdn.net/dn/blz4aY/btsAyrpl48o/Iww79pY3281Q5gzSZDxF5K/img.png)
- 키생성 : ssh-keygen 실행 (id_rsa , id_rsa.pub 파일 생성)
![](https://blog.kakaocdn.net/dn/c2ZQrv/btsAAOq7lrm/XaTpGkUeslKnghF3wbHIX1/img.png)
- vi id_rsa.pub 오픈 (전체 복사)
![](https://blog.kakaocdn.net/dn/bYWGX8/btsAD3Vg4xK/2Qduhd5midDagEcADQZkYK/img.png)
- 에이전트 서버로 이동 .ssh 폴더로 이동 --> authorized_keys 오픈해서 붙여넣기
![](https://blog.kakaocdn.net/dn/zDNKX/btsAFx2Snui/TBNjAdTf0OwVs9Sqjq56Y1/img.png)
![](https://blog.kakaocdn.net/dn/cy1UaO/btsAFrooB2O/Fb5gL0Ks6EK6AaKEllEhN1/img.png)
- 에이전트 서버에서 cat authorized_keys 확인하면, 마스터 노드의 공개키를 갖고 있음
![](https://blog.kakaocdn.net/dn/cm2jf1/btsAzannkxJ/kx2iBg5SeqR1nvWooi4Zlk/img.png)
[1-3] 젠킨스 마스터 서버 웹 접속
![](https://blog.kakaocdn.net/dn/dgKK7r/btsAGQnnFuD/m55YVtKkQcEwqI9AgmdC1k/img.png)
![](https://blog.kakaocdn.net/dn/AOuWG/btsAEm1Yqsc/SEhktjaLT1UQkhIi9wLkNk/img.png)
![](https://blog.kakaocdn.net/dn/cKGG0V/btsAHZkbJPp/TDfyEmP194KND4daNq5eFk/img.png)
![](https://blog.kakaocdn.net/dn/uOzPI/btsAGRfxd2I/K1GMKir4rizxusLMU3cw31/img.png)
- 젠킨스 관리 --> 노드 --> Built-In Node 클릭 --> Configure 클릭 --> Number of executors '0' 선택 --> SAVE
![](https://blog.kakaocdn.net/dn/bzvWzg/btsABA6YlHb/6YrkFcwiRcj98dGwSWef3K/img.png)
![](https://blog.kakaocdn.net/dn/cdm3jP/btsAF4sO0ey/ohIKLgnmIM5KQ4FGElZ0hk/img.png)
- 젠킨스 관리 --> 노드 --> New Node 클릭 --> Jenkins-Agent 생성
![](https://blog.kakaocdn.net/dn/pGgSE/btsAFGeGz8w/TSUwnfSwrD2KhCuKPfmKZK/img.png)
![](https://blog.kakaocdn.net/dn/bbLLQF/btsABAlA6WB/gJzs3XdmmolRKkKrBMP4rk/img.png)
![](https://blog.kakaocdn.net/dn/JwxQi/btsAFZSspsu/cUKfGXfz7nIkI94kIOAjV1/img.png)
![](https://blog.kakaocdn.net/dn/c0VYPS/btsAzdYO2zS/TxVupCU5ih6thM1JIHn3Ek/img.png)
- 젠킨스 에이전트 서버의 내부 IP 등록
![](https://blog.kakaocdn.net/dn/kZ8LI/btsABBSpXsW/GmEHk67TKdaqlptYZ1qEv1/img.png)
![](https://blog.kakaocdn.net/dn/bcJmjz/btsAGTxI3n1/EktK2BWdo9wcdL7F111Xt1/img.png)
![](https://blog.kakaocdn.net/dn/b4MfMh/btsAF7JQ1O7/Qv1YoDJZvSKLEn3GN0v2i0/img.png)
![](https://blog.kakaocdn.net/dn/vYQBi/btsAHYTeqJS/RR1wFCDNCK1Oyvn53EkE11/img.png)
- 젠킨스 마스터 노드의 개인키 복사후, 등록
![](https://blog.kakaocdn.net/dn/b0Ok6Y/btsAFGZ6yus/v9hPToPcRFbDZE63Bm8FrK/img.png)
![](https://blog.kakaocdn.net/dn/d8RpJZ/btsAJyT0Sd6/Aj9T0Re1v7KxsKfmvGBXEK/img.png)
- Non verifying Verification Strategy 선택
![](https://blog.kakaocdn.net/dn/ccEyBA/btsAJzL9O2e/mFmbT8njGigMuhkk533cF0/img.png)
![](https://blog.kakaocdn.net/dn/biOW4n/btsAza19uwz/QPwtafSNahZYZt0keWC6J0/img.png)
![](https://blog.kakaocdn.net/dn/enDhEe/btsAJfUBwCK/KKMbYu4eWA97agsKMYkN9K/img.png)
- 최종적으로 에이전트 서버가 젠킨스에 추가됨
[1-4] 젠킨스 테스트용 빌드 수행 (24분)
- 파이프라인 생성 --> Test --> ok 클릭 --> Hello world 생성 --> Save
![](https://blog.kakaocdn.net/dn/bU1dMS/btsAFuFGVE6/ojP5ugKoLydWW84jThcyc1/img.png)
![](https://blog.kakaocdn.net/dn/CS5b0/btsAIF6YyXo/43yIGYBcGn5PQwCykX0wk0/img.png)
![](https://blog.kakaocdn.net/dn/dR5XNO/btsAHYThags/5ZFaUMoBwM89PKk4CJzai0/img.png)
[2] 젠킨스 서버에 Maven 설정 및 Github 자격증명 등록 (25분)
![](https://blog.kakaocdn.net/dn/dghl8e/btsAJhSwOEs/vLM9t5W25Xcz7STbJKnhTk/img.png)
- 플러그인 설치 (젠킨스에 내장 설치 방법)
- Maven Integration 3.23
- Pipeline Maven Integration
- Eclipse Temurin installer
![](https://blog.kakaocdn.net/dn/dCoZ4w/btsAJzetV2o/6OiJ97w3NAJjzmCR6nOdh0/img.png)
1) 젠킨스 관리 --> Tools --> Maven 설정 (기존 maven-3.9.5 , /opt/maven-3.9.5 했지만 추가 설정함)
![](https://blog.kakaocdn.net/dn/JO1dm/btsAGZSBbyY/dHSQwSrVkKi54froEKr6Hk/img.png)
2) 젠킨스 관리 --> Tools --> JDK installations 설정
![](https://blog.kakaocdn.net/dn/cCZmT0/btsABBdZIhe/c1l2u4dbRjwq3IlRvhTZX1/img.png)
3) Github 자격증명 --> 젠킨스에 추가
- 젠킨스 관리 --> Credentials --> Add Credentials (Username 과 Password 동일해야 함)
![](https://blog.kakaocdn.net/dn/ySCUe/btsAJymnHT2/MWLBHi9D9sF5A1jzPdQdEK/img.png)
![](https://blog.kakaocdn.net/dn/k31dg/btsAF4GDrR9/5lz2IoG7oKzM4ZMnKM5OhK/img.png)
![](https://blog.kakaocdn.net/dn/bmXMbl/btsAIFzig9J/aJtkHy9O1r7EDc4Fvds0Jk/img.png)
- (위의 password 에 깃허브 토큰 입력)
- 깃허브로 가서 토큰 확인 --> Settings --> Developer settings --> Tokens (classic)
![](https://blog.kakaocdn.net/dn/KqCjn/btsAGVia40y/2F8XwwlWMGtoRFibNrqa51/img.png)
![](https://blog.kakaocdn.net/dn/T5isl/btsAByIl1wR/Ke14noaHcZbhwjpfQkU7g1/img.png)
![](https://blog.kakaocdn.net/dn/mTPe9/btsAFG66a8C/U4kPfuEnyPsPdGrKwbeLuK/img.png)
- Github 자격증명 생성 완료
![](https://blog.kakaocdn.net/dn/dQ8jYS/btsAJFZ2gSx/fRkUkhPNyRd24nKJq4f1y0/img.png)
[3] 빌드용 Jenkinsfile 생성 & 테스트 아티팩트, CI Job 생성 (30분)
![](https://blog.kakaocdn.net/dn/Fa5xT/btsAG0RHcil/knkNK1UFBO8UAtZU2rwCBK/img.png)
https://github.com/Ashfaque-9x/register-app
![](https://blog.kakaocdn.net/dn/bWRYuW/btsAGZLZURy/Rxkx1s6uXk0kKrtcEJJQ7k/img.png)
![](https://blog.kakaocdn.net/dn/BkunW/btsAFqXWZ4G/tKfSNIgN3aRaJxwuyNTLZ0/img.png)
- 빌드용 Jenkinsfile 생성 (영상용)
pipeline {
agent { label 'Jenkins-Agent' }
tools {
jdk 'Java17'
maven 'Maven3'
}
stages{
stage("Cleanup Workspace"){
steps {
cleanWs()
}
}
stage("Checkout from SCM"){
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/register-app'
}
}
stage("Build Application"){
steps {
sh "mvn clean package"
}
}
stage("Test Application"){
steps {
sh "mvn test"
}
}
}
}
- 젠킨스 파이프라인 CI Job 생성 (42분)
: register-app-ci
![](https://blog.kakaocdn.net/dn/4Axre/btsAFtmORKW/PUUNdS1oQc2kltzkBftBN1/img.png)
![](https://blog.kakaocdn.net/dn/cBRGzQ/btsAD1jnIaA/a14mHZtHL141HvxxwdgRdk/img.png)
![](https://blog.kakaocdn.net/dn/2BKB9/btsAIbL3ZhH/EqJPQ0wEEt7WBuj6GF5xQ0/img.png)
![](https://blog.kakaocdn.net/dn/mKfWW/btsAHZkK0ua/fD34cLO1w8Nd3g0jvWqkK1/img.png)
![](https://blog.kakaocdn.net/dn/bBocHE/btsAKbrdnnk/KKw9ukkjGUmWgCv06ZkNmk/img.png)
![](https://blog.kakaocdn.net/dn/cQw9Xv/btsAK8A0V06/7fOVYLsmKwunsLbHUu4vMk/img.png)
- 빌드용 Jenkinsfile 생성 (적용)
pipeline {
agent any
tools {
jdk 'Java17'
maven 'Maven3'
}
stages{
stage("Cleanup Workspace"){
steps {
cleanWs()
}
}
stage("Checkout from SCM"){
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/register-app'
}
}
stage("Build Application"){
steps {
sh "mvn clean package"
}
}
stage("Test Application"){
steps {
sh "mvn test"
}
}
}
}
[4] 소나큐브 설치 및 설정 (42분)
![](https://blog.kakaocdn.net/dn/b16Vw9/btsAFZ6HZJB/tgEPMCBmHtMbN5ZRfG7Yo1/img.png)
## Update Package Repository and Upgrade Packages
$ sudo apt update
$ sudo apt upgrade
## Add PostgresSQL repository
$ sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
$ wget -qO- https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo tee /etc/apt/trusted.gpg.d/pgdg.asc &>/dev/null
![](https://blog.kakaocdn.net/dn/Fl7Qy/btsAIGMiRG0/eRPkzAE8UES7iHXSsODuo0/img.png)
## Install PostgreSQL
$ sudo apt update
$ sudo apt-get -y install postgresql postgresql-contrib
$ sudo systemctl enable postgresql
![](https://blog.kakaocdn.net/dn/6kxk4/btsAJv4Knjs/QaycgX3onPU19aLe1iS4Ek/img.png)
![](https://blog.kakaocdn.net/dn/bIAf1x/btsAGSTNKaX/uqH0ZgtX6hv3GuqevLw9WK/img.png)
## Create Database for Sonarqube
$ sudo passwd postgres
$ su - postgres
$ createuser sonar
$ psql
$ ALTER USER sonar WITH ENCRYPTED password 'sonar';
$ CREATE DATABASE sonarqube OWNER sonar;
$ grant all privileges on DATABASE sonarqube to sonar;
$ \q
$ exit
![](https://blog.kakaocdn.net/dn/u3gzK/btsAD1DW0nu/y7kLwZN8vhKbzDmNyyiKg1/img.png)
![](https://blog.kakaocdn.net/dn/mEcte/btsAJDO7eOp/PC29rkDRAYwwaTKkHKKRB1/img.png)
## Add Adoptium repository
$ sudo bash
$ wget -O - https://packages.adoptium.net/artifactory/api/gpg/key/public | tee /etc/apt/keyrings/adoptium.asc
$ echo "deb [signed-by=/etc/apt/keyrings/adoptium.asc] https://packages.adoptium.net/artifactory/deb $(awk -F= '/^VERSION_CODENAME/{print$2}' /etc/os-release) main" | tee /etc/apt/sources.list.d/adoptium.list
![](https://blog.kakaocdn.net/dn/bsRklc/btsAGRgnuB0/r0yaXUjTkUtvUZqYB85ldk/img.png)
![](https://blog.kakaocdn.net/dn/b1rB4e/btsAF2oSaeF/NOpaUxLgyKjTg3wPsFCHtK/img.png)
![](https://blog.kakaocdn.net/dn/blaIX8/btsAF48bOmG/AhpVP1lRXEWnTXQyQo5jD1/img.png)
## Install Java 17
$ apt update
$ apt install temurin-17-jdk
$ update-alternatives --config java
$ /usr/bin/java --version
$ exit
![](https://blog.kakaocdn.net/dn/M8BN1/btsAJhZOxR3/FVNieHqVOOw3bjsEmPABlK/img.png)
![](https://blog.kakaocdn.net/dn/qJ73v/btsAJ9NI4at/5kn6RciKfN9dNcECiyVsqK/img.png)
## Linux Kernel Tuning
# Increase Limits
$ sudo vim /etc/security/limits.conf
//Paste the below values at the bottom of the file
sonarqube - nofile 65536
sonarqube - nproc 4096
# Increase Mapped Memory Regions
sudo vim /etc/sysctl.conf
//Paste the below values at the bottom of the file
vm.max_map_count = 262144
# 리부팅
![](https://blog.kakaocdn.net/dn/HkApw/btsALaS8CAu/4YSOqxrR1zQmiGYR7fpYrK/img.png)
![](https://blog.kakaocdn.net/dn/bmUd0i/btsAD5l4vyw/zhnQfKe0pN7JsXSvKp44rK/img.png)
![](https://blog.kakaocdn.net/dn/O4IWL/btsAF4f3K9h/ds0gLAKi2RPbJqVvRhiK70/img.png)
## 9000 포트 오픈
![](https://blog.kakaocdn.net/dn/1rkX0/btsAJfHIHBr/HOsP8kFAHuiQXs4zQ7abA0/img.png)
#### Sonarqube Installation ####
## Download and Extract
$ sudo wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-9.9.0.65466.zip
$ sudo apt install unzip
$ sudo unzip sonarqube-9.9.0.65466.zip -d /opt
$ sudo mv /opt/sonarqube-9.9.0.65466 /opt/sonarqube
![](https://blog.kakaocdn.net/dn/cVWFqw/btsAD3hzwXK/XPMLxidFIrexOleR16Q62k/img.png)
## Create user and set permissions (55분)
$ sudo groupadd sonar
$ sudo useradd -c "user to run SonarQube" -d /opt/sonarqube -g sonar sonar
$ sudo chown sonar:sonar /opt/sonarqube -R
![](https://blog.kakaocdn.net/dn/bGIzL7/btsAKUQAYrf/xqQWaULcruO2X44lF8KQI1/img.png)
## Update Sonarqube properties with DB credentials
$ sudo vim /opt/sonarqube/conf/sonar.properties
//Find and replace the below values, you might need to add the sonar.jdbc.url
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
sonar.jdbc.url=jdbc:postgresql://localhost:5432/sonarqube
![](https://blog.kakaocdn.net/dn/10ZXP/btsAKUQC2JM/Sz17aWy7KfjxYmFKhKkpy1/img.png)
## Create service for Sonarqube
$ sudo vim /etc/systemd/system/sonar.service
//Paste the below into the file
[Unit]
Description=SonarQube service
After=syslog.target network.target
[Service]
Type=forking
ExecStart=/opt/sonarqube/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube/bin/linux-x86-64/sonar.sh stop
User=sonar
Group=sonar
Restart=always
LimitNOFILE=65536
LimitNPROC=4096
[Install]
WantedBy=multi-user.target
![](https://blog.kakaocdn.net/dn/KFDPn/btsAJhFMwoL/IftPVYJYxcURzRkc13RIp1/img.png)
- 실제 테스트 서버 스크립트
[Unit]
Description=SonarQube service
After=network.target
[Service]
Type=forking
User=sonar
ExecStart=/opt/sonarqube-9/bin/linux-x86-64/sonar.sh start
ExecStop=/opt/sonarqube-9/bin/linux-x86-64/sonar.sh stop
Restart=always
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
## Start Sonarqube and Enable service
$ sudo systemctl start sonar
$ sudo systemctl enable sonar
$ sudo systemctl status sonar
![](https://blog.kakaocdn.net/dn/W3hRi/btsAIdKsb1K/agNnKJRDzd6GXmXTDxzxnk/img.png)
## Watch log files and monitor for startup
$ sudo tail -f /opt/sonarqube/logs/sonar.log
![](https://blog.kakaocdn.net/dn/baHMFX/btsAIIjkK1N/P3yQplbxzdjM3OvrZ10Ko0/img.png)
## 소나큐브 웹 접속 (admin)
![](https://blog.kakaocdn.net/dn/boridB/btsALUiwi3X/8yzYKnDnOkt6AoIcqagoFK/img.png)
[5] 소나큐브 & 젠킨스 연동 (1:01분)
![](https://blog.kakaocdn.net/dn/bkM5zv/btsAK8OUtvU/Ct7W60uI4XVh0OGqwWLSe0/img.png)
## 소나큐브 토큰 생성 --> 젠킨스 연동용
![](https://blog.kakaocdn.net/dn/cIXMzR/btsAMsfcJS4/NIdhhiMf0XKogwzAfgGcuk/img.png)
![](https://blog.kakaocdn.net/dn/dKm4Gi/btsAJGy3BK0/8xGeMGlsGHQvNywsjeGx2k/img.png)
## 젠킨스에서 플러그인 설치
- SonarQube Scanner
- Sonar Quality Gates
- Quality Gates
![](https://blog.kakaocdn.net/dn/cgVTyR/btsALWnzpHb/Q7DmMlMCpycNiFVmuzpICk/img.png)
- 경고 해제 방법
![](https://blog.kakaocdn.net/dn/Ie2Qv/btsAJIwRftu/5RtSoNGUKdKWYGdy2uKfE0/img.png)
## 젠킨스 관리 --> 시스템 --> 소나큐브 서버 연동 설정
![](https://blog.kakaocdn.net/dn/bfTpbc/btsAK9OhcMq/d6GydLbnutPuaRrJFyFBy1/img.png)
## 젠킨스 관리 --> Tools --> 소나큐브 스캐너 설치
![](https://blog.kakaocdn.net/dn/bJXCfB/btsAGUrhhdd/2vzdzczOANhFulwRrY2GWK/img.png)
## 젠킨스 파이프라인 스크립트에 소나큐브 분석을 위한 단계 추가
![](https://blog.kakaocdn.net/dn/cH846W/btsAJy2ndby/DToL0kBQqX7I7vlhiKZGO0/img.png)
pipeline {
agent any
tools {
jdk 'Java17'
maven 'Maven3'
}
stages{
stage("Cleanup Workspace"){
steps {
cleanWs()
}
}
stage("Checkout from SCM"){
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/register-app'
}
}
stage("Build Application"){
steps {
sh "mvn clean package"
}
}
stage("Test Application"){
steps {
sh "mvn test"
}
}
stage("SonarQube Analysis"){
steps {
script {
withSonarQubeEnv(credentialsId: 'jenkins-sonar-token') {
sh "mvn sonar:sonar"
}
}
}
}
}
}
![](https://blog.kakaocdn.net/dn/racC1/btsAJzAeqDl/iCBIUe9Qw8go0P4ieSTdU0/img.png)
![](https://blog.kakaocdn.net/dn/bUatHx/btsAGQoYr5z/ouObIm1mS9yMZEgrK5m9qK/img.png)
![](https://blog.kakaocdn.net/dn/3Rejg/btsAGQP0uHZ/mvRdTaTdq976OzN8ic9FD0/img.png)
## 소나큐브 웹훅 설정 (1:13분)
- Administration --> Configuration --> Webhooks --> Create 클릭
- 미설정시 --> 소나큐브 품질 게이트 단계 에러 발생
![](https://blog.kakaocdn.net/dn/bcDeOG/btsALbk6EKY/h5ENVvZNV0dX2YVkgWNqrk/img.png)
- 젠킨스 서버의 내부IP 입력
![](https://blog.kakaocdn.net/dn/bwWC6x/btsALafqJ7L/5kznYAGPdg4gmYAagVcRNk/img.png)
![](https://blog.kakaocdn.net/dn/bMylX7/btsAKcR6B5k/AEU9dzNROeCcfxkOnrwrk0/img.png)
- 테스트시 젠킨스 서버 내부IP 입력시 에러 발생 (퍼블릭 IP 등록시 성공 - 보안그룹 오픈 필요)
![](https://blog.kakaocdn.net/dn/mStb9/btsAGYger2v/lsfWjoPN18jxmotpv4KvZk/img.png)
![](https://blog.kakaocdn.net/dn/Bglt8/btsAJ2Wd2xJ/3fC2JWQULmafkjzpKqwz0K/img.png)
## 젠킨스 파이프라인 스크립트에 소나큐브 품질 게이트 단계 추가
![](https://blog.kakaocdn.net/dn/bBZg7m/btsAJFG241G/eS00N7WpVhlQzRpPhYu5Kk/img.png)
pipeline {
agent any
tools {
jdk 'Java17'
maven 'Maven3'
}
stages{
stage("Cleanup Workspace"){
steps {
cleanWs()
}
}
stage("Checkout from SCM"){
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/register-app'
}
}
stage("Build Application"){
steps {
sh "mvn clean package"
}
}
stage("Test Application"){
steps {
sh "mvn test"
}
}
stage("SonarQube Analysis"){
steps {
script {
withSonarQubeEnv(credentialsId: 'jenkins-sonar-token') {
sh "mvn sonar:sonar"
}
}
}
}
stage("Quality Gate"){
steps {
script {
waitForQualityGate abortPipeline: false, credentialsId: 'jenkins-sonar-token'
}
}
}
}
}
![](https://blog.kakaocdn.net/dn/mKZsZ/btsAJEahV0x/MAh6K8cfG64cywUXTsw6bk/img.png)
![](https://blog.kakaocdn.net/dn/cyCbVe/btsAJ2Pwooi/24BgOAOnyqRVPfAoSDmXTK/img.png)
[6] 파이프라인 스크립트로 도커이미지 빌드 및 푸쉬 (1:17분)
![](https://blog.kakaocdn.net/dn/wG6wa/btsAKbffplC/GJK9MM0YkrqcGyhypvzaF0/img.png)
## 젠킨스에 도커관련 플러그인 설치 (6개)
- Docker
- Docker Commons
- Docker Pipeline
- Docker API
- docker-build-step
- CloudBees Docker Build and Publish
![](https://blog.kakaocdn.net/dn/kJ4oO/btsAMkhVrD6/TXArOXtyuh8wxs30qbb5K0/img.png)
## 젠킨스에 도커허브 자격증명 추가
![](https://blog.kakaocdn.net/dn/btHpKo/btsAJ2o3wUi/4Ggrg1cpkrjwpEEz94jQM1/img.png)
- Username : 도커허브의 계정 ID
- Password : 도커허브의 계정 토큰 (하기 도커허브 그림 참고)
- ID : 임의의 ID 생성
![](https://blog.kakaocdn.net/dn/cndpez/btsAMmtjoh2/VKnAb7jChaNZ3W6ZZ41g01/img.png)
![](https://blog.kakaocdn.net/dn/dqdKnL/btsANuxHsbi/Ct3zS1MGk6qzjUQPmcCNuk/img.png)
![](https://blog.kakaocdn.net/dn/cfawtp/btsAMmNECAE/mvqHVojnkvb5Fzkk06izMK/img.png)
![](https://blog.kakaocdn.net/dn/ct1WLX/btsAMTYOTHb/jzpFmg9my5nTQjEyntrR1K/img.png)
## 깃허브에서 Jenkinsfile 내용 추가
pipeline {
agent any
tools {
jdk 'Java17'
maven 'Maven3'
}
environment {
APP_NAME = "register-app-pipeline"
RELEASE = "1.0.0"
DOCKER_USER = "dhrbduf"
DOCKER_PASS = 'dockerhub'
IMAGE_NAME = "${DOCKER_USER}"+"/"+"${APP_NAME}"
IMAGE_TAG = "${RELEASE}-${BUILD_NUMBER}"
}
stages{
stage("Cleanup Workspace"){
steps {
cleanWs()
}
}
stage("Checkout from SCM"){
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/register-app'
}
}
stage("Build Application"){
steps {
sh "mvn clean package"
}
}
stage("Test Application"){
steps {
sh "mvn test"
}
}
stage("SonarQube Analysis"){
steps {
script {
withSonarQubeEnv(credentialsId: 'jenkins-sonar-token') {
sh "mvn sonar:sonar"
}
}
}
}
stage("Quality Gate"){
steps {
script {
waitForQualityGate abortPipeline: false, credentialsId: 'jenkins-sonar-token'
}
}
}
stage("Pom.xml Info"){
steps {
script {
sh "env"
sh "echo ${env.BUILD_ID}"
sh "echo $currentBuild.number"
// def VERSION = readMavenPom().getVersion()
def VERSION = sh(script: 'mvn help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true)
sh "echo $VERSION"
def ARTIFACTID = sh(script: 'mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout', returnStdout: true)
sh "echo $ARTIFACTID"
def GROUPID = sh(script: 'mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout', returnStdout: true)
sh "echo $GROUPID"
}
}
}
stage("Build & Push Docker Iamge"){
steps {
script {
docker.withRegistry('',DOCKER_PASS) {
docker_image = docker.build "${IMAGE_NAME}"
}
docker.withRegistry('',DOCKER_PASS) {
docker_image.push("${IMAGE_TAG}")
docker_image.push('latest')
}
}
}
}
}
}
- 환경변수 추가
![](https://blog.kakaocdn.net/dn/n6Cez/btsAMVPX2is/h9WUQv0btRjS8RVLKKvMNK/img.png)
- 빌드 및 푸쉬 내용 추가
![](https://blog.kakaocdn.net/dn/bxd12i/btsAO5RMLeW/LliijhhIjodwV4j7bRVkdk/img.png)
- 빌드 에러 발생시 (docker.sock 권한 변경 후 해결 - 서버 리부팅 후 초기화됨)
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/auth": dial unix /var/run/docker.sock: connect: permission denied
sudo chmod 666 /var/run/docker.sock
![](https://blog.kakaocdn.net/dn/bcwBjQ/btsAXfUGR0i/kD1i2cfYYqNbJKJIjFVpI1/img.png)
- (향후 서버 리부팅시 적용해 볼것 !!)
![](https://blog.kakaocdn.net/dn/YhAeg/btsATAZLy8S/fbbqGVYt5rinvxWgYFwx10/img.png)
![](https://blog.kakaocdn.net/dn/bd0CUi/btsAMsncSWA/btCkk7UeUP65F2RmGgJvL1/img.png)
![](https://blog.kakaocdn.net/dn/b1ZO03/btsAK836ce7/OhHvFzLd14OTYqNPZ6Lsp0/img.png)
## 도커이미지 빌드 및 푸쉬 성공 (1:25분)
![](https://blog.kakaocdn.net/dn/dnYYDA/btsAKRBifq8/T93wiKpGPCB62O89Pm9pkK/img.png)
![](https://blog.kakaocdn.net/dn/d36HlF/btsALJXhXCL/LfExiHjhgxzUpugzoM1jd0/img.png)
![](https://blog.kakaocdn.net/dn/bMiUsb/btsAOKOfvo3/FMr4R7dGio9JXFsBMJZ3ck/img.png)
![](https://blog.kakaocdn.net/dn/bEShmB/btsAMn7letv/zAEkylvnvZjPJDY96FrR8k/img.png)
[7] 파이프라인 스크립트에 --> 트리비 (Trivy) & 아티팩트 정리 추가 (1:26분)
![](https://blog.kakaocdn.net/dn/odnSP/btsAONRPsBL/Kekzzy8lJEQecY4CoWcJF0/img.png)
stage("Trivy Scan") {
steps {
script {
sh ('docker run -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image ashfaque9x/register-app-pipeline:latest --no-progress --scanners vuln --exit-code 0 --severity HIGH,CRITICAL --format table')
}
}
}
stage ('Cleanup Artifacts') {
steps {
script {
sh "docker rmi ${IMAGE_NAME}:${IMAGE_TAG}"
sh "docker rmi ${IMAGE_NAME}:latest"
}
}
}
[8] eksctl 로 쿠버네티스 구성 (1:29분)
![](https://blog.kakaocdn.net/dn/ckzzxP/btsATDWsWdu/acOXXTYPHJ56E9zgRNX2c0/img.png)
## 부트스트랩 서버 생성
$ sudo apt update
$ sudo apt upgrade
## Install AWS Cli on the above EC2
Refer--https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html
$ sudo su
$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ apt install unzip, $ unzip awscliv2.zip
$ sudo ./aws/install
OR
$ sudo yum remove -y aws-cli
$ pip3 install --user awscli
$ sudo ln -s $HOME/.local/bin/aws /usr/bin/aws
$ aws --version
![](https://blog.kakaocdn.net/dn/bGfBY4/btsAXicNEPm/2nRF49AwPpnAXOWDjoY2u1/img.png)
## Installing kubectl
Refer--https://docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html
$ sudo su
$ curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.1/2023-04-19/bin/linux/amd64/kubectl
$ ll , $ chmod +x ./kubectl //Gave executable permisions
$ mv kubectl /bin //Because all our executable files are in /bin
$ kubectl version --output=yaml
![](https://blog.kakaocdn.net/dn/0T1po/btsAThe4l4i/AiyDt2uEJ2Apdt5DxhaMwk/img.png)
## Installing eksctl
Refer---https://github.com/eksctl-io/eksctl/blob/main/README.md#installation
$ curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
$ cd /tmp
$ ll
$ sudo mv /tmp/eksctl /bin
$ eksctl version
![](https://blog.kakaocdn.net/dn/Tuar6/btsASJbSENK/A7073VUkANoGf2ICWLw5M1/img.png)
## IAM 역할 생성 (부트스트랩 서버에 할당)
- Create Role --> AWS Service --> EC2 --> AdministratorAccess 권한 할당 --> Role이름 (eksctl_role) --> Role생성
![](https://blog.kakaocdn.net/dn/c99qcv/btsASbfsyLr/sK4QkkK9JyGkSD1jzi8yNK/img.png)
![](https://blog.kakaocdn.net/dn/eaMcF9/btsAXhE0q8W/kvl0voyRtxqj3MFmeExwWK/img.png)
![](https://blog.kakaocdn.net/dn/buu4Gi/btsATNEIx8r/beqvKr7XUx0V2kni453Kok/img.png)
![](https://blog.kakaocdn.net/dn/3mQPD/btsASqDERjx/FkOd6Zt9MjIsGEKWKraXU1/img.png)
![](https://blog.kakaocdn.net/dn/bCIQtW/btsATP3u1iJ/uQ3aqnUTrVqzJyvTo3TUsk/img.png)
- 부트스트랩 서버에 역할 연동
![](https://blog.kakaocdn.net/dn/cKzl9D/btsA2tZbWtn/krjkZD6Qjjx24rOsQq3dTK/img.png)
## Setup Kubernetes using eksctl
Refer--https://github.com/aws-samples/eks-workshop/issues/734
$ eksctl create cluster --name virtualtechbox-cluster \
--region ap-south-1 \
--node-type t2.small \
--nodes 3 \
$ kubectl get nodes
![](https://blog.kakaocdn.net/dn/cJyIyJ/btsATgAvNyV/sRGeijeJWf80Gq1jDccOb0/img.png)
![](https://blog.kakaocdn.net/dn/L9fVY/btsAWjwessH/JZmqulE8dHbuXIXY6HkFQK/img.png)
[9] ArgoCD 설치 및 EKS 클러스터 연동 (1:41분)
![](https://blog.kakaocdn.net/dn/FLKyl/btsATlhlGjt/sMPXOkJTCgV8V26rD40E31/img.png)
1 ) First, create a namespace
$ kubectl create namespace argocd
2 ) Next, let's apply the yaml configuration files for ArgoCd
$ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml
![](https://blog.kakaocdn.net/dn/bqkDBG/btsAXiRsi0y/PrKKwpowfljSLoKI7ApMK1/img.png)
3 ) Now we can view the pods created in the ArgoCD namespace.
$ kubectl get pods -n argocd
4 ) To interact with the API Server we need to deploy the CLI:
$ sudo curl --silent --location -o /usr/local/bin/argocd https://github.com/argoproj/argo-cd/releases/download/v2.4.7/argocd-linux-amd64
$ sudo chmod +x /usr/local/bin/argocd
![](https://blog.kakaocdn.net/dn/cRnWHw/btsA26CRa1d/qc0ikLC9gnApkriHFjlqz1/img.png)
5 ) Expose argocd-server
$ kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'
6 ) Wait about 2 minutes for the LoadBalancer creation
$ kubectl get svc -n argocd
![](https://blog.kakaocdn.net/dn/8uB6j/btsA2ZDJXan/dMkLo0HARFEdK2ybX6jU01/img.png)
7 ) Get pasword and decode it. (비밀번호 변경 할것!!)
$ kubectl get secret argocd-initial-admin-secret -n argocd -o yaml
$ echo WXVpLUg2LWxoWjRkSHFmSA== | base64 --decode
![](https://blog.kakaocdn.net/dn/d7qQqy/btsAUHRIyiA/AQSSIjmQ8kL983a6KjSmSK/img.png)
8) ArgoCD 웹화면 확인
![](https://blog.kakaocdn.net/dn/YZJyE/btsATC4KbJ8/aiuaRVHtHAWOi2qUEO0bZ0/img.png)
## Add EKS Cluster to ArgoCD
9 ) login to ArgoCD from CLI
$ argocd login a2255bb2bb33f438d9addf8840d294c5-785887595.ap-south-1.elb.amazonaws.com --username admin
![](https://blog.kakaocdn.net/dn/r8BPE/btsA2whJcQR/66t00cFnUAvIbZohc3F9bK/img.png)
10 ) ArgoCD 클러스터 정보 확인
$ argocd cluster list
![](https://blog.kakaocdn.net/dn/k5Agb/btsA3TwPT5K/S66z7vOoJqkXA3LQsAIdsk/img.png)
11 ) Below command will show the EKS cluster
$ kubectl config get-contexts
12 ) Add above EKS cluster to ArgoCD with below command (NAME 부분을 Add 할것!!)
$ argocd cluster add i-08b9d0ff0409f48e7@virtualtechbox-cluster.ap-south-1.eksctl.io --name virtualtechbox-eks-cluster
![](https://blog.kakaocdn.net/dn/eIAVoI/btsAVtzm6rS/O9rdMRIU3Y2Ypf7kR5dDF1/img.png)
$ argocd cluster list
![](https://blog.kakaocdn.net/dn/9PGHE/btsAXfnjGtS/8QqZuukNOVc7dPe7rtZYi0/img.png)
![](https://blog.kakaocdn.net/dn/b47PWU/btsA2waYByE/ykIwqHSIwLAQ5qj354pQ1k/img.png)
13 ) $ kubectl get svc
[10] 자동화 ArgoCD 설정 & EKS 배포 & 깃허브 (1:53분)
![](https://blog.kakaocdn.net/dn/caPbxh/btsAUoE5uJh/Pz5Q7DcRilvKVze3r0J05K/img.png)
## EKS용 매니페스트 파일 (별도 Github 저장소)
- 이 저장소를 ArgoCD 클러스터에 연결해야 함.
![](https://blog.kakaocdn.net/dn/wO3MA/btsAUoZo7ze/QvP1fFXl5F4nyogy8dKdi1/img.png)
- Argocd --> Settings --> Repositories --> CONNECT REPO --> 깃허브 설정 (비번은 토큰 넣을것!!) --> CONNECT클릭
![](https://blog.kakaocdn.net/dn/Vxz1s/btsAWj4y5rg/lA7WMMKoA0ilqP912LoMrK/img.png)
![](https://blog.kakaocdn.net/dn/bNaYvK/btsATC4Tqvy/zvVKSrJSfe7bLOJpZHaEUk/img.png)
- EKS용 매니페스트 파일 깃허브 연동 성공
![](https://blog.kakaocdn.net/dn/bELHAS/btsATPiHALU/kZ1cfKI1L32z2Pyypu6R01/img.png)
## ArgoCD를 통해 EKS클러스터에 리소스와 APP 배포
- Applications --> 하기내용 설정 --> CREATE 클릭
(생성시 Namespace 와 Image 명 --> yml 파일이 동일한지 확인 할것!!)
![](https://blog.kakaocdn.net/dn/c6wDXE/btsA32gfv1Z/zt4Hv1fLs4yrBkoKQxFK2k/img.png)
![](https://blog.kakaocdn.net/dn/pGQiC/btsAXheuZ0Q/UBYxRSkNm4ugAHoes92RxK/img.png)
![](https://blog.kakaocdn.net/dn/BzsJZ/btsATPC1P8f/PqWxdMpf7DzoLLzFsJh0Y1/img.png)
![](https://blog.kakaocdn.net/dn/TZsXH/btsAVsHmAYZ/IrqJdv7YFYFrWwLs2CveN1/img.png)
![](https://blog.kakaocdn.net/dn/lK1fP/btsAUH5MVul/z4wtc6qKdWCSKrDdrwMsE1/img.png)
![](https://blog.kakaocdn.net/dn/b2yLks/btsATA0pha3/ZOclOn2vgggKKcGHlLK5L0/img.png)
- deployment.yaml 파일
apiVersion: apps/v1
kind: Deployment
metadata:
name: register-app-deployment
namespace: default
spec:
replicas: 2
selector:
matchLabels:
app: register-app
template:
metadata:
labels:
app: register-app
spec:
containers:
- name: register-app
image: dhrbduf/register-app-pipeline:latest
resources:
limits:
memory: "256Mi"
cpu: "500m"
ports:
- containerPort: 8080
- service.yaml 파일
apiVersion: v1
kind: Service
metadata:
name: register-app-service
namespace: default
labels:
app: register-app
spec:
selector:
app: register-app
ports:
- port: 8080
targetPort: 8080
type: LoadBalancer
- kubectl get svc 로 외부서비스 CLB 주소 확인
![](https://blog.kakaocdn.net/dn/VZNAj/btsATmgXgFv/S6VgXm5miIvTfw6lB4KrpK/img.png)
## APP 배포 접속 확인
- ArgoCD를 통해 EKS 클러스터 배포가 완벽하게 진행됨
![](https://blog.kakaocdn.net/dn/IkkEy/btsAVqXcPee/FmFEMdI1SGG8vkXX66wFck/img.png)
![](https://blog.kakaocdn.net/dn/brRRlH/btsATP4be9L/ktuk1n1OPZ0VUAKwAuOkhK/img.png)
[10] 젠킨스 파이프라인으로 CD 작업 생성 (2:00분)
## gitops-register-app-cd 파이프라인 생성
- Old Build 2개로 제한
![](https://blog.kakaocdn.net/dn/ZRsWg/btsA72NUOfS/d61UqYLf6rsw2YlJNJ5i91/img.png)
![](https://blog.kakaocdn.net/dn/2fNwF/btsA3R7JxPx/9pL67hn8KfgdHRnsDt6ZpK/img.png)
- 매개변수 설정 (깃허브의 배포 매니페스트 파일의 이미지 태그를 변경할 때마다 이미지 태그를 지정)
![](https://blog.kakaocdn.net/dn/bbZHFV/btsAWj5pf7d/id0aje7x19med9gPGaDzXk/img.png)
- 빌드를 원격으로 유발
: gitops-token
![](https://blog.kakaocdn.net/dn/cdPffm/btsA7RZ4TvC/T1BEszaPCdjqHXyXmupoY0/img.png)
- 깃허브 설정 후, 저장
![](https://blog.kakaocdn.net/dn/FnU9U/btsA7NwDc7K/OrvRyfusuB4m0eL5ZJjmv0/img.png)
![](https://blog.kakaocdn.net/dn/bt6FCB/btsA6SydGYR/NRnErJkM2izFF19uxJBRc0/img.png)
- 파이프라인 생성
![](https://blog.kakaocdn.net/dn/qIR4m/btsAXiZzx00/KoSbia7A8ffKLr3kDUsGNk/img.png)
## 깃허브 register-app 이동 (CI 빌드 역할 - Jenkinsfile 수정)
![](https://blog.kakaocdn.net/dn/4Svw2/btsA4en6COo/mmbsfUtEM6gM6Vd3Ykjnlk/img.png)
- 한단계 추가 (CD 파이프라인을 트리거)
![](https://blog.kakaocdn.net/dn/cxhkTi/btsA7sTNgMe/TySAP9NPNy8mQzlOWVu221/img.png)
stage("Trigger CD Pipeline") {
steps {
script {
sh "curl -v -k --user clouduser:${JENKINS_API_TOKEN} -X POST -H 'cache-control: no-cache' -H 'content-type: application/x-www-form-urlencoded' --data 'IMAGE_TAG=${IMAGE_TAG}' 'http://젠킨스 내부IP주소:8080/job/gitops-register-app-cd/buildWithParameters?token=gitops-token'"
}
}
}
- JENKINS_API_TOKEN 생성 (젠킨스 콘솔)
1) 유저 --> Configure --> API 토큰 생성 및 복사 (HTTPS 방식만 허용)
![](https://blog.kakaocdn.net/dn/kWVKq/btsA7RTqJvy/1ssKcUsKjA3dUQxKBCue1k/img.png)
![](https://blog.kakaocdn.net/dn/bHPAjm/btsA1b6S194/k1NOlGMfneM0uqQUA6IWAK/img.png)
2) 젠킨스관리 --> Credentials --> 시스템 --> Global Credentials 클릭
![](https://blog.kakaocdn.net/dn/xQr6a/btsA5ftEAK0/KPx4hKJpZHNVle1uutIstK/img.png)
![](https://blog.kakaocdn.net/dn/W0Nh3/btsA7QAeOAt/Y8h287NfUN2wvdRc8zIyi1/img.png)
3) Jenkinsfile 에 --> JENKINS_API_TOKEN 을 환경변수로 설정
![](https://blog.kakaocdn.net/dn/b9E2xx/btsA4UwpNbg/MmjT2uz1zcm4OLdiZrFR31/img.png)
pipeline {
agent any
tools {
jdk 'Java17'
maven 'Maven3'
}
environment {
APP_NAME = "register-app-pipeline"
RELEASE = "1.0.0"
DOCKER_USER = "dhrbduf"
DOCKER_PASS = 'dockerhub'
IMAGE_NAME = "${DOCKER_USER}"+"/"+"${APP_NAME}"
IMAGE_TAG = "${RELEASE}-${BUILD_NUMBER}"
JENKINS_API_TOKEN = credentials("JENKINS_API_TOKEN")
}
stages{
stage("Cleanup Workspace"){
steps {
cleanWs()
}
}
stage("Checkout from SCM"){
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/register-app'
}
}
stage("Build Application"){
steps {
sh "mvn clean package"
}
}
stage("Test Application"){
steps {
sh "mvn test"
}
}
stage("SonarQube Analysis"){
steps {
script {
withSonarQubeEnv(credentialsId: 'jenkins-sonar-token') {
sh "mvn sonar:sonar"
}
}
}
}
stage("Quality Gate"){
steps {
script {
waitForQualityGate abortPipeline: false, credentialsId: 'jenkins-sonar-token'
}
}
}
stage("Pom.xml Info"){
steps {
script {
sh "env"
sh "echo ${env.BUILD_ID}"
sh "echo $currentBuild.number"
// def VERSION = readMavenPom().getVersion()
def VERSION = sh(script: 'mvn help:evaluate -Dexpression=project.version -q -DforceStdout', returnStdout: true)
sh "echo $VERSION"
def ARTIFACTID = sh(script: 'mvn help:evaluate -Dexpression=project.artifactId -q -DforceStdout', returnStdout: true)
sh "echo $ARTIFACTID"
def GROUPID = sh(script: 'mvn help:evaluate -Dexpression=project.groupId -q -DforceStdout', returnStdout: true)
sh "echo $GROUPID"
}
}
}
stage("Build & Push Docker Iamge"){
steps {
script {
docker.withRegistry('',DOCKER_PASS) {
docker_image = docker.build "${IMAGE_NAME}"
}
docker.withRegistry('',DOCKER_PASS) {
docker_image.push("${IMAGE_TAG}")
docker_image.push('latest')
}
}
}
}
stage("Trivy Scan") {
steps {
script {
sh ('docker run -v /var/run/docker.sock:/var/run/docker.sock aquasec/trivy image dhrbduf/register-app-pipeline:latest --no-progress --scanners vuln --exit-code 0 --severity HIGH,CRITICAL --format table')
}
}
}
stage ('Cleanup Artifacts') {
steps {
script {
sh "docker rmi ${IMAGE_NAME}:${IMAGE_TAG}"
sh "docker rmi ${IMAGE_NAME}:latest"
}
}
}
stage("Trigger CD Pipeline") {
steps {
script {
sh "curl -v -k --user admin:${JENKINS_API_TOKEN} -X POST -H 'cache-control: no-cache' -H 'content-type: application/x-www-form-urlencoded' --data 'IMAGE_TAG=${IMAGE_TAG}' 'http://10.50.6.98:8080/job/gitops-register-app-cd/buildWithParameters?token=gitops-token'"
}
}
}
}
}
- Pipeline register-app-ci 빌드 성공
: Pipeline gitops-register-app-cd 작업으로 자동 연동됨 (Jenkinsfile 작성 필요)
![](https://blog.kakaocdn.net/dn/el0O2Q/btsA2wiTiVb/p9BI1JaLJYkcN1DXkmm8yk/img.png)
![](https://blog.kakaocdn.net/dn/H4qha/btsA7xaXV2R/Bl7uK8FtlFglWhLuI47e10/img.png)
![](https://blog.kakaocdn.net/dn/bHzeh5/btsA8KVc7Pl/wJrsvvi2vhcaa85mUzW2Sk/img.png)
[11] 깃허브 gitops-register-app (CD용) Jenkinsfile 생성 (2:12분)
## gitops-register-app 깃허브 이동 (쿠번네티스 매니페스트 파일 있음)
![](https://blog.kakaocdn.net/dn/OPbco/btsBaZ5DCFK/gmjhPQy0CUY5KpooHINYO1/img.png)
![](https://blog.kakaocdn.net/dn/zojg4/btsBgxBkkvG/xDxNeYqP3vNwB1QShn7Kb0/img.png)
## Jenkinsfile 생성
pipeline {
agent any
environment {
APP_NAME = "register-app-pipeline"
}
stages {
stage("Cleanup Workspace") {
steps {
cleanWs()
}
}
stage("Checkout from SCM") {
steps {
git branch: 'main', credentialsId: 'github', url: 'https://github.com/dhrbduf/gitops-register-app'
}
}
stage("Update the Deployment Tags") {
steps {
sh """
cat deployment.yaml
sed -i 's/${APP_NAME}.*/${APP_NAME}:${IMAGE_TAG}/g' deployment.yaml
cat deployment.yaml
"""
}
}
stage("Push the changed deployment file to Git") {
steps {
sh """
git config --global user.name "dhrbduf"
git config --global user.email "dhrbduf@gmail.com"
git add deployment.yaml
git commit -m "Updated Deployment Manifest"
"""
withCredentials([gitUsernamePassword(credentialsId: 'github', gitToolName: 'Default')]) {
sh "git push https://github.com/dhrbduf/gitops-register-app main"
}
}
}
}
}
## 빌드 테스트 결과 deployment.yaml 에 IMAGE_TAG 내용 변경 확인 (CI 쪽의 이미지 태그를 받아옴)
![](https://blog.kakaocdn.net/dn/lvsb5/btsBgwvEA24/ktOvdAqU0Jm0kklIgoVFT0/img.png)
[12] 깃허브 commit 으로 CI/CD 자동화 테스트 구현 (2:21분)
![](https://blog.kakaocdn.net/dn/tjQT0/btsBgvjeDam/TXi3v27rQqoiDEpd04clKk/img.png)
## CI작업에 트리거 설정 (register-app-ci 파이프라인 --> Configure 이동)
- 매 분 깃허브 모니터링 (https://github.com/dhrbduf/register-app.git)
![](https://blog.kakaocdn.net/dn/qrSsR/btsBjqBlBGH/i7Lv1ok7JKDkvDtZVnws11/img.png)
![](https://blog.kakaocdn.net/dn/dPdfU3/btsBfJIRFhZ/pWo57SWTTwr5zvb6k6s7Z0/img.png)
## index.jsp 소스파일 수정 후, git push 완료
![](https://blog.kakaocdn.net/dn/VsBxM/btsBc0dyHLq/sjdUeoSmB7wGGLCX2lWSE1/img.png)
![](https://blog.kakaocdn.net/dn/YZsNh/btsBgIJTZD6/uDu5PicCkRSCjT6k7JeBRk/img.png)
![](https://blog.kakaocdn.net/dn/rLXNF/btsBjRFseGv/eni6KTsaS5PkU3NUzKTLn1/img.png)
## CI Job 수행후, 자동으로 CD Job 수행
![](https://blog.kakaocdn.net/dn/JHDpc/btsBivb5zxQ/janSSKTcRpI6mKxR7US2fK/img.png)
![](https://blog.kakaocdn.net/dn/D55x5/btsBiPuKcQl/jiL8WtNgw7qXHoMdMvTYl1/img.png)
- 도커허브에서 Image 태그 8번 변경 확인
![](https://blog.kakaocdn.net/dn/nzubV/btsBeT6kqq2/CuHFWr5aakeHGwb2LzPSKK/img.png)
- 깃허브에서 Image 태그 8번 변경 확인 (최신 태그)
![](https://blog.kakaocdn.net/dn/5ng0t/btsBfd40V3H/evCQ1fb7YuVCFKnkVdXa7k/img.png)
## ArgoCD로 이동하여 새로고침 수행 (2:27분)
![](https://blog.kakaocdn.net/dn/c8fxwU/btsBjBKR2c0/6zniuTK6XO8rJSXI9XKRyk/img.png)
![](https://blog.kakaocdn.net/dn/bwdqXN/btsBqKfdQOp/Hy8HvknZNLJUfrZYZjnCNK/img.png)
- 테스트시 SYNC --> SYNCHRONIZE 클릭해야 배포됨
![](https://blog.kakaocdn.net/dn/oAySZ/btsBqJm5MvD/Wj94VQCop1TzUNFxCH4gKK/img.png)
![](https://blog.kakaocdn.net/dn/Ij1Jq/btsBjCbWNW5/aZt9g5pDmLLVp6HkEPDYK1/img.png)
## 배포 후 적용된 화면
![](https://blog.kakaocdn.net/dn/bc4w1a/btsBjbFFuaY/lUey6X19K7r3fZXIIfT271/img.png)
![](https://blog.kakaocdn.net/dn/xdXXc/btsBiWV7KJN/pY4Dky4ip0jzOWIKnqZwy1/img.png)
[완료]
## Jenkins & Docker & ArgoCD & EKS 를 사용하여 CI/CD 라이프라인을 구성 !!