๐ฉ๐ป CI/CD
1๏ธโฃ ๊ตฌ์ฑ ์์
- Jenkins Server : AWS EC2 Ubuntu 18.04
- Spring Boot Server : AWS EC2 Ubuntu 18.04
- Github Repository
- Docker Hub Repository
2๏ธโฃ ์งํ ์์
- Jenkins Server์ Docker ์ค์น
- Jenkins Server์ Docker๋ฅผ ์ด์ฉํ์ฌ Jenkins ์คํ
- Jenkins ์ ์
- Jenkins์ Github ์ฐ๋
- Jenkins์ Docker Hub ์ฐ๊ฒฐ
- Jenkins Server์ Spring Boot Server SSH ์ฐ๊ฒฐ ์ค์
- Jenkins์ Slack ์ฐ๋
- Jenkins Pipeline ๊ตฌ์ฑ
- Spring Boot Project Github Repository Clone
- Gradle Build
- Docker Build
- Docker Push
- Spring Boot Server SSH ์ฐ๊ฒฐ
- Docker Pull
- Docker Run
- Slack Notification
์ฌ์ ์ Jenkins Server, Spring Boot Server๋ฅผ ์ํ AWS EC2 ์ธ์คํด์ค 2๊ฐ์ Spring Boot Project๊ฐ ์ฌ๋ผ๊ฐ์๋ Github Repository์ Docker Hub Repository๊ฐ ์์ฑ๋์ด ์์ด์ผ ํ๋ค. ๋๋ถ๋ถ์ ์ค์ ์ Jenkins Server์ ์ ์ํ์ฌ ์งํํ๋ค. Spring Boot Server๋ SSH ์ฐ๊ฒฐ ์ค์ ์ public key๋ฅผ ๋ฑ๋กํ ๋๋ง ์ ์ํ๋ค.
๐ป Jenkins Server EC2
1๏ธโฃ EC2 ์ด๊ธฐ ์ค์
sudo apt update
sudo apt upgrade
sudo apt install build-essential
2๏ธโฃ Docker ์ค์น
1. ๊ธฐ๋ณธ ์ค์ , ์ฌ์ ์ค์น
$ sudo apt update
$ sudo apt install apt-transport-https ca-certificates curl software-properties-common
2. ์๋ ์ค์น ์คํฌ๋ฆฝํธ ํ์ฉ
๋ฆฌ๋ ์ค ๋ฐฐํฌํ ์ข ๋ฅ๋ฅผ ์๋์ผ๋ก ์ธ์ํ์ฌ Docker ํจํค์ง๋ฅผ ์ค์นํด์ฃผ๋ ์คํฌ๋ฆฝํธ๋ฅผ ์ ๊ณต
$ sudo wget -qO- https://get.docker.com/ | sh
3. Docker ์๋น์ค ์คํํ๊ธฐ ๋ฐ ๋ถํ ์ ์๋ ์คํ ์ค์
$ sudo systemctl start docker
$ sudo systemctl enable docker
4. Docker ๊ทธ๋ฃน์ ํ์ฌ ๊ณ์ ์ถ๊ฐ
$ sudo usermod -aG docker ${USER}
$ sudo systemctl restart docker
- sudo๋ฅผ ์ฌ์ฉํ์ง ์๊ณ docker๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
- docker ๊ทธ๋ฃน์ root ๊ถํ๊ณผ ๋์ผํ๋ฏ๋ก ๊ผญ ํ์ํ ๊ณ์ ๋ง ํฌํจ
- ํ์ฌ ๊ณ์ ์์ ๋ก๊ทธ์์ํ ๋ค ๋ค์ ๋ก๊ทธ์ธ
5. Docker ์ค์น ํ์ธ
$ docker -v
3๏ธโฃ Docker๋ก Jenkins ์ค์นํ๊ธฐ
1. Jenkins ์ด๋ฏธ์ง ํ์ผ ๋ด๋ ค๋ฐ๊ธฐ(lts ๋ฒ์ )
$ docker pull jenkins/jenkins:lts
2. ๋ด๋ ค๋ฐ์์ง ์ด๋ฏธ์ง ํ์ธ
$ docker images
3. Jenkins ์ด๋ฏธ์ง๋ฅผ Container๋ก ์คํ
$ docker run -d -p 8080:8080 -p 50000:50000 -v /jenkins:/var/jenkins -v /home/ubuntu/.ssh:/root/.ssh -v /var/run/docker.sock:/var/run/docker.sock --name jenkins -u root jenkins/jenkins:lts
4. ๋์๊ฐ๊ณ ์๋ Container ํ์ธ
$ docker ps
โ EC2 ํ๋ฆฌํฐ์ด์์ Jenkins๊ฐ ์๊พธ ์ฃฝ์ด์..๐คฆโ๏ธ
ํ๋ฆฌํฐ์ด EC2๋ ๋๋ฌด ์๊ณ ์์คํฉ๋๋ค. Jenkins๋ฅผ ๊ตฌ์ฑํ๊ณ ๋น๋ํ๋ฉด ๋ฉ์ถฐ๋ฒ๋ฆฝ๋๋ค. AWS CloudWatch๋ก ์ฌ์ฉ๋ฅ ์ ๋ณด๋ฉด ์์ฃผ ๊ทธ๋ํ๋ฅผ ๋ฐ์ณ ๋๊ฐ๋๋ค. ๊ทธ๋์ ์ฌ์ ์ swap ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํด์ ์ด๋ฌํ ๋ฌธ์ ๋ฅผ ๋ฐฉ์งํ๋ค.
ํ๋ฆฌํฐ์ด EC2 ๊ธฐ๋ณธ RAM์ด 1GB์ด๋, 2GB(128MB * 16) swap ํ์ผ์ ๋ง๋ค์ด ํ ๋นํฉ๋๋ค.
$ sudo dd if=/dev/zero of=/swapfile bs=128M count=16
$ sudo chmod 600 /swapfile
$ sudo mkswap /swapfile
$ sudo swapon /swapfile
$ sudo swapon -s
$ sudo vi /etc/fstab
/swapfile swap swap defaults 0 0
๐คตโ๏ธ Jenkins
1๏ธโฃ Jenkins ์ ์
1. ๋ธ๋ผ์ฐ์ ์์ [EC2 ์ธ์คํด์ค URL]:8080์ผ๋ก ์ ์
2. ์ํธ ์ ๋ ฅ
/var/lib/jenkins/secrets/initialAdminPassword๋ฅผ ํ์ธํด์ผ ํ๋๋ฐ Jenkins Container์ ์ ์ํ์ฌ ์ป์ด์ค๊ฑฐ๋ "docker logs jenkins" ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
// Container์ ์ ์ํ์ง ์๊ณ ํ์ธ
$ docker logs jenkins
// Container ์ ์
$ docker exec -it jenkins bash
// ์ํธ ํ์ผ ํ์ธ
$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword
3. Install suggested plugins๋ก ํ๋ฌ๊ทธ์ธ ์ค์น
4. Jenkins ๊ณ์ ์์ฑ
Jenkins ๋ฉ์ธ ๋์๋ณด๋ ํ์ด์ง๊ฐ ๋์ค๋ฉด ์ฑ๊ณต
2๏ธโฃ Jenkins, Github ์ฐ๋
1. ssh ํค ์์ฑ
Jenkins Container๋ฅผ ์์ฑํ ๋ "/home/ubuntu/.ssh:/root/.ssh"๋ก .ssh ๋ํ ๋๋ฆฌ๋ฅผ ๋ง์ดํธ ํด๋์๊ธฐ ๋๋ฌธ์ Container ๋ฐ์์ ssh ํค๋ฅผ ์์ฑํ๋ฉด Jenkins Container์ ์ฐ๊ฒฐ๋๋ค.
// ๊ทธ๋ฅ ์ ๋ถ enter๋ฅผ ์
๋ ฅํด default๋ก ๋ง๋ ๋ค.
$ ssh-keygen
EC2์ ์ ์ํ๋ฉด ๊ธฐ๋ณธ ์ ์ ๊ฐ ubuntu์ด๊ธฐ ๋๋ฌธ์ /home/ubuntu/.ssh์ id_rsa์ id_rsa.pub์ด ์์ฑ๋๋ค.
2. Github Deploy Key ๋ฑ๋ก
๋ง๋ค์ด ๋์ Github Repository > Settings > Deploy Keys > Add deploy key๋ก ์ ์ํ๋ค.
Title์ Jenkins๋ก ์ง์ด ์ฃผ๊ณ (๋ง์๋๋ก ํด๋ ๋๋ค), Key ๋ถ๋ถ์ id_rsa.pub์ ๋ค์ด์๋ public key ๊ฐ์ ๋ฃ์ด์ค๋ค. ์๋ ๋ช
๋ น์ด๋ก ํ์ธ ๊ฐ๋ฅํ๋ค.
$ cd /home/ubuntu/.ssh
$ cat id_rsa.pub
3. Jenkins Credentials ๋ฑ๋ก
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > Manage Credentials > Credentials์ ์ ์ํ๋ค.
Store Jenkins์ Domain์ด (global)์ธ ํ์ดํ๋ฅผ ๋๋ฌ Global credentials (unrestricted)๋ก ์ด๋ํ๋ค.
์ผ์ชฝ ๋ฉ๋ด์ Add credentials๋ฅผ ๋๋ฌ credentials๋ฅผ ์ถ๊ฐํ๋ค.
- Kind
SSH Username with private key - ID
github -> ๋ง์๋๋ก ์ง์ด๋ ๋๋ค. ๋ค๋ง Pipeline Script ์์ฑ ์ credentialsId๋ก ์ฌ์ฉ๋๋ ์๋ณํ ์ ์๋๋ก ํ์. - Username
root (default) - Private Key
Enter directly ์ฒดํฌ -> private key ์ ๋ ฅ
์ฌ๊ธฐ์ private key๋ Jenkins Server์์ ์์ฑํ id_rsa์ด๋ค. ์๋ ๋ช ๋ น์ด๋ก ํ์ธ ๊ฐ๋ฅํ๋ค.$ cd /home/ubuntu/.ssh $ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY----- ... ... ์ด์ ๊ฐ์ ํํ์ key๊ฐ private key ์ ๋๋ค ... ... -----END OPENSSH PRIVATE KEY-----
- OK๋ฅผ ๋๋ฌ ํค๋ฅผ ์์ฑ
3๏ธโฃ Jenkins, Docker Hub ์ฐ๊ฒฐ
1. Docker Plugin ์ค์น
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ํ๋ฌ๊ทธ์ธ ๊ด๋ฆฌ > ์ค์น ๊ฐ๋ฅ > Docker ๊ฒ์ > Docker, Docker Pipeline ํ๋ฌ๊ทธ์ธ ์ค์น ๋ฐ ์ฌ์คํ
2. Docker Hub Credentials ๋ฑ๋ก
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > Manage Credentials > Credentials์ ์ ์ํ๋ค.
Store Jenkins์ Domain์ด (global)์ธ ํ์ดํ๋ฅผ ๋๋ฌ Global credentials (unrestricted)๋ก ์ด๋ํ๋ค.
์ผ์ชฝ ๋ฉ๋ด์ Add credentials๋ฅผ ๋๋ฌ credentials๋ฅผ ์ถ๊ฐํ๋ค.
- Kind
Username with password - Username
๋ณธ์ธ์ Docker Hub ID - Password
๋ณธ์ธ์ Docker Hub Password - ID
docker-hub -> ๋ง์๋๋ก ์ง์ด๋ ๋๋ค. ๋ค๋ง Pipeline Script ์์ฑ ์ credentialsId๋ก ์ฌ์ฉ๋๋ ์๋ณํ ์ ์๋๋ก ํ์. - OK๋ฅผ ๋๋ฌ ํค๋ฅผ ์์ฑ
3. Jenkins Container ๋ด๋ถ์ Docker ์ค์น
Jenkins Pipeline์์ Docker ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก Jenkins Container ๋ด๋ถ์ Docker๋ฅผ ์ค์นํด์ผ ํ๋ค.
- Jenkins Container์ ์ ์
$ docker exec -it jenkins bash
- Docker ์ค์น
$ docker run -d -p 8080:8080 -p 50000:50000 -v /jenkins:/var/jenkins -v /home/ubuntu/.ssh:/root/.ssh -v /var/run/docker.sock:/var/run/docker.sock --name jenkins -u root jenkins/jenkins:lts
Jenkins Container๋ฅผ ๊ฐ๋ํ ๋ ์์ ์ฒ๋ผ ์ธ๋ถ Docker volume์ ์ฐ๊ฒฐํด๋์์ ์๋์ฒ๋ผ docker.sock ๊ถํ ๋ณ๊ฒฝ๋ง ํ๋ฉด Container ๋ด๋ถ์์ docker ๋ช
๋ น์ด๊ฐ ์ฌ์ฉ ๊ฐ๋ฅํ๋ค๊ณ ํ๋๋ฐ Pipeline Script๋ฅผ ์์ฑํ๊ณ Buildํ๋๋ docker ๋ช
๋ น์ด ์ฌ์ฉ ๋ถ๋ถ์์ command not found ์๋ฌ๊ฐ ๋ฐ์ํ์ฌ ๊ทธ๋ฅ Container ๋ด๋ถ์๋ Docker๋ฅผ ์ค์นํ์๋ค.
Docker ์ค์น ๋ฐฉ๋ฒ์ ์์์ EC2 ๋ด์ Docker๋ฅผ ์ค์นํ ๋ฐฉ๋ฒ๊ณผ ๋์ผํ๋ค. ๋ค๋ง Container ๋ด๋ถ์ sudo, vi, wget์ด ์ค์น๋์ด ์์ง ์์ ์ฐจ๋ก๋๋ก ์ค์น ํ Docker๋ฅผ ์ค์นํด์ผ ํ๋ค.
- docker.sock ๊ถํ ๋ณ๊ฒฝ
$ sudo chmod 666 /var/run/docker.sock
โ Jenkins Container ๋ด๋ถ์ Docker๋ฅผ ์ค์นํ๋ ๊ฒ์ ๋ํ์ฌ..
- Docker๊ฐ ์ค์น๋์ด ์๋ Jenkins ์ด๋ฏธ์ง ํ์ผ์ ์ฌ์ฉํ๋ค.
- docker exec ๋ช ๋ น์ด๋ก Jenkins Container ๋ด๋ถ๋ก ์ ์ํ ๋ค์ ๋ด๋ถ์ Docker๋ฅผ ์ค์นํ๋ค.
- docker ๊ฒฝ๋ก์ docker.sock ํ์ผ ๊ฒฝ๋ก๋ฅผ ๋์ปค ๋ณผ๋ฅจ์ ์ถ๊ฐํด ์ฌ์ฉํ๋ค.
- ์ด ๋ฐฉ๋ฒ์ ์ฌ์ฉํ๋๋ผ๋ Container ๋ด๋ถ์ docker-cil๋ ์ค์นํด์ผ ํ๋ค๋ ๊ธ์ ๋ณด์๋ค.
- ์คํ ํ์.
4๏ธโฃ Jenkins, Spring Boot Server SSH ์ฐ๊ฒฐ
Jenkins๋ก Gradle ๋น๋ํ๊ณ Dockerfile๋ก ๋์ปค ์ด๋ฏธ์ง๋ฅผ ๋น๋ํด์ Docker Hub์ Pushํ๊ณ Spring Boot Server์์ ๋์ปค ์ด๋ฏธ์ง๋ฅผ Pullํด์ ์คํํ๊ฒ ํ๊ธฐ ์ํด ํ์ํ๋ค. Jenkins Pipeline Script์์ SSH๋ฅผ ์ฌ์ฉํ์ฌ Spring Boot Server์ ๋ช ๋ น์ด ์คํ์ ํ ์ ์๋๋ก ํ๋ ๊ฒ์ด๋ค.
1. SSH Agent Plugin ์ค์น
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ํ๋ฌ๊ทธ์ธ ๊ด๋ฆฌ > ์ค์น ๊ฐ๋ฅ > SSH Agent ํ๋ฌ๊ทธ์ธ์ ๊ฒ์ํ๊ณ ์ค์น ๋ฐ ์ฌ์คํ
2. Spring Boot Server ์ ์
3. Spring Boot Server์ .ssh/authorized_keys ํ์ผ์ Jenkins Server์ public key๋ฅผ ์ถ๊ฐ
// Jenkins Server์์ public key ํ์ธ
$ cat /home/ubuntu/.ssh/id_rsa.pub
// Spring Boot Server์ Jenkins Server public key ์ถ๊ฐ
$ vi /home/ubuntu/.ssh/authorized_keys
4. Jenkins Credentials ๋ฑ๋ก
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > Manage Credentials > Credentials์ ์ ์ํ๋ค.
Store Jenkins์ Domain์ด (global)์ธ ํ์ดํ๋ฅผ ๋๋ฌ Global credentials (unrestricted)๋ก ์ด๋ํ๋ค.
์ผ์ชฝ ๋ฉ๋ด์ Add credentials๋ฅผ ๋๋ฌ credentials๋ฅผ ์ถ๊ฐํ๋ค.
- Kind
SSH Username with private key - ID
ssh -> ๋ง์๋๋ก ์ง์ด๋ ๋๋ค. ๋ค๋ง Pipeline Script ์์ฑ ์ credentialsId๋ก ์ฌ์ฉ๋๋ ์๋ณํ ์ ์๋๋ก ํ์. - Username
root (default) - Private Key
Enter directly ์ฒดํฌ -> private key ์ ๋ ฅ
์ฌ๊ธฐ์ private key๋ Jenkins Server์์ ์์ฑํ id_rsa์ด๋ค. ์๋ ๋ช ๋ น์ด๋ก ํ์ธ ๊ฐ๋ฅํ๋ค.$ cd /home/ubuntu/.ssh $ cat id_rsa
-----BEGIN OPENSSH PRIVATE KEY----- ... ... ์ด์ ๊ฐ์ ํํ์ key๊ฐ private key ์ ๋๋ค ... ... -----END OPENSSH PRIVATE KEY-----
- OK๋ฅผ ๋๋ฌ ํค๋ฅผ ์์ฑ
์ฌ์ค์ ์์ Jenkins์ Github ์ฐ๋ ์ ์์ฑํ Jenkins Credentials๊ณผ ๋์ผํ๋ค. ํ์ง๋ง ID๋ฅผ ๊ตฌ๋ถํ์ฌ ์ฌ์ฉํ๊ณ ์ SSH Credentials์ ๋ณ๋๋ก ์์ฑํ์๋ค.
โ SSH Agent Plugin vs Publish Over SSH Plugin
์ ์ Jenkins Pipeline์ด ์๋ Freestyle project๋ก ๋์ผํ CI/CD๋ฅผ ๊ตฌ์ฑํ์ ๋๋ SSH Agent Plugin์ด ์๋ Publish Over SSH Plugin์ ์ฌ์ฉํ๋ค. ํ์ง๋ง Pipeline์ผ๋ก ๋ณ๊ฒฝํ๋ฉด์ Script์์ SSH๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ผ๋ก SSH Agent Plugin์ด ๋ ๋ง์ด ๊ฒ์๋๊ณ ๊ฐ๋จํด๋ณด์ฌ SSH Agent Plugin์ ์ฌ์ฉํ์๋ค. ํ์ง๋ง ๋ ๊ฐ์ ํ๋ฌ๊ทธ์ธ์ ์ฐจ์ด๋ฅผ ๋์ค์ ๋ณด๋ค ์์ธํ๊ฒ ์์๋ณด์์ผ๊ฒ ๋ค.
Freestyle project๋ก ๊ตฌ์ฑํ์ ๋ Publish Over SSH๋ฅผ ์ค์น ๋ฐ ์ค์ ํ๋ ๋ฐฉ๋ฒ์ ์๋์ ๊ฐ๋ค.
1. Publish Over SSH ํ๋ฌ๊ทธ์ธ ์ค์น
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ํ๋ฌ๊ทธ์ธ ๊ด๋ฆฌ > ์ค์น ๊ฐ๋ฅ > Publish Over SSH ํ๋ฌ๊ทธ์ธ์ ๊ฒ์ํ๊ณ ์ค์น ๋ฐ ์ฌ์คํ
2. Publish Over SSH ํ๋ฌ๊ทธ์ธ ์ค์
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ์์คํ ์ค์ ์์ Publish Over SSH ์์ญ์ ๊ณ ๊ธ ๋ฒํผ์ ๋๋ฌ ์ค์
- Path to key๋ private key์ ๊ฒฝ๋ก๋ฅผ ์
๋ ฅํ๋ค.
์ง๊ธ๊น์ง๋ Jenkins Server์์ jenkins ์ปจํ ์ด๋์ ์ ์ํ์ง ์๊ณ key๋ค์ ์ ๊ทผํ์ง๋ง jenkins๋ ์ปจํ ์ด๋๋ก ์คํ์ค์ด๋๊น Jenkins Server์ key ๊ฒฝ๋ก๋ฅผ ๋ชจ๋ฅธ๋ค. ์ฆ /home/ubuntu/.ssh/id_rsa๋ฅผ ์ ๋ ฅํ๋ฉด ์๋๋ค. ์ฐ๋ฆฌ๋ ๋คํ์ด Jenkins Server์์ ์ปจํ ์ด๋๋ฅผ ์คํํ ๋ /home/ubuntu/.ssh๋ฅผ /root/.ssh์ ์ฐ๊ฒฐํด ๋์๊ธฐ ๋๋ฌธ์ /root/.ssh/id_rsa๋ฅผ ์ ๋ ฅํ๋ฉด ๋๋ค. - Key๋ private key ๊ฐ์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
id_rsa ํ์ผ ๋ด์ฉ์ ๋ณต์ฌํด์ ๋ฃ์ด์ค๋ค. - Name์ ์ ์ํ ssh ์๋ฒ์ ์ด๋ฆ์ ์ ๋ ฅํ๋ค.(๋ง์๋๋ก ์ง์ด์ฃผ์ธ์)
- Hostname์ ์ ์ํ ์๋ฒ์ ์ฃผ์๋ฅผ ๋ฃ์ด์ฃผ์ธ์.
Spring Boot Server EC2 ์ธ์คํด์ค URL์ ๋ฃ์ด์ค๋ค. - Username์ ์ ์ํ ์ ์ ๋ช
์ ๋ฃ์ด์ค๋ค.
๊ธฐ๋ณธ ์ ์ ์ธ ubuntu๋ฅผ ์ ๋ ฅํ๋ค. - Test Configuration ๋ฒํผ์ ๋๋ฌ ์ ์์ ์ผ๋ก ์ฐ๊ฒฐ ๋๋์ง ํ์ธํ๋ค.
5๏ธโฃ Jenkins, Slack ์ฐ๋
1. Slack Notification Plugin ์ค์น
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ํ๋ฌ๊ทธ์ธ ๊ด๋ฆฌ > ์ค์น ๊ฐ๋ฅ > Slack Notification ํ๋ฌ๊ทธ์ธ์ ๊ฒ์ํ๊ณ ์ค์น ๋ฐ ์ฌ์คํ
2. Slack์ Jenkins ์ฑ ์ถ๊ฐ
Slack ์ฑ์์ ํ๋จ์ ์ฑ ์ถ๊ฐ > jenkins ๊ฒ์ > jenkins ์ ํ ํ ์ฐ๋์ ํ๋ฉด ์ฐ๋ ๊ฐ์ด๋ ์นํ์ด์ง์ ํ์ ๋๋ฉ์ธ๊ณผ ํ ํฐ์ด ์ถ๋ ฅ๋๋ค. ์ด๋ฅผ ์ด์ฉํ์ฌ Slack Credentials์ ๋ฑ๋กํ๋ค.
3. Slack Credentials ๋ฑ๋ก
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > Manage Credentials > Credentials์ ์ ์ํ๋ค.
Store Jenkins์ Domain์ด (global)์ธ ํ์ดํ๋ฅผ ๋๋ฌ Global credentials (unrestricted)๋ก ์ด๋ํ๋ค.
์ผ์ชฝ ๋ฉ๋ด์ Add credentials๋ฅผ ๋๋ฌ credentials๋ฅผ ์ถ๊ฐํ๋ค.
- Kind
Secret text - Scope
Global - Secret
Slack์์ jenkins ์ฑ ์ฐ๋ ์ ์ถ๋ ฅ๋ ํ ํฐ - ID
slack -> ๋ง์๋๋ก ์ง์ด๋ ๋๋ค. ๋ค๋ง Pipeline Script ์์ฑ ์ credentialsId๋ก ์ฌ์ฉ๋๋ ์๋ณํ ์ ์๋๋ก ํ์. - OK๋ฅผ ๋๋ฌ ํค๋ฅผ ์์ฑ
4. Slack ์ค์
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ์์คํ ์ค์ ์์ Slack ์์ญ์ ์ค์
- Workspace
Slack์์ jenkins ์ฑ ์ฐ๋ ์ ์ถ๋ ฅ๋ ํ์ ๋๋ฉ์ธ - Credential
์์์ ๋ฑ๋กํ Slack Credential - Default channel / member id
Jenkins ์๋ฆผ์ด ์ ์ก๋๊ธธ ์ํ๋ ์ฑ๋๋ช
๐ฆธโ๏ธ Jenkins Pipeline
์ด์ ๋๋์ด Pipeline์ ๊ตฌ์ฑํ ์ค๋น๊ฐ ๋๋ค! Jenkins ๋์๋ณด๋ > ์๋ก์ด Item์์ item name์ ์ ๋ ฅํ๊ณ Pipeline์ ์ ํ, OK ๋ฒํผ์ ๋๋ฅธ๋ค.
1๏ธโฃ Jenkins, Github Webhook ์ฐ๋
Github Repository์ push event๊ฐ ๋ฐ์ํ์ ๋ ์๋์ผ๋ก Build๊ฐ ์คํ๋๊ฒ ํ๊ธฐ ์ํด Pipeline๊ณผ Github Webhook์ ์ฐ๋ํด์ผ ํ๋ค.
1. Github Integration Plugin ์ค์น
Jenkins ๋์๋ณด๋ > Jenkins ๊ด๋ฆฌ > ํ๋ฌ๊ทธ์ธ ๊ด๋ฆฌ > ์ค์น ๊ฐ๋ฅ > Github Integration ํ๋ฌ๊ทธ์ธ์ ๊ฒ์ํ๊ณ ์ค์น ๋ฐ ์ฌ์คํ
2. Jenkins Pipeline ์ค์
- Github project ์ค์
Pipeline ๊ตฌ์ฑ ํ๋ฉด > General ์์ญ์์ Github project๋ฅผ ์ ํํ๋ค. Project url์ ๋ณธ์ธ์ Github Repository Url์ ์ ๋ ฅํ๋ค. ์ด ๋ Repository Url์ Clone ์ ์ฌ์ฉํ๋ HTTPS Url(.git์ผ๋ก ๋๋จ)์ ์ ๋ ฅํ๋ค. - Build Triggers ์ค์
Pipeline ๊ตฌ์ฑ ํ๋ฉด > Build Triggers ์์ญ์์ GitHub hook trigger for GITScm polling์ ์ ํํ๋ค.
3. Github Webhook ์ถ๊ฐ
Github Repository์์ Settings > Webhooks > Add Webhook ์ ๋๋ฌ Webhook์ ์ถ๊ฐํ๋ค.
- Payload URL
[Jenkins Server URL]:[Jenkins Server ํฌํธ]/github-webhook/ - Content type
application/x-www-form-urlencoded - ๋๋จธ์ง๋ ๋ชจ๋ default ์ค์ ์ ์ง
-Add webhook ๋ฒํผ์ ๋๋ฌ Webhook์ ์ถ๊ฐ -> ๋ชฉ๋ก์์ ๋ น์ ์ฒดํฌ ์์ด์ฝ์ด ์์ฑ๋๋ฉด ์ฑ๊ณต
2๏ธโฃ Pipeline Script ์์ฑ
pipeline {
agent any
environment {
imagename = "docker build๋ก ๋ง๋ค ์ด๋ฏธ์ง ์ด๋ฆ"
registryCredential = 'Docker Hub Credential ID'
dockerImage = ''
}
stages {
stage('Prepare') {
steps {
echo 'Clonning Repository'
git url: 'Github Repository SSH Url(git@github.com๋ก ์์)',
branch: 'Clone ๋ฐ์์ฌ Branch ์ด๋ฆ',
credentialsId: 'Github Credential ID -> github'
}
post {
success {
echo 'Successfully Cloned Repository'
}
failure {
error 'This pipeline stops here...'
}
}
}
stage('Bulid Gradle') {
steps {
echo 'Bulid Gradle'
dir('.'){
sh './gradlew clean build'
}
}
post {
failure {
error 'This pipeline stops here...'
}
}
}
stage('Bulid Docker') {
steps {
echo 'Bulid Docker'
script {
dockerImage = docker.build imagename
}
}
post {
failure {
error 'This pipeline stops here...'
}
}
}
stage('Push Docker') {
steps {
echo 'Push Docker'
script {
docker.withRegistry( '', registryCredential) {
dockerImage.push()
}
}
}
post {
failure {
error 'This pipeline stops here...'
}
}
}
stage('Docker Run') {
steps {
echo 'Pull Docker Image & Docker Image Run'
sshagent (credentials: ['SSH Credential ID -> ssh']) {
sh "ssh -o StrictHostKeyChecking=no [Spring Boot Server username]@[Spring Boot Server IP ์ฃผ์] 'docker pull [๋์ปค์ด๋ฏธ์ง ์ด๋ฆ]'"
sh "ssh -o StrictHostKeyChecking=no [Spring Boot Server username]@[Spring Boot Server IP ์ฃผ์] 'docker ps -q --filter name=[์ปจํ
์ด๋ ์ด๋ฆ] | grep -q . && docker rm -f \$(docker ps -aq --filter name=[์ปจํ
์ด๋ ์ด๋ฆ])'"
sh "ssh -o StrictHostKeyChecking=no [Spring Boot Server username]@[Spring Boot Server IP ์ฃผ์] 'docker run -d --name [์ปจํ
์ด๋ ์ด๋ฆ] -p 8080:8080 [๋์ปค์ด๋ฏธ์ง ์ด๋ฆ]'"
}
}
}
}
post {
success {
slackSend (channel: '#์ฑ๋๋ช
', color: '#00FF00', message: "SUCCESSFUL: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
failure {
slackSend (channel: '#์ฑ๋๋ช
', color: '#FF0000', message: "FAILED: Job '${env.JOB_NAME} [${env.BUILD_NUMBER}]' (${env.BUILD_URL})")
}
}
}
โ ํน์ branch push event์๋ง ๋์ํ๋๋ก ์ค์ ..
์์ ๊ฐ์ Github Webhook ์ค์ ์ผ๋ก๋ ๋ชจ๋ branch์ push event์ Pipeline์ด ๋์ํ๊ฒ ๋๋ค.
ํน์ branch push event์๋ง ๋์ํ๋๋ก ํ๊ธฐ ์ํด์๋ ์ถ๊ฐ ํ๋ฌ๊ทธ์ธ๊ณผ ์ค์ ์ด ํ์ํ ๊ฒ ๊ฐ์๋ฐ ๋ ๊ณต๋ถ๊ฐ ํ์ํ๋ค.
โ application.yml๊ณผ ๊ฐ์ ๋น๋ฐ์ ๋ณด๊ฐ ๋ค์ด์๋ ํ์ผ์ ์ด๋ป๊ฒ ๋ฃ์ด์ฃผ์ง..
์ฌ๋ฌ ๋น๋ฐ์ ๋ณด๊ฐ ๋ค์ด์๋ application.yml์ Github์ ์ฌ๋ผ๊ฐ์ง ์๋๋ก ํด๋์๋๋ฐ ํด๋น application.yml์ด resources ํด๋์ ์์ง์์ Gradle Build ์ค๋ฅ๊ฐ ๊ณ์ ๋ฐ์ํ๋ค.
๋ฐ๋ก application.yml์ ์๋ฒ์ ๋ฃ์ด์ฃผ๊ณ ์ด๋ฅผ copyํ์ฌ ๋ฃจํธ ๋๋ ํ ๋ฆฌ์ ์์น์ํค๊ฒ ํ๊ณ java -jar ์คํ์ -Dspring.config.location=/application.yml๊ณผ ๊ฐ์ด ๋์ํ๋๋ก Dockerfile์ ๊ตฌ์ฑํด๋ณด๊ธฐ๋ ํ์ผ๋ test ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ค.
๋ฐ๋ผ์ ํ์ฌ๋ ๊ทธ๋ฅ workspace ๋ด๋ถ resources ํด๋์ ์ง์ ๋ฃ์ด๋์๋ค. ํ์ง๋ง ๋ ์ข์ ๋ฐฉ๋ฒ์ ์ฐพ์๋ด์ผ๊ฒ ๋ค.
๐ฌ ํ๊ณ
์ด๋ฒ์ด Jenkins๋ก CI/CD๋ฅผ ๊ตฌ์ถํ๋ ๊ฒ ์ธ ๋ฒ์งธ์ธ๋ฐ ์ด์ ์ผ ์ข ์๊ฒ ๋ค.. Jenkins๋ ์ ์ ์ ๋๋ ์ค.. ๋ ๊ณต๋ถํด์ผ์ง~
๐ ์ฐธ๊ณ
- EC2 ํ๋ฆฌํฐ์ด์์ Jenkins๊ฐ ๋์๊ฐ์ง ์๋ ๋ฌธ์ ํด๊ฒฐํ๊ธฐ
- ์ค์ ํ์ผ์ ์ฌ์ฉํ์ฌ Amazon EC2 ์ธ์คํด์ค์์ ์ค์ ๊ณต๊ฐ์ผ๋ก ์ฌ์ฉํ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ ๋นํ๋ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น?
- Docker๋ฅผ ํตํ ์ ํจ์ค(Jenkins) ์ค์นํ๊ธฐ.
- [AWS] Jenkins๋ฅผ ํ์ฉํ Docker x SpringBoot CI/CD ๊ตฌ์ถ
- [Jenkins] Docker Jenkins๋ก Spring Boot ๋น๋ ๋ฐ ๋ฐฐํฌ - 2 (ํ์ดํ๋ผ์ธ ์์ฑ ๋ฐ ๋น๋ ํ ์คํธ)
- [ํ ํฌON์ธ๋ฏธ๋] Jenkins๋ฅผ ํ์ฉํ CI/CD 1๊ฐ - ์ ํจ์ค(Jenkins) ์ดํด | T์์นด๋ฐ๋ฏธ
๋๊ธ