위 이미지와 같이 Jenkins 를 활용하여 CI/CD 이미지 배포를 셋팅하려고한다.
Jenkinsfile 은 4단계로 나눠진다.
Jenkinsfile
GithubJenkins연동
JenkinsSlack연동
pipeline {
agent any
parameters {
booleanParam(name : 'BUILD_DOCKER_IMAGE', defaultValue : true, description : 'BUILD_DOCKER_IMAGE')
booleanParam(name : 'RUN_TEST', defaultValue : true, description : 'RUN_TEST')
booleanParam(name : 'PUSH_DOCKER_IMAGE', defaultValue : true, description : 'PUSH_DOCKER_IMAGE')
booleanParam(name : 'DEPLOY_WORKLOAD', defaultValue : true, description : 'DEPLOY_WORKLOAD')
// CI
string(name : 'ACCOUNT_ID', defaultValue : 'hwang088', description : 'ACCOUNT_ID')
string(name : 'DOCKER_IMAGE_NAME', defaultValue : 'pipeline-test', description : 'DOCKER_IMAGE_NAME')
string(name : 'DOCKER_TAG', defaultValue : '1.0.0', description : 'DOCKER_TAG')
// CD
string(name : 'TARGET_SVR_USER', defaultValue : 'ec2-user', description : 'TARGET_SVR_USER')
string(name :'TARGET_SVR_DIR', defaultValue : '/home/ec2-user/', description : 'TARGET_SVR_PATH')
string(name : 'TARGET_SVR', defaultValue : '10.0.1.251', description : 'TARGET_SVR')
}
environment {
REGION = "ap-northeast-1"
ECR_REPOSITORY = "${params.ACCOUNT_ID}/${params.DOCKER_IMAGE_NAME}"
ECR_DOCKER_TAG = "${params.DOCKER_TAG}"
DOCKER_ACCOUNT_ID = "${params.ACCOUNT_ID}"
TARGET_SERVER = "${params.TARGET_SVR_USER}@${params.TARGET_SVR}"
TARGET_PATH = "${params.TARGET_SVR_DIR}"
}
stages {
stage('============ Build Docker Image ============') {
when {
expression {return params.BUILD_DOCKER_IMAGE}
}
steps {
dir("${env.WORKSPACE}") {
sh 'docker build -t ${ECR_REPOSITORY}:${ECR_DOCKER_TAG} .'
}
}
post {
always {
echo "Docker build success!!"
}
}
}
stage('============ Run test code ============') {
when { expression { return params.RUN_TEST }}
steps {
sh('docker run --rm ${ECR_REPOSITORY}:${ECR_DOCKER_TAG} /root/.local/bin/pytest -v ')
echo 'good'
}
}
stage('============ Push Docker Image ============') {
when { expression { return params.PUSH_DOCKER_IMAGE }}
steps {
sh '''
cat ~/my_password.txt | docker login --username ${DOCKER_ACCOUNT_ID} --password-stdin
docker push ${ECR_REPOSITORY}:${ECR_DOCKER_TAG}
'''
echo "Push Docker Image to Docker_hub"
}
}
stage('============ Deploy workload ============') {
when { expression { return params.DEPLOY_WORKLOAD}}
steps {
sshagent (credentials: ['aws_ec2_user_ssh']) {
sh """#!/bin/bash
scp -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
deploy/docker-compose.yml \
${TARGET_SERVER}:${TARGET_PATH};
ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no \
${TARGET_SERVER} \
'cat ~/my_password.txt | docker login --username ${DOCKER_ACCOUNT_ID} --password-stdin; \
export IMAGE=${ECR_REPOSITORY}; \
export TAG=${ECR_DOCKER_TAG}; \
docker-compose -f docker-compose.yml down;
docker-compose -f docker-compose.yml up -d';
"""
echo "complete"
}
}
}
}
post {
success {
slackSend(
channel: "#jenkins_test",
color: "good",
message: "[Successful] Job:${env.JOB_NAME}, Build num:#${env.BUILD_NUMBER} (<${env.RUN_DISPLAY_URL}|open job detail>)"
)
}
failure {
slackSend(
channel: "#jenkins_test",
color: "danger",
message: "[Failed] Job:${env.JOB_NAME}, Build num:#${env.BUILD_NUMBER} @channel (<${env.RUN_DISPLAY_URL}|open job detail>)"
)
}
}
}
jenkinsfile 작성하는데 있어 많은 시간을 소비했다 확인해보니 이상하게도 파라미터 ${params.NAME} 사용하니깐 변수를 못받았다
여러 블로그를 참조하니 파라미터를 사용하길래 당연히 될줄알고 사용했는데 이럴줄몰랐다. 그래서 우선 환경변수(ENV)로 등록하여 사용하니 정상작동을 했다.
기타
- ssh key 생성
- ssh-keygen -t rsa
- ssh-copy-id -i ~/.ssh/rd_rsa.pub 호스트네임@IP
- 호스트 .ssh 소유자 및 권한 확인 (소유자:호스트, 권한: 700)