DevOps/CI CD

AWS ECR + Jenkins CI CD 구축하기

Jeffrey Oh 2023. 7. 14. 22:14
반응형

DDD 9기 동아리 활동을 하면서 새로운 것에 시도해보고자 AWS ECR 과 연동한 방법을 기록한다.

Server 작업 1

지금까지는 네이버 클라우드 플랫폼을 사용하면서 아주 쉽게 도커 이미지를 빌드하고 푸시했다.

AWS ECR (Amazon Elastic Container Registry) 는 설정이 조금 달라서 구글링을 많이 했다.

앞으로 말할 서버라는 것은 Jenkins 서버와 배포하려는 타겟 서버를 말한다.

서버에 접속하여 다음을 설치한다.

sudo apt -y install awscli
sudo apt -y install amazon-ecr-credential-helper

설치가 완료되면 awscli 명령어를 통해 configure 를 설정한다.

aws configure
  1. AWS Access Key ID 입력
  2. AWS Secret Access Key 입력
  3. Region 입력 -> 보통 우린 서울이니까 ap-northeast-2 입력
  4. 얜 뭔지 몰라서 입력안하고 Enter

~/.aws 폴더에 configcredentials 가 생성되어 있을 것이며 각각 입력했던 값들이 저장되어 있을 것이다.

AWS 작업

1. 사용자 생성

AWS 로 가서 IAM 에서 먼저 사용자를 만든다.
이 때 여기서 권한으로 AmazonElasticContainerRegistryPublicFullAccess 를 줘도 된다. (이 글은 정책 지정으로 할 것이다)

2. 정책 생성

정책 생성으로 가서 서비스 선택에서 Elastic Container Registry 를 선택한다.

그 다음 모든 Elastic Container Registry 작업(ecr:*) 여기를 체크한다.

그 다음 리소스 영역에서 ARN 추가 버튼을 클릭한다.

이 계정 으로 체크하고 리전은 ap-northeast-2 서울만 써준다.
그리고 모든 repository name 에 체크해서 전체 리포지토리 접근 권한 부여하면
아래 ARN 부분은 자동으로 채워질 것이다. 이대로 ARN 추가 버튼을 눌러 완료한다.

다음으로 넘어가서 정책 이름을 간략히 적고 (ex. ecr-policy) 정책 생성하여 마무리한다.

3. 사용자 정책 부여

다시 사용자로 돌아가 아까 생성한 사용자를 클릭해서 들어 간 뒤 권한 탭에서 맨 우측에 권한 추가 > 권한 추가 를 클릭한다.

직접 정책 연결 에서 만들어둔 정책명을 검색하여 체크하고 다음을 누르고 권한 추가하여 완료한다.

4. 엑세스 키 만들기

보안 자격 증명 탭으로 이동하여 아래로 스크롤 조금 하면 엑세스 키 만들기 가 있다. 클릭한다.
여기서 Command Line Interface(CLI) 방식을 사용할 것이기 때문에 이것을 체크하고 아래에 확인도 체크한 후 다음을 눌러 생성한다.

여기서 페이지를 나가면 다시 만들어야한다. 엑세스 키는 언제든지 확인이 가능하지만 비밀 엑세스 키는 다시 볼 수 없으니
복사하여 다른 곳에 달리 보관하던지 해야한다. 잠시 어딘가 백업해두자.

5. ECR Repository 만들기

Elastic Container Registry 서비스로 와서 리포지토리를 생성한다.
이름칸은 이미지 이름 정도로 간략히 쓴다 (ex. OOO-api)

양식은 다음과 같다. <유저 계정 ID 12자리>.dkr.ecr.<Region>.amazonaws.com/<Repository 이름>
ECR 리포지토리 URL를 곧바로 써야하니 여기 있다는 걸 기억해두자. (외우란게 아니라 옆에 복사버튼 있으니까)

Server 작업 2

다시 서버로 돌아와 다음 명령어를 실행한다.

aws ecr get-login-password --region ap-northeast-2

그러면 엄청 긴 토큰 값이 나타날 것이다. 그거를 전체 복사한다. (끝에 ==까지)

그런 다음 다음처럼 명령어를 실행한다.

docker login -u AWS -p <엄청 긴 토큰> <ECR 리포지토리 URL>

URL 입력 전에 한칸 띄워쓰기 해야한다. 실행하고 나서 Login Success 가 뜬다면 성공이다.

(업데이트 2023-07-21)
AWS ECR 로그인은 만료시간이 존재 하므로 매번 서버에서 하기 번거로워 Jenkins Pipeline 에 ECR Login Stage 를 추가함

만약 실패한다면 aws configure 부터해서 권한의 문제이므로 IAM 사용자, 정책 등 다시 확인하고 엑세스, 비밀 키 잘못쓴건 아닌지 확인할 것

Jenkins 작업

1. 플러그인 설치

추가로 설치해야할 플러그인이 있다.
설치하고 재시작 한다.

  • Amazon ECR plugin
  • AWS Credentials Plugin (아마 CloudBees AWS Credentials Plugin 이걸로 나올거임)
  • Pipeline: AWS Steps
2. 변수 및 Credentials 설정

둘다 써보기 위해 먼저 ECR 리포지토리 URL 은 Global properties 에 추가한다.

그 다음 엑세스 키 값을 지정하기 위해 Jenkins 관리 > Credentials 메뉴로 간다.
새로 추가를 누르고 다음 처럼 작성한다.

ID 는 편한 값으로 써도 된다 (안쓰면 일련의 값이 부여되고 수정이 안되서 바꾸려면 지우고 새로 만들어야함)
Access Key ID 는 아까 백업해둔 엑세스 키를 입력한다.
Secret Access Key 는 아까 백업해둔 시크릿 키를 입력한다.

Jenkinsfile

파이프라인을 다음과 같이 작성한다.

pipeline {
  agent any

  tools {
    jdk("java-17-amazon-corretto")
  }

  environment {
    IMAGE_NAME = 'test-api'
    REGION = 'ap-northeast-2'
    AWS_CREDENTIALS = 'AWS_CREDENTIALS'
    AWS_IAM = 'AWS_IAM'
  }

  stages {

    stage('Build Container Image') {
      steps {
        script {
          image = docker.build("${AWS_REGISTRY_URL_SIKDOROK}/${IMAGE_NAME}", "./폴더명")
        }
      }
    }
    
    stage('ECR Login') {
      steps {
        script {
          withAWS(region: "${REGION}", credentials: "AWS_CREDENTIALS") {
            // AWS ECR 로그인 절차 수행
            sh 'aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${AWS_REGISTRY_URL_SIKDOROK}'
          }
        }
      }
    }

    stage('Push Container Image') {
      steps {
        script {
          // cleanup current user docker credentials
          sh 'rm  ~/.dockercfg || true'
          sh 'rm ~/.docker/config.json || true'

          docker.withRegistry("https://${AWS_REGISTRY_URL_SIKDOROK}", "ecr:${REGION}:${AWS_CREDENTIALS}") {
            image.push("${BUILD_NUMBER}")
            image.push("latest")
          }
        }
      }
    }

    stage('Remove Container Image') {
      steps {
        sh "docker image rm ${AWS_REGISTRY_URL_SIKDOROK}/${IMAGE_NAME}:latest"
        sh "docker image rm ${AWS_REGISTRY_URL_SIKDOROK}/${IMAGE_NAME}:${BUILD_NUMBER}"
        sh "docker system prune -a --volumes -f" // 사용 안하는 것 전부 삭제
      }
    }
    
    stage('Server Run') {
      steps {
        sshagent(credentials: [SSH_CONNECTION_CREDENTIAL]) {
            sh """
               ssh -o StrictHostKeyChecking=no ${SSH_CONNECTION} '
               aws ecr get-login-password --region ${REGION} | docker login --username AWS --password-stdin ${AWS_REGISTRY_URL_SIKDOROK}
               IMAGE_NAME=${IMAGE_NAME} IMAGE_STORAGE=${AWS_REGISTRY_URL_SIKDOROK} BUILD_NUMBER=${BUILD_NUMBER} ./deploy.sh
               '
            """
        }
      }
    }
  }

}

기존에 다른 글에는 slack notification, build-args 등 여러 설정이 있는데 여기서는 필요한 것만 작성했다.


에러대응

  1. no basic auth credentials
    • aws configure 설정하고 docker login 해야함
반응형