반응형
CI/CD Jenkins 설치 및 설정
의의
: Docker에서 app git clone > gradlew build > jar 생성 > jar를 기반으로 image 생성 > repository에 image push 의 작업을 Jenkins 하나로 통합관리한다.
사전작업
- Jenkins 컨테이터 생성
$ docker run -d -p 8080:8080 -p 50000:50000 \
-v /study/jenkins:/var/jenkins_home \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /usr/bin/docker:/usr/bin/docker \
--name jenkins2 jenkins/jenkins:2.346.2-jdk8
- 8080 포트를 열고, 50000 포트는 추후 jenkins agent 용으로 사용
- host : jenkins container를 mount 하여 컨테이너 죽으면 날라가는 data 저장
- docker.sock 을 mount해야 jenkins pipeline에서 docker 명령어 사용가능
- ( docker는 plugin으로만 되지않고, docker 명령어 사용을 위한 mount가 필요)
- 이름생성 및 jenkins , jdk 버전
- GitLab에 project-gitops > manifest 에 deploy.yaml이 있어야함 (예시)
apiVersion: apps/v1
kind: Deployment
metadata:
name: msa1
spec:
replicas: 1
selector:
matchLabels:
app: msa1
template:
metadata:
labels:
app: msa1
spec:
containers:
- name: msa1
// 내가 Push해서 올려놓은 image의 주소
image: yj0326/msa:msa1v_67
ports:
- containerPort: 8080
방법
- Jenkins pipeline script를 작성하여 수동 구동
- pipeline script를 적은 jenkinfile을 gitlab에 넣어놓고 그 gitlab 주소를 읽어온다
- GitLab에 webhook으로 연결하여 git push 시 webhook trigger를 발생하고 jenkins에서는 테스트 빌드 배포까지 자동화 (push 후 바로 자동 배포는 좀 위험한 방법임)
※ 여기에서는 1번으로 작업한다.
Jenkins에서 GitLab 연동할 Credential 생성
- jenkins 관리 > manage Credentials > Jenkins > Global credentials > Add Credentials
- Username with password > Username 생성 > password와 ID는 gitlab 계정
Jenkins에서 Image Repository 연동할 Credential 생성
- jenkins 관리 > manage Credentials > Jenkins > Global credentials > Add Credentials
- Username with pwd > pwd 와 ID 는 DockerHub 계정 or Harbor 계정
Jenkins에서 Create a job
- 이름 정의 > Pipeline 클릭 후 OK
- Pipeline > Definition = Pipeline script
Jenkins pipeline 예시 (Gradle, 설명 있음)
node {
// Jenkins Build Version for ArgoCD sync
def IMAGE_TAG = env.BUILD_ID
// Check out
stage('Git Checkout') {
echo '>>>>>STAGE: CHECKOUT'
sh "rm -rf ./* ./.git*"
git branch: 'main', credentialsId: 'yj0326', url: '<https://gitlab.com/msa3040311/hello1.git>'
}
// Build
stage('GRADLE BUILD') {
echo '>>>>>빌드'
sh "chmod +x ./gradlew"
sh "./gradlew build"
}
// plain.jar delete & .jar rename
stage('Archive Setting'){
echo 'STAGE: ARCHIVE SETTING - GRADLE'
// build file counting
def fileCount = sh(script:"find ./build/libs -type f | wc -l", returnStdout: true);
echo ">>>>> fileCount = ${fileCount}"
if(fileCount.toInteger() > 1){
// get plain jar
def plainFile = sh(script:"""find ./build/libs -regextype egrep -regex '.*plain.(war|jar)\\$'""", returnStdout: true).trim();
echo ">>>>> PLAIN FILE DELETE = ${plainFile}"
// plain jar delete
sh """find ./build/libs -regextype egrep -regex '.*plain.(war|jar)\\$' -exec rm {} \\\\;"""
}
def archiveFile = sh(script:"find ./build/libs -type f", returnStdout: true).trim();
echo ">>>>> ARCHIVE FILE = ${archiveFile}"
sh "cp ${archiveFile} ./hello1.jar"
}
// Image Build ((Dockerfile & jar))
stage('Image Build') {
echo 'STAGE: IMAGE BUILD'
image = docker.build("yj0326/msa", "-f ./Dockerfile ./")
}
// Image Push to DockerHub
stage('Image Push') {
echo 'STAGE: IMAGE PUSH'
// DockerHub URL = cat ~/.docker/config.json
docker.withRegistry("<https://index.docker.io/v1/>", "dockerhub"){
image.push("msa1v_${IMAGE_TAG}")
}
}
// deploy
// deploy.yaml git clone 후 Deploy.yaml 업데이트, 실행
stage('GitOps YAML Push') {
echo 'STAGE: Deploy'
// try 5
tryCnt=0
retry(5){
tryCnt
if(tryCnt>1){
sleep 5 //5sec
}
echo ">>>>> GITOPS CHECKOUT"
sh "rm -rf ./* ./.git*"
git branch: "main", credentialsId: 'yj0326', url: '<https://gitlab.com/project-gitops1/manifests.git>'
echo ">>>>> UPDATE DEPLOY.YAML"
// sed 치환문법 : s/문자열A/문자열B/g
// 문자열A를 문자열B로 치환한다.
sh "sed -i 's/msa:.*/msa:${IMAGE_TAG}/g' ./msa1/deploy.yaml"
echo ">>>>> GITOPS COMMIT & PUSH"
withCredentials([gitUsernamePassword(credentialsId:'yj0326')]){
sh 'git config --local user.email "yj0326@strato.co.kr"'
sh 'git config --local user.name "yj0326"'
sh "git add -A"
sh "git commit -m 'Update App Image Tag to ${IMAGE_TAG}'"
sh "git push -u origin HEAD:main"
}
}
}
}
Jenkins pipeline 예시 (Maven)
node {
// Jenkins Build Version for ArgoCD sync
def IMAGE_TAG = env.BUILD_ID
// Check out
stage('Git Checkout') {
echo '>>>>>STAGE: CHECKOUT'
sh "rm -rf ./* .git*"
git branch: 'main', credentialsId: 'yj0326', url: '<https://gitlab.com/msa3040311/hello3-mvn.git>'
}
// Build
stage('MAVEN BUILD') {
echo '>>>>>빌드'
sh "chmod 777 ./mvnw"
sh "./mvnw clean install"
}
// jar.original delete & .jar rename
stage('Original Setting'){
echo 'STAGE: Original SETTING - MAVEN'
// jar file count
def fileCount = sh(script:"find ./target -type f -regextype egrep -regex '.*.(war|jar)' | wc -l", returnStdout: true);
echo ">>>>> fileCount = ${fileCount}"
// jar file copy
def originalFile = sh(script:"find ./target -type f -regextype egrep -regex '.*.(war|jar)'", returnStdout: true).trim();
echo ">>>>> ORIGINAL FILE = ${originalFile}"
sh "cp ${originalFile} ./hello3.jar"
}
// Image Build ((Dockerfile & jar))
stage('Image Build') {
echo 'STAGE: IMAGE BUILD'
image = docker.build("yj0326/msa", "-f ./Dockerfile ./")
}
// Image Push to DockerHub
stage('Image Push') {
echo 'STAGE: IMAGE PUSH'
// DockerHub URL = cat ~/.docker/config.json
docker.withRegistry("<https://index.docker.io/v1/>", "dockerhub"){
image.push("msa3_mvn_v_${IMAGE_TAG}")
}
}
// deploy
// deploy.yaml git clone 후 Deploy.yaml 업데이트, 실행
stage('GitOps YAML Push') {
echo 'STAGE: Deploy'
// try 5
tryCnt=0
retry(5){
tryCnt
if(tryCnt>1){
sleep 5 //5sec
}
echo ">>>>> GITOPS CHECKOUT"
sh "rm -rf ./* ./.git*"
git branch: "main", credentialsId: 'yj0326', url: '<https://gitlab.com/project-gitops1/manifests.git>'
echo ">>>>> UPDATE DEPLOY.YAML"
// sed 치환문법 : s/문자열A/문자열B/g
// 문자열A를 문자열B로 치환한다.
sh "sed -i 's/msa:.*/msa:${IMAGE_TAG}/g' ./msa3/deploy.yaml"
echo ">>>>> GITOPS COMMIT & PUSH"
withCredentials([gitUsernamePassword(credentialsId:'yj0326')]){
sh 'git config --local user.email "yj0326@strato.co.kr"'
sh 'git config --local user.name "yj0326"'
sh "git add -A"
sh "git commit -m 'Update App Image Tag to ${IMAGE_TAG}'"
sh "git push -u origin HEAD:main"
}
}
}
}
저장 후 Dashboard > Build Now 클릭
- Docker images 이미지 생성 확인
- 연결된 Repository에서 이미지 Push 확인
- GitLab에 deploy.yaml 생성확인
반응형
'개발인생 > DevOps Engneer' 카테고리의 다른 글
DevOps) CI (Jenkins Agent jnlp 방식 & Docker image build) (0) | 2023.03.30 |
---|---|
DevOps) CD with ArgoCD (지속적인 배포) (0) | 2023.03.15 |
DevOps) CI with Docker (Legacy 방식) (0) | 2023.03.15 |
DevOps ) CI/CD Workflow (0) | 2023.03.14 |
DevOps) GitLab + ArgoCD로 kubernetes project 배포 (0) | 2023.03.09 |