-
Notifications
You must be signed in to change notification settings - Fork 0
๐ ๏ธ CI๏ผCD
1. ๊ฐ๋ฐ์๊ฐ ๋ก์ปฌ ํ๊ฒฝ์์ ์ฝ๋๋ฅผ ์์ฑ ๋ฐ ํ
์คํธํ ํ , ๋ณ๊ฒฝ์ฌํญ์ github๋ก push
2. github๋ ๋ณ๊ฒฝ ์ฌํญ์ push ๋๋ฉด webhook์ด ์ด๋ฒคํธ๋ฅผ ๊ฐ์งํ๊ณ ํด๋น ์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํด์ HTTP ์์ฒญ
3. webhook์์ HTTP์์ฒญ์ ํ๊ฒ ๋๋ฉด JENKINS๋ฅผ ํตํด Gradle์ ์ฌ์ฉํ์ฌ ์์ค์ฝ๋๋ฅผ ๋น๋ํ๊ณ ์คํ์ด ๊ฐ๋ฅํ jar ํ์ผ๋ก ์์ฑ
4. ๋น๋๋ jar ํ์ผ์ dockerfile๋ฅผ ์ฌ์ฉํ์ฌ Docker image๋ก pakaging.
5. Docker๋ image๋ฅผ DockerHub๋ก push
6. ์ฟ ๋ฒ๋คํฐ์ค ํด๋ฌ์คํฐ๋ Docker image๋ฅผ ๊ฐ์ ธ์์ ๋ฐฐํฌํ๊ณ ๋ฐฑ์๋์ ํ๋ก ํธ์๋๋ ๊ฐ๊ฐ์ ํ๋๋ก ๋ฐฐํฌ๋จ
7. ubuntu ์๋ฒ์์ MariaDb๋ฅผ ๊ด๋ฆฌํ๊ณ backend์ ์ฐ๋ํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๊ณ ๊ด๋ฆฌํจ
8. ์ฌ์ฉ์๊ฐ ์์ฒญํ ๋ฒ์ญ ์์
์ DeepL API๋ก ์ ์ก๋์ด ์ฒ๋ฆฌ๋๋ฉฐ, ๋ฒ์ญ๋ ๊ฒฐ๊ณผ๊ฐ ๋ฐํ๋จ
ํ๊ฒฝ
โฝ macOS Sonoma 14.2
๋๊ตฌ | ๋ฒ์ |
---|---|
JDK | 17 |
Docker | 25.0.3 |
Kubernetes | 1.29.1 |
Jenkins | 2.453 |
[ Dockerfile ]
- Spring boot Dockerfile
FROM openjdk:17-alpine
COPY build/libs/*.jar app.jar
# ARG๋ก ํ๊ฒฝ ๋ณ์ ์ค์
ARG JASYPT_KEY
ENV JASYPT_KEY=$JASYPT_KEY
ENTRYPOINT ["java", "-jar", "app.jar", "--jasypt.encryptor.password=${JASYPT_KEY}"]
๐ jasypt๋ณตํธํ ํจ์ค์๋(JASYPT_KEY)๋ Jenkins Credentials๋ฅผ ํตํด ๊ด๋ฆฌํ๋ฉฐ, ์คํ ์ ํ๊ฒฝ ๋ณ์๋ก์ ์ ๋ ฅ๋์ด ์คํ๋จ.
- Vue Dockerfile
FROM node:lts-alpine
RUN apk add --no-cache curl
WORKDIR /app
COPY . ./
RUN npm install
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
- Jenkins Dockerfile
FROM jenkins/jenkins:jdk17
USER root
RUN apt-get update && \
apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg && \
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
# docker-compose ์ค์น
RUN curl -L "https://github.com/docker/compose/releases/download/1.28.5/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \
chmod +x /usr/local/bin/docker-compose && \
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
- Jenkins docker-compose.yml
version: '3.7'
services:
jenkins:
build:
context: .
dockerfile: Dockerfile
container_name: 'jenkins_docker'
# mac ์ค๋ฆฌ์ฝ ์นฉ์ ๊ฒฝ์ฐ ์ค์
platform: linux/arm64
restart: always
user: root
ports:
- '8080:8080'
- '50000:50000'
volumes:
- './jenkins_home:/var/jenkins_home'
- '/var/run/docker.sock:/var/run/docker.sock'
docker: not found
์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ
docker exec -it jenkins_docker /bin/bash : container ์ ์
curl -fsSL https://get.docker.com -o get-docker.sh : docker ์ค์น
sh get-docker.sh
โฝ Jenkins Credentials
-
์ ํจ์ค ๋์ปค ์ปจํ ์ด๋์ ์ ์ํด RSA Key ์์ฑ -> Github ์ ์์ ์ํด private key ๋ฑ๋ก
-
Dockerhub ์ ์์ ์ํ dockerhub ๊ณ์ ์ ๋ณด ๋ฑ๋ก
-
jasypt ๋ณตํธํ์ ํ์ํ password ๋ฑ๋ก
- Github
Repository Settings์ ์ ๊ทผํ์ฌ Deploy keys์ public key ๋ฑ๋ก
- ngrok์ผ๋ก port๋ฅผ ๊ฐ๋ฐฉํ์ฌ Webhook ์ฐ๊ฒฐ
ngrok http 8080
- Jenkins Tools์์ Java(OpenJDK 17) , Gradle(8.7) ์ค์
- ์๋ก์ด Item -> Pipeline ์์ฑ -> Build Triggers -> Github hook trigger for GITScm polling ์ฒดํฌ
- Jenkins Pipeline Script
pipeline {
agent any
tools {
gradle 'gradle'
jdk 'openJDK17'
}
environment {
DOCKERHUB_USERNAME = 'orlzll'
GITHUB_URL = 'https://github.com/OmokNoonE/OnionHotSayYo-backend.git'
}
stages {
stage('Preparation') {
steps {
script {
sh 'docker --version'
}
}
}
stage('Source Build') {
steps {
// ์์คํ์ผ ์ฒดํฌ์์
git branch: 'main', url: 'https://github.com/OmokNoonE/OnionHotSayYo-backend.git'
// ์์ค ๋น๋
// 755๊ถํ ํ์ (์๋์ฐ์์ Git์ผ๋ก ์์ค ์
๋ก๋์ ๊ถํ์ 644)
// JASYPT_KEY Credentials
sh "chmod +x ./gradlew"
withCredentials([string(credentialsId: 'JASYPT_KEY', variable: 'JASYPT_KEY')]) { //set SECRET with the credential content
sh "./gradlew clean build -P jasypt.encryptor.password=${JASYPT_KEY}"
}
}
}
stage('Container Build') {
steps {
// jar ํ์ผ ๋ณต์ฌ
sh "cp ./build/libs/*.jar ."
// ์ปจํ
์ด๋ ๋น๋ ๋ฐ ์
๋ก๋
withCredentials([string(credentialsId: 'JASYPT_KEY', variable: 'JASYPT_KEY')]) { //set SECRET with the credential content
sh "docker build --build-arg JASYPT_KEY=${JASYPT_KEY} -t ${DOCKERHUB_USERNAME}/onion-back2:latest . --platform linux/x86_64"
}
// docker hub๋ก push
withCredentials([usernamePassword(credentialsId: 'DOCKERHUB_PASSWORD', usernameVariable: 'DOCKERHUB_USER', passwordVariable: 'DOCKERHUB_PASS')]) {
sh "echo $DOCKERHUB_PASS | docker login --username $DOCKERHUB_USER --password-stdin"
sh "docker push ${DOCKERHUB_USERNAME}/onion-back2:latest"
}
}
}
}
}
๐จ ์ต์ด๋ก pipeline ๊ตฌ์ถ ํ์๋ ์ง๊ธ ๋น๋
์คํ
Note
์คํฌ๋ฆฝํธ๋ฅผ ํตํด ์คํํ๋ ค๋ฉด ์๋ ๋งค๋ํ์คํธ ํ์ผ๋ค์ ํ๋์ ํด๋์์ ๊ด๋ฆฌ
- boot001dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: boot001dep
spec:
selector:
matchLabels:
app: boot001kube
replicas: 1
template:
metadata:
labels:
app: boot001kube
spec:
containers:
- name: boot-container
image: orlzll/onion-back2:latest
imagePullPolicy: Always
ports:
- containerPort: 8888
- boot001ser.yml
apiVersion: v1
kind: Service
metadata:
name: boot001ser
spec:
type: NodePort
ports:
- port: 8888 #์๋น์คํฌํธ
targetPort: 8888
protocol: TCP
nodePort: 30001
selector:
app: boot001kube
- vue001dep.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue001dep
spec:
selector:
matchLabels:
app: vue001kube
template:
metadata:
labels:
app: vue001kube
spec:
containers:
- name: vue-container
image: orlzll/onion-front2:latest
imagePullPolicy: Always
ports:
- containerPort: 5173
- vue001ser.yml
apiVersion: v1
kind: Service
metadata:
name: vue001ser
spec:
type: NodePort
ports:
- port: 5173
targetPort: 5173
protocol: TCP
nodePort: 30000
selector:
app: vue001kube
# ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก ์ค์
KUBE_DIR=../../infra
VUE_DIR=../frontend/OnionHotSayYo_frontend # frontend ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก
PASSWORD='0000' # sudo password
# vue project build
cd $VUE_DIR
echo $PASSWORD | sudo -S docker build -t orlzll/onion-front2 .
echo $PASSWORD | sudo -S docker push orlzll/onion-front2
# manifest
cd $KUBE_DIR
kubectl apply -f vue001dep.yml && kubectl apply -f vue001ser.yml
kubectl apply -f boot001dep.yml && kubectl apply -f boot001ser.yml
Note
ํ์ฌ frontend project๋ Jenkins๋ฅผ ํตํ build ์๋ํ๊ฐ ๋์ด ์์ง ์์ผ๋ฏ๋ก ์ด ๊ณผ์ ์์ build ๋ฐ docker hub๋ก image push ํ๋๋ก ์ค์ ํจ
[ ์ด๋ฏธ์ง ๋ณ๊ฒฝ ์ ๋ํ๋ก์ด๋จผํธ ์ ๋ฐ์ดํธ ]
- ๋ฐฑ์๋
kubectl rollout restart deployments boot001dep
์ ํจ์ค๋ฅผ ํตํด dockerhub image๊ฐ ์๋์ผ๋ก ์ ๋ฐ์ดํธ ๋๋ฏ๋ก deployments restart
VUE_DIR=../frontend/OnionHotSayYo_frontend # frontend ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก
PASSWORD='0000' # sudo password
# vue project build
cd $VUE_DIR
echo $PASSWORD | sudo -S docker build -t orlzll/onion-front2 .
echo $PASSWORD | sudo -S docker push orlzll/onion-front2
# deployment restart
kubectl rollout restart deployments vue001dep
๋น๋ -> ๋์ปค ํ๋ธ์ ์ด๋ฏธ์ง ์ ๋ก๋ -> ์ฌ์์๋จ
Note
์ถํ ํด๋น ๊ณผ์ ์ ArgoCD๋ฅผ ํตํด ๋์ปค ํ๋ธ ์ด๋ฏธ์ง์ ๋ณ๊ฒฝ์ ๊ฐ์งํ๊ณ Kubernetes ํด๋ฌ์คํฐ ๋ด์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋์ผ๋ก ์ ๋ฐ์ดํธํ๋๋ก ๊ณ ๋ํ ์์
Redis Pods
Refresh Token ๊ด๋ฆฌ๋ฅผ ์ํด Redies๋ฅผ Kubernetes pods๋ก์ ๋ฐฐํฌํจ
redis-pod.yml
redis-svc.yml
redis-configmap.yml