본문 바로가기
카테고리 없음

Jenkins 파이프라인에서 도커이미지를 ECR에 푸시

by 홍띠 2023. 6. 4.

이번에는 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한 이미지를 이용할 예정이므로 해당 태그를 전달 받도록 구성했다.