GDSC Solution Challenge์ ๋์ ํ๋ฉด์, ์ฒ์ GCP๋ฅผ ์ฌ์ฉํ๊ฒ ๋์๋ค!
๊ธฐ์กด ์คํ๋ง๋ถํธ ์ฑ์ ๊ฐ๋ฐํ ๋ ๋ณดํต AWS์ CodeDeploy (+ S3, EC2)๋ฅผ ํ์ฉํ์ฌ CI/CD๋ฅผ ๊ตฌ์ถํ์๋๋ฐ,
์ด๋ฒ์ GCP๋ ์ฌ์ฉํด๋ณผ๊ฒธ, ์๋ก์ด ํด์ธ Jenkins๋ฅผ ํตํ์ฌ CI/CD๋ฅผ ๊ตฌ์ถํ๋ ๋ฐฉ๋ฒ์ ๋ํด ์์๋ณธ ๋ด์ฉ์ ์ ๋ฆฌํด๋ณด์๋ค.
๊ณผ์ ์ ๋ฆฌ
[GCP] Compute Engine ์ค์
์ธํ ์ ๋ณด
์๋ฒ๋ ์คํ๋ง๋ถํธ์ฉ ์๋ฒ, ์ ํจ์ค์ฉ ์๋ฒ ์ด 2๊ฐ๋ฅผ ์ธํ ํด์ฃผ์๋ค.
- ubuntu
- http/https ํธ๋ํฝ ํ์ฉ (๋ฏธ๋ฆฌ 8080 - 9090 ํฌํธ๋ฅผ ์ด์ด์ค.)
- ์๋ฒ
- remine-springboot-server [์คํ๋ง๋ถํธ์ฉ ์๋ฒ]
- remine-jenkins-server [์ ํจ์ค์ฉ ์๋ฒ]
์ธ๋ถ ๊ณ ์ ์ฃผ์ ์์ฝ
VPC ๋คํธ์ํฌ > IP ์ฃผ์๋ก ๋ค์ด๊ฐ์ ๋ ์ธ์คํด์ค ๋ชจ๋ ์ธ๋ถ ๊ณ ์ IP ์ฃผ์๋ฅผ ์ฌ์ฉํ ์ ์๋๋ก ์ค์ ํด์ฃผ์๋ค.
- ์ ์ญ์ด ์๋ ์ง์ญ์ผ๋ก ์ค์ : asia-northeast3 (์์ธ) ๋ก ์ค์ ํจ.
[VM] ์ค์ ๋ฉ๋ชจ๋ฆฌ ์ค์
์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ค์ ํ๋ ์ด์ ?
Swap ๋ฉ๋ชจ๋ฆฌ๋ ๊ฐ์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๊ตฌํํ๋ ๋ฐฉ๋ฒ ์ค ํ๋๋ก, ๋ฌผ๋ฆฌ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ ๋ ์์คํ ์ ์ฌ์ฉ๋ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ถ๊ฐ์ ์ผ๋ก ์์์ ํ ๋นํ๊ธฐ ์ํด ์ฌ์ฉ๋๋ค.
(๋ฌผ๋ก GCP์ ๊ฒฝ์ฐ๋ ์๋์ง๋ง..) AWS EC2๋ฅผ ํ๋ฆฌํฐ์ด๋ก ์ค์ ํ๊ณ Gradle ๋น๋ ์์ ์ ์๋ํ๋ ๊ณผ์ ์์ ์๋ฒ์ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋ถ์กฑํ๋ ๊ฒฝํ์ด ์๋ค. ๊ทธ๋์ ์ด๋ฒ์๋ ๋ฏธ๋ฆฌ ์คํ๋ง๋ถํธ ์๋ฒ์ ์ ํจ์ค ์๋ฒ ๋ ๋ค ์ค์ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ค์ ํด์ฃผ์๋ค.
์ค์ ๋ฐฉ๋ฒ
$ 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
์๋ ๋ด์ฉ์ /etc/fstab์ ์ถ๊ฐํจ
/swapflie swap swap defaults 0 0
๊ทธ๋ฌ๋ฉด ๋ค์ ๋ช ๋ น์ด๋ฅผ ํตํด ๋ฉ๋ชจ๋ฆฌ ์ค์ ์ด ์๋ฃ๋์์์ ํ์ธํ ์ ์๋ค.
$ free -h
์ฐธ๊ณ ์๋ฃ
https://repost.aws/ko/knowledge-center/ec2-memory-swap-file
[DOCKER] ๋์ปค ์ค์นํ๊ธฐ
๋๊ฐ์ Compute Engine ์ค์์ Jenkins server์ ์ค์น๋ฅผ ํด์ฃผ๋๋ก ํ์.
→ ์ด ๋ค๋ก๋ ์ญ ๋ฐ๋ก ์ธ๊ธ์ด ์๋ ์ด์ ์ ํจ์ค ์๋ฒ์์ ๊ณ์ ์ธํ ํด์ฃผ๋ ๊ฒ์ด๋ค!
์๋ ๋ช ๋ น์ด๋ค์ ์ญ ์ณ์ ๋์ปค๋ฅผ ์ค์นํด์ฃผ์!
$ sudo apt update
$ sudo apt-get install ca-certificates curl gnupg
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
$ sudo chmod 006 /var/run/docker.sock
์๋ ๋ช ๋ น์ด๋ฅผ ํตํด ์ค์น๋ฅผ ํ์ธํ ์ ์๋ค.
$ docker -v
[JENKINS] ์ ํจ์ค ์ค์นํ๊ธฐ
๋์ปค์์ ์ ํจ์ค ๊ณต์ ์ด๋ฏธ์ง๋ฅผ pull ๋ฐ์์์ฃผ์.
$ docker pull jenkins/jenkins:jdk17
์๋ ๋ช ๋ น์ด๋ฅผ ํตํ์ฌ ๋ค์ด๋ก๋ ๋ ์ด๋ฏธ์ง๋ฅผ ํ์ธํด์ค ์ ์๋ค.
$ docker images
์ ํจ์ค ์ด๋ฏธ์ง๋ฅผ ์ปจํ ์ด๋๋ก ์คํํด๋ณด์.
$ docker run -p 80:8080 -v /var/run/docker.sock:/var/run/docker.sock --name jenkins jenkins/jenkins:jdk17
์ฐธ๊ณ ๋ก ์ฌ๊ธฐ์, Jenkins๋ฅผ 80๋ฒ ํฌํธ๋ก ๋์์ฃผ์๋๋ฐ,
GCP์ ๋คํธ์ํฌ ๋ณด์ > ๋ฐฉํ๋ฒฝ ์ ์ฑ
์ค์ ์ ํตํด ๋ฏธ๋ฆฌ VM์ ํฌํธ๋ฅผ ์ด์ด๋์์ผ ํ๋ค!
[JENKINS] ์ ํจ์ค ์ด๊ธฐ ์ค์
๋ค์๊ณผ ๊ฐ์ ์์น์์ ์ ํจ์ค์ ์ด๊ธฐ ๋น๋ฐ๋ฒํธ๋ฅผ ํ์ธํ ์ ์๋ค.
๋ง์ฝ ๋ก๊ทธ๊ฐ ๋จ์ง ์์๋ค๋ฉด jenkins shell๋ก ์ด๋ ํ ๋ก๊ทธ์ธ secret์ ํ์ธํ ์ ์๋ค.
$ docker exec -it {๋์ปค ์ปจํ
์ด๋ ์ด๋ฆ} /bin/bash
$ cat /var/jenkins_home/secrets/initialAdminPassword
- ๋ง์ฝ ์์์ ์ปจํ ์ด๋ ์คํ ๋ช ๋ น์ด๋ฅผ ๋๊ฐ์ด ์ ๋ ฅ, ์คํํ๋ค๋ฉด --name์ jenkins๋ก ์ค์ ํ์ผ๋ฏ๋ก ๋์ปค ์ปจํ ์ด๋ ์ด๋ฆ์ jenkins ์ด๋ค!
์ ํจ์ค VM์ ํผ๋ธ๋ฆญ IPV4:์ ํจ์ค ํฌํธ๋ก ์ ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ด ์ด๊ธฐ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ ์ ์๋ค.
Administrator password ์ ๋ ฅ ๋ถ๋ถ์ ์ด๊ธฐ ๋น๋ฐ๋ฒํธ๋ฅผ ์ ๋ ฅํ์.
Continue ๋ฒํผ์ ๋๋ฅด๋ฉด ๋ค์๊ณผ ๊ฐ์ ํ์ด์ง๋ก ๋์ด๊ฐ๊ฒ ๋๋๋ฐ, ์ฌ๊ธฐ์ Install suggested plugins๋ฅผ ์ ํํด์ฃผ๋ฉด ๋๋ค.
ํ๋ฌ๊ทธ์ธ์ ๋ชจ๋ ๋ค์ด ๋ฐ์๋ค๋ฉด, admin user๋ฅผ ์์ฑํ๋ ํ์ด์ง๊ฐ ๋์ค๋๋ฐ
์ฌ๊ธฐ์๋ ๊ผญ ๊ด๋ฆฌ์ ์ ์ ๋ฅผ ์์ฑํด์ฃผ๊ณ save and continue๋ฅผ ๋๋ฌ์ฃผ์.
[GITHUB] git ์ ๊ทผ์ ์ํ credential ์์ฑ
์ด์ ์ ํจ์ค์์ git์ ์ ๊ทผํ ์ ์๋๋ก ์์ ์ ํ๋กํ์ credential์ ์์ฑํด์ค ๊ฒ์ด๋ค.
GitHub์์ ํ๋กํ ์ฌ์ง์ ๋๋ฅด๋ฉด ๋์ค๋ ์ฌ์ด๋๋ฐ์ Settings > ์ผ์ชฝ ์ฌ์ด๋์ Developer settings ์ ๋ค์ด๊ฐ์
Personal access tokens > Tokens (classic)์ ๋ค์ด๊ฐ์,
Generate new token > Generate new token(classic)์ ํด๋ฆญํ์
ํ ํฐ์ ์ฌ์ฉ ์ฉ๋๋ฅผ Note์ ๊ฐ๋จํ ์ ์ด์ฃผ๊ณ ,
Scope๋ฅผ ์ค์ ํด์ฃผ๋ฉด ๋๋ค.
- repo, admin:repo_hook ์ ์ฒดํฌ๋ฅผ ํด์ฃผ์๋ค. (์๋ ์ฌ์ง ์ฐธ๊ณ )
๊ทธ ์ดํ Generate token์ ํด๋ฆญํ๋ฉด ghp_๋ก ์์ํ๋ ํ ํฐ์ ํ์ธํ ์ ์๋ค.
(์ด๋๋ง ํ์ธ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ ๋ฉ๋ชจ์ฅ์ ์ ๋ณต์ฌํด๋์!)
[JENKINS] Jenkins์ Git credential ์ค์
Dashboard > Jenkins ๊ด๋ฆฌ > System ์ ์ ์ํ์
GitHub ๋ถ๋ถ์ ์๋ +ADD ๋ฒํผ์ ๋๋ฅธ ๋ค, Jenkins ๋ฒํผ์ ํด๋ฆญํ์ฌ ์๋ก์ด Credential ๋ ๊ฐ๋ฅผ ์์ฑํด์ค ์์ ์ด๋ค.
(ADD ๋ฒํผ ์์น๋ ์๋ ์ฌ์ง ์ฐธ๊ณ )
์๋ก์ด Credential ์ค์
1. jenkins-github-secret-text
Secret์ ์๊น ๋ฐ๊ธ๋ฐ์ ghp_ ๋ก ์์ํ๋ ํค๋ฅผ ๋ถ์ฌ๋ฃ์
2. jenkins-github-username-password
Username์ github ์ด๋ฉ์ผ, Password์ ์๊น ๋ฐ๊ธ๋ฐ์ ghp_๋ก ์์ํ๋ ํค๋ฅผ ๋ถ์ฌ๋ฃ์
Connection Test
- Name์ repository url
- Credential์ ์์์ ์์ฑํ jenkins-github-secret-text ๋ฅผ ์ค์ ํ์
์ฐ์ธก ํ๋จ์ Test connection ๋ฒํผ์ ๋๋ฅด๊ณ Credentials verified for user 5jisoo, rate limit: 4999 ์ ๊ฐ์ ๋ฌธ๊ตฌ๊ฐ
์ข์ธก ํ๋จ์ ์์ฑ๋๋ฉด ์ฐ๊ฒฐ์ ์ฑ๊ณตํ ๊ฒ์ด๋ค! (๋์์ Credential ์ค์ ๋ ์ ๋๊ฒ!)
์ ์ฅ ๋ฒํผ์ ๋๋ฌ ์ ์ ์ฅํด์ฃผ์
[JENKINS] Jenkins์ Git Clone Pipeline ์์ฑ
์๋ก์ด ํ์ดํ๋ผ์ธ ์์ฑ
์ ํจ์ค ์ข์ธก + ์๋ก์ด Item์ ํด๋ฆญํ์ฌ Pipeline์ ์๋กญ๊ฒ ์์ฑํด๋ณด์
- ์ด๋ฆ์ ๋ง์๋๋ก ์ง์ด๋ ๋๊ณ ,
- Pipeline์ ์ ํํ ๋ค OK๋ฅผ ๋๋ฅธ๋ค
ํ๋จ์ pipeline syntax๋ฅผ ํด๋ฆญํด์ค๋ค.
Git Clone ์คํฌ๋ฆฝํธ ์์ฑํ๊ธฐ
Steps์ ๋ค์๊ณผ ๊ฐ์ด ๊ธฐ์ ํ๊ณ Generate Pipeline Script๋ฅผ ํด๋ฆญํ๋ฉด ์๋์ผ๋ก ํ์ดํ๋ผ์ธ ์คํฌ๋ฆฝํธ๋ฅผ ์์ฑํด์ค๋ค!
- Branch: trigger๊ฐ ๋๋ ๋ธ๋์น๋ ๋ง์๋๋ก ์์ฑํ๋ค (ex main, develop .. ๋ฑ๋ฑ)
- ์ด ๋ ๋ธ๋์น๋ ๊ผญ ์กด์ฌํ๋ ๋ธ๋์น๋ก ์ค์ ํ์!
- Credential์ ์๊น ๋ฑ๋กํ jenkins-github-username-password์ผ๋ก ์ค์ ํด์ค๋ค.
Script๋ฅผ ๋ณต์ฌํ์ฌ ๋ค์๊ณผ ๊ฐ์ด ํ์ดํ๋ผ์ธ์ ์์ฑํด์ฃผ์.
pipeline {
agent any
stages {
stage('Git Clone') {
steps {
git branch: 'develop',
credentialsId: 'jenkins-github-username-password',
url: 'https://github.com/re-Mine/reMine-Server'
}
}
}
}
์ ์ฅ์ ๋๋ฅธ ๋ค, ์ง๊ธ ๋น๋ ๋ฒํผ์ ํด๋ฆญํ์ฌ ํด๋ก ์ฌ๋ถ๋ฅผ ํ์ธํด๋ณด์
Clone ํ์ธํ๊ธฐ
์๋ ๋ช ๋ น์ด๋ค์ ์์ฑํด์ฃผ์.
- ๋์ปค ์ปจํ
์ด๋์ vim๋ ์๊น๋ ค์์ผ๋ฏ๋ก ์ค์นํด์ผ ํ๋ค.
→ vim์ ์ค์นํ ๋ ๊ถํ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด? ์ด ๊ธ ํ๋จ์ ์๋ ํธ๋ฌ๋ธ ์ํ ๋ถ๋ถ์ '๋์ปค ์ปจํ ์ด๋ ๊ถํ ์๋ฌ ๋ฐ์ํ ๊ฒฝ์ฐ' ๋ถ๋ถ์ ์ฐธ๊ณ ํ๋ฉด ๋๋ค.
$ apt-get update
$ apt-get upgrade
$ apt-get install vim
jenkins ์ด๋ฏธ์ง์ ์ ์ํ ๋ค,
/var/jenkins_home/workspace/spring-pipeline(ํ์ดํ๋ผ์ธ ์ด๋ฆ) ์ผ๋ก ์ด๋ํ๋ฉด ํด๋ก ๋ ๋ด์ฉ์ ํ์ธํ ์ ์๋ค.
$ docker exec -it jenkins /bin/bash
$ cd /var/jenkins_home/workspace/spring-pipeline
$ ls -al
[JENKINS] ๋ฏผ๊ฐ ์ ๋ณด ์ถ๊ฐ
๋ณดํต ๊ด๋ฆฌํ๋ application-000.properties ํ์ผ๋ค์ ๋ฏผ๊ฐ์ ๋ณด๋ผ์ .gitignore ๋ก github์ ๊ณต๊ฐ์ ์ผ๋ก ์ฌ๋ฆฌ์ง ์๋๋ฐ,
์ด๋ฐ ๋ฏผ๊ฐ ์ ๋ณด๊ฐ ํฌํจ๋ ํ์ผ์ ์ค์ ํ๋ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ(ํ๊ฒฝ ๋ณ์ ๋ฑ..)์ด ์์ง๋ง Jenkins ์์ฒด์์ ์ ๊ณตํ๋ Credential ๊ธฐ๋ฅ์ ์ฌ์ฉํด๋ณด์๋ค!
Jenkins ๊ด๋ฆฌ > Credentials > ์๋ ์ฌ์ง์ฒ๋ผ (global) ๋ถ๋ถ ํด๋ฆญํด์ Global credentials (unrestricted) ๋ค์ด๊ฐ๊ธฐ
Credential ์ถ๊ฐ
Add Credentials ํด๋ฆญํด์ ๋ค์๊ณผ ๊ฐ์ด ์ธํ ํด์ฃผ๊ธฐ
- Kind: Secret file
- Scope: Global (default)
- File ์ ํํ๊ธฐ
- ID: ๋ง์๋๋ก - ํ์ดํ๋ผ์ธ ์์ฑํ ๋ ์ฐ์ด๋ฏ๋ก ์๋ณ๊ฐ๋ฅํ ์์ด๋๋ก ์์ฑํฉ๋๋ค.
ํ์ดํ๋ผ์ธ ์์ฑ
ํ์ดํ๋ผ์ธ > Configuration(๊ตฌ์ฑ) ์ ๋ค์ด์ค๋ฉด ํ์ดํ๋ผ์ธ ์์ ์ด ๊ฐ๋ฅํฉ๋๋ค
- git clone ์ดํ ์คํ๋ ์ ์๋๋ก ์์ฑํด์ค์๋ค
- ๊ฒฝ๋ก๋, ํ์ผ๋ช ์ ๊ฐ ํ๋ก์ ํธ ์ธํ ์ ๋ง๊ฒ ์ค์ ํด์ค๋๋ค
stage('Copy application-SECRET.properties') {
steps {
withCredentials([file(credentialsId: 'application-secret', variable: 'dbConfigFile')]) {
script {
sh 'cp $dbConfigFile src/main/resources/application-SECRET.properties'
}
}
}
}
Credential ํ์ผ ์ถ๊ฐ ํ์ธ
์ง๊ธ ๋น๋ ๋ฒํผ์ ๋๋ฌ์ ๋น๋๋ฅผ ์คํํ๊ณ , docker ์ ์ ์ํ์ฌ ํ์ธํฉ๋๋ค
$ cd /var/jenkins_home/workspace/spring-pipeline(ํ์ดํ๋ผ์ธ ์ด๋ฆ)/src/main/resources
$ ls -al
[JENKINS] Build Pipeline ์์ฑ
gradle ๋น๋ ํ์ดํ๋ผ์ธ ์์ฑํ๊ธฐ
์ฐธ๊ณ ๋ก ์ฌ๊ธฐ์ ./gradlew clean build๋ผ๊ณ ์์ฑํ๋ฉด ๊ต์ฅํ ์ค๋ ๊ฑธ๋ฆฐ๋ค (11๋ถ ๊ฑธ๋ฆผ;;)
- ์ด์ ์บ์ ์ญ์ ๊ฐ ํ์ํ ๋๋ง clean์ ์์ฑํ๋๋ก ํ์
stage('build with gradle') {
steps {
sh 'chmod +x gradlew'
sh './gradlew build'
}
}
๋น๋ ํ์ธํ๊ธฐ
build๋ jar ํ์ผ์ build/libs ํ์ผ์ ์ ์ฅ๋๋ค!
ํด๋น ์์น๋ก ์ด๋ํด์ jar ํ์ผ์ด ๋ฌด์ฌํ ์์ฑ๋์๋์ง ํ์ธํด๋ณด์.
- ๋ง์ฝ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค๋ฉด, ํค ํ์ผ์ด ๋น ์ง ๊ฑด ์๋์ง ์ ํ์ธํด๋ณด์.
- ์๋ฌ๋ Build History์ #n ๋ถ๋ถ์ ํด๋ฆญํ ๋ค Console output ์ ๋ณด๋ฉด ์ค์๊ฐ ์ฝ์ ๋ก๊ทธ๋ฅผ ํ์ธํ ์ ์๋ค.
[GCP] Spring Boot Server์ SSH KEY ์ค์
์ด์ Jenkins Server์์ Spring Boot Server๋ก SSH ์ ์์ด ๊ฐ๋ฅํ๋๋ก Spring Boot Server์ ํค๋ฅผ ์ค์ ํด์ฃผ์.
์๋์ฐ๋ puttygen์ ์ด์ฉํ์ฌ ppk, pem ํค๋ฅผ ๋ง๋ค์ด์ค ์ ์๋๋ฐ ๋ง๋๋ ๋ฐฉ๋ฒ์ ๊ตฌ๊ธ๋งํ๋ฉด ๋ง๊ณ ๊ต์ฅํ ์ฌ์ฐ๋ ํจ์คํ๊ฒ ๋ค! ์ด ๋ ๋์ค๋ ssh-rsa๋ก ์์ํ๋ public key ๋ถ๋ถ์ ์ ๋ณต์ฌํด๋๋ฉด ๋๋ค.
SSH ๊ณต๊ฐ ํค ์ถ๊ฐ
spring boot server ์ธ์คํด์ค์ ๋ค์ด๊ฐ์ ์์ ๋ฒํผ์ ๋๋ฅด์
SSH ํค ๋ถ๋ถ์์ ํญ๋ชฉ ์ถ๊ฐ ๋ฒํผ์ ๋๋ฌ์ ์๊น ๋ณต์ฌํด๋ ssh-rsa๋ก ์์ํ๋ ๊ณต๊ฐํค๋ฅผ ์ถ๊ฐํด์ค ๋ค, ์ ์ฅํ๋ค.
๊ณต๊ฐํค ํ์ธํ๊ธฐ
Spring Boot ์๋ฒ์ SSH ์ ์์ ํด๋ณด์
- ์ฐธ๊ณ ๋ก, ์ฝ์์์ SSH ์ โผ ๋ฒํผ, ๋ธ๋ผ์ฐ์ ์ฐฝ์์ ์ด๊ธฐ ๋ฒํผ์ ๋๋ฅด๋ฉด ๋ฐ๋ก ๋ธ๋ผ์ฐ์ ์ ์ ์์ด ๊ฐ๋ฅํ๋ค
.ssh ํด๋๋ก ์ด๋ํ์ฌ authorized_keys ํ์ผ์ ํ์ธํ์ฌ ๋ฐฉ๊ธ ์ถ๊ฐํ SSH ๊ณต๊ฐํค๊ฐ ์๋์ง ํ์ธํ๋ค
$ cd .ssh
$ cat authorized_keys
๋ง์ฝ ์ด ๋ ๊ณต๊ฐํค๊ฐ ์๋ค๋ฉด vim ํธ์ง๊ธฐ๋ฅผ ํ์ฉํ์ฌ ์๋์ผ๋ก ๋ฃ์ด์ฃผ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค.
$ vim authorized_keys
[JENKINS] SSH Credential ์ค์ ๋ฐ ํ๋ฌ๊ทธ์ธ ์ค์น
SSH Credential ์ค์
์๊น์ ๋์ผํ๊ฒ Credential ์ ์ถ๊ฐํ์
Jenkins ๊ด๋ฆฌ > Credentials > ์๋ ์ฌ์ง์ฒ๋ผ (global) ๋ถ๋ถ ํด๋ฆญํด์ Global credentials (unrestricted)์ ๋ค์ด๊ฐ์.
Add Credentials ๋ฒํผ์ ํด๋ฆญํ๊ณ ๋ค์๊ณผ ๊ฐ์ด Spring Server์ Compute Engine์ ์ ๊ทผํ๋ pemํค๋ฅผ ๋ฑ๋กํด์ฃผ์
- ์ฐธ๊ณ ๋ก pemํค๋ ----BEGIN RSA PRIVATE KEY---— ๋ถํฐ
-----END RSA PRIVATE KEY----- ๊น์ง ์ ๋ถ ๋ถ์ฌ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค. - Scope๋ Global, ID๋ jenkins-ssh-key๋ก ์ค์ ํด์ฃผ์๋ค.
- Username์ Ubuntu ์๋ฒ์ ๊ธฐ๋ณธ ์ ์ ์ธ ubuntu๋ฅผ ๋ฃ์ด์ฃผ์๋ค.
(๋ฐ๋ก ์ค์ ์ ํ์ ๊ฒฝ์ฐ ๋ณ๊ฒฝํด์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.)
SSH Agent ํ๋ฌ๊ทธ์ธ ์ค์น
Jenkins ๊ด๋ฆฌ > Plugins > Available plugins๋ก ์ด๋ํ์ฌ
SSH Agent ๋ฅผ ์ค์นํ๊ณ jenkins ์ปจํ ์ด๋๋ฅผ ์ฌ์์ํด์ฃผ์
$ docker ps # ์คํ์ค์ธ ์ปจํ
์ด๋ ํ์ธ
$ docker ps -a # ์ค์ง๋ ์ปจํ
์ด๋๊น์ง ๋ชจ๋ ํ์ธ
$ docker restart jenkins
[VM] Spring Boot Server ์ค์
(์ด ๋ถ๋ถ์ ์ ํจ์ค ์๋ฒ๊ฐ ์๋, ์คํ๋ง๋ถํธ ์๋ฒ์ ์ธ์คํด์ค ์ค์ ์ด๋ค.)
JDK ์ค์น
์๋ ๋ช ๋ น์ด๋ฅผ ์์ฑํ์ฌ jdk๋ฅผ ์ค์นํด์ฃผ์.
์ฐธ๊ณ ๋ก ํ์์ ํ๋ก์ ํธ์์๋ java 17์ ์ฌ์ฉํ์ฌ 17 ๋ฒ์ ์ ์ค์นํด์ฃผ์๋๋ฐ, ์ด๊ฑด ํ๋ก์ ํธ์ ๋ง๊ฒ ์ค์นํด์ฃผ๋ฉด ๋๋ค.
$ sudo apt update
$ sudo apt install openjdk-17-jdk
$ java --version # ์๋ฐ ๋ฒ์ ํ์ธ
Deploy shell ํ์ผ ์์ฑ
์ดํ๋ฆฌ์ผ์ด์ ์ ์คํํ ์ ํ์ผ์ ์์ฑํด์ฃผ์.
$ mkdir remine # application ์ด๋ฆ์ ๋ง๊ฒ ์ค์
$ vi deploy.sh
์๋ shell ํ์ผ์์
APP_NAME, APP_LOG, ERROR_LOG, DEPLOY_LOG ๋ณ์ ๋ถ๋ถ์ ๊ฐ์์ ํ๋ก์ ํธ ์ค์ ์ ๋ง๊ฒ ๋ณ๊ฒฝํ๋ฉด ๋๋ค.
#!/bin/bash
APP_NAME=remine
APP_LOG=./remine/application.log
ERROR_LOG=./remine/error.log
DEPLOY_LOG=./remine/deploy.log
CURRENT_PID=$(pgrep -f $APP_NAME)
if [ -z $CURRENT_PID ]
then
echo "> ์ข
๋ฃํ ์ ํ๋ฆฌ์ผ์ด์
์ด ์์ต๋๋ค." >> $DEPLOY_LOG
else
echo "> kill -9 $CURRENT_PID" >> $DEPLOY_LOG
kill -15 $CURRENT_PID
sleep 5
fi
JAR_NAME=$(ls $APP_NAME | grep 'SNAPSHOT.jar' | tail -n 1)
chmod +x ./$APP_NAME/$JAR_NAME
nohup java -jar -Duser.timezone=Asia/Seoul ./$APP_NAME/$JAR_NAME --logging.level.org.hibernate.SQL=DEBUG > $APP_LOG 2>$ERROR_LOG &
[JENKINS] Deploy ํ์ดํ๋ผ์ธ ์์ฑ
Deploy ํ์ดํ๋ผ์ธ ์์ฑ
ํ์ดํ๋ผ์ธ > Cofiguration์ ๋ค์ด๊ฐ์ ํ์ดํ๋ผ์ธ์ ์๋กญ๊ฒ ์ถ๊ฐ๋ก ์์ฑํด์ค๋ค
- ๋ฌผ๋ก ssh user name์ด ubuntu ๊ฐ ์๋๋ผ๋ฉด ubuntu๊ฐ ์๋๋ผ ์๋กญ๊ฒ ์์ฑํด์ฃผ์ด์ผ ํ๋ค.
stage('deploy') {
steps {
sshagent(credentials: ['jenkins-ssh-key']) {
sh '''
ssh -o StrictHostKeyChecking=no ubuntu@{spring server ip} uptime
scp /var/jenkins_home/workspace/spring-pipeline/build/libs/*.jar ubuntu@{spring server ip}:/home/ubuntu/{application name}
ssh -t ubuntu@{spring server ip} chmod +x ./deploy.sh
ssh -t ubuntu@{spring server ip} ./deploy.sh
'''
}
}
}
key file copy ์๋ฌ๊ฐ ๋ฐ์ํ๋ค๋ฉด?
์ด ๋ key file copy์์ ์๋ฌ๊ฐ ๋ฐ์ํ๋๋ฐ, Permission Denied ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
- pipeline์์ sudo๋ฅผ ๋ถ์ฌ๋ ๋น๋ฐ๋ฒํธ ์
๋ ฅ์ด ํ์ํ๋ค๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋๋ฐ,
chmod ๋ช ๋ น์ด๋ฅผ ํ์ฉํด ์ ๊ทผ๊ถํ์ ์์ ํ๋ฉด ๋๋ค.
stage('Copy application-SECRET.properties') {
steps {
withCredentials([file(credentialsId: 'application-secret', variable: 'dbConfigFile')]) {
script {
sh 'cp $dbConfigFile src/main/resources/application-SECRET.properties'
sh 'chmod 644 src/main/resources/application-SECRET.properties'
}
}
}
}
๊ฒฐ๊ณผ
{์คํ๋ง๋ถํธ ์๋ฒ public ipv4}:8080 ํฌํธ๋ก ์ ์ํ๋ฉด ๋ค์๊ณผ ๊ฐ์ Whitelabel ํ์ด์ง๋ฅผ ํ์ธํ ์ ์๋ค.
์๋ ๋ช ๋ น์ด๋ฅผ ํตํด Spring Boot ์๋ฒ์์ java ํ์ผ์ด ๋ฐฐํฌ๋๊ณ ์๋์ง ํ์ธํด๋ณด์
$ ps -ef | grep java
[JENKINS | GITHUB] Github Webhook ์ค์ ํ๊ธฐ
Github ์น ํ ์ถ๊ฐํ๊ธฐ
Repository Settings > Webhooks > Add webhook ํด๋ฆญํ๊ธฐ
- Payload URL : Jenkins Server IP ์ฃผ์/github-webhook/
- Content type: application/json
Pipeline Trigger ์ค์
Configuration์ ๋ค์ด๊ฐ์ Build Triggers GitHub hook trigger for GITScm polling ์ฒดํฌํ๊ธฐ
ํธ๋ฌ๋ธ ์ํ
๋์ปค ์ปจํ ์ด๋ ๊ถํ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ
์ํฉ
- apt-get update ๋ฅผ ์คํ์, Permission denied ์๋ฌ๊ฐ ๋ฐ์ํจ
- sudo apt-get update๋ฅผ ์คํ ์, sudo command not found ์๋ฌ๊ฐ ๋ฐ์ํจ.
์ด ๋๋ sudo๋ ๊น์์ฃผ์ด์ผ ํ๋ ์ํฉ์ด๋ผ์ ์๋ ๋ช ๋ น์ด์ฒ๋ผ docker ๋ฅผ root๊ถํ์ผ๋ก ์ ์ํ์ฌ์ผ ํ๋ค.
$ docker exec -itu0 jenkins /bin/bash
๊ธฐ์กด์ docker exec -it jenkins /bin/bash ๋ก ์ ๊ทผํ์ผ๋, -itu0 ๋ก ์คํํ๋ฉด ๋ฃจํธ ๊ถํ์ผ๋ก ์ ๊ทผ์ด ๊ฐ๋ฅํ๋ค.
๋ง๋ฌด๋ฆฌ
๋ณด์ํ ์
์คํ๋ง docker-compose๋ฅผ ๋ฐ๋ก ์ฌ์ฉํ์ง ์์์ ๋ฐฐํฌ ๊ณผ์ ์์ ๋ฐ๋ก Docker๋ฅผ ์ฌ์ฉํ์ง ์์๋๋ฐ, (Jenkins ์ ์ธ)
๋ค์๋ฒ์ ๋์ปค๋ฅผ ๋์ ํด์ ์๋ก์ด ๋ฐฐํฌ ํ์ดํ๋ผ์ธ์ ์ ์ํด๋ณด๋ ๊ฒ๋ ์ข์ ๊ฒ ๊ฐ๋ค!
์ ์ํ๋ฉฐ ์ฐธ๊ณ ํ ์ฌ์ดํธ
- https://hellodavid.tistory.com/78
- https://velog.io/@rungoat/CICD-Jenkins-credentials%EB%A1%9C-application-secret.yml-%ED%8C%8C%EC%9D%BC-%EA%B4%80%EB%A6%AC
- https://kangwoojin.github.io/programing/gradle-build-performance/
- ํ์๋ ๋ฑํ ์๊ณ ์ถ์ง ์์๋ค๐ฅฒ [๋ณธ๋ฌธ์ผ๋ก]
๋๊ธ