이번에는 Docker로 빌드한 이미지를 Amazon ECR 레포지토리에 푸시하는 과정을 젠킨스를 이용해서 자동화 하려고 한다.
추가로 내 경우에는 다음 파이프라인을 트리거 하는 과정까지 필요해서 아래 세개의 과정이 실행되어야 한다.
1. Docker build -> 2. ECR에 이미지 Push -> 3. 다음 파이프라인 트리거
플러그인 설치
젠킨스 웹에서 아래 두개의 플러그인을 설치한다. (Jenkins 관리 -> Plugins -> Available Plugins)
- Amazon ECR
- Docker Pipeline
(Dokcer로 젠킨스 사용한다면) docker-compose.yaml 수정
Docker로 젠킨스를 사용하는데, 젠킨스 컨테이너 내부에서도 도커 명령어가 실행되어야 한다.
아래의 설정을 하지 않는다면, docker: not found 에러가 발생한다.
이렇게 도커가 이중으로 실행될때는 Docker in Docker(DinD)나 Docker out of Docker(DooD)의 구조가 있다.
DinD는 보안상의 문제로 권장되지 않아, 가능하면 DooD로 사용한다.
Docker in Docker(DinD): Docker 안에 Docker 데몬이 독립적으로 실행되는 것. Docker 데몬이 2개가 실행되는 구조.
Docker out of Docker(DooD): 호스트 docker socket을 볼륨을 통해 공유한다. 도커 내부에서 실행되는 컨테이너는 호스트 컨테이너와 같은 위치에서 실행되는 'sibling' 관계로 실행된다.
docker-compose.yml 수정
services:
jenkins:
image: jenkins/jenkins:lts
user: root
privileged: true
ports:
- "8090:8080"
volumes:
- ./jenkins_home:/var/jenkins_home
- /usr/bin/docker:/usr/bin/docker
- /var/run/docker.sock:/var/run/docker.sock
(만약에 Dockerfile에서 docker를 따로 설치할거라면 '/usr/bin/docker:/usr/bin/docker' volume은 빼도된다.)
credentials 등록
Jenkins 웹 -> Jenkins 관리 -> Credentials 에서 아래와 같이 Credential을 등록한다.
이때, Kind를 꼭 AWS Credentials로 해야한다. 만약에 해당 종류가 없다면 AWS ECR 플러그인이 설치되어있는지 확인 할 것.
파이프라인 작성
이제 Pipeline만 작성하면 된다.
아래는 도커를 빌드해서 ECR에 Push하는 기본 코드이다. scripted 문법으로 작성했다.
node {
stage('init') {
// cleanup current user docker credentials
sh 'rm -f ~/.dockercfg ~/.docker/config.json || true'
}
stage('Build Image') {
// docket.build("빌드이미지:tag","빌드 위치")
customImage = docker.build("testImage:0.1.${env.BUILD_ID}","/var/jenkins_home/docker-zip/test-app")
}
stage("Push Image") {
// configure registry
docker.withRegistry('https://xxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com', 'ecr:ap-northeast-2:aws-credential-id') {
//push the image
customImage.push()
}
}
}
위의 'aws-credential-id'에는 위에서 생성한 credential의 ID를 넣어주면 된다.
맨 처음에 설명한대로, 여기서는 뒤의 빌드를 트리거하는 것 까지 추가한다.
node {
stage('init') {
// cleanup current user docker credentials
sh 'rm -f ~/.dockercfg ~/.docker/config.json || true'
}
stage('Build Image') {
// docket.build("빌드이미지:tag","빌드 위치")
customImage = docker.build("testImage:0.1.${env.BUILD_ID}","/var/jenkins_home/docker-zip/test-app")
}
stage("Push Image") {
// configure registry
docker.withRegistry('https://xxxxxxx.dkr.ecr.ap-northeast-2.amazonaws.com', 'ecr:ap-northeast-2:aws-credential-id') {
//push the image
customImage.push()
}
}
stage('post build') {
echo "${currentBuild.currentResult}"
// 실행 결과 확인
if (currentBuild.currentResult == 'SUCCESS') {
// Job이 성공적으로 실행됐을 때의 처리 로직
// test-build-2 트리거링 및 파라미터 전달
build(job: 'test-build-2', parameters: [string(name: 'IMAGE_TAG', value: "0.1.${env.BUILD_ID}")], wait: false)
}
}
}
Push Image가 정상적으로 실행되었다면 'post build' stage에서 'test-build-2'를 실행한다.
뒤에서 실행 될 'test-build-2'에서는 현재 실행되는 Job에서 ECR에 Push한 이미지를 이용할 예정이므로 해당 태그를 전달 받도록 구성했다.