Jenkins을 이용하여 Docker Image를 ECR로 올리기 with Github, 퍼블릭 서브넷

2025. 2. 14. 21:58·IT/cloud

Docker in Docker (DinD) 방식으로 AWS ECR 활용하기

DockerAgent 준비물

Docker in Docker(DinD) 방식으로 에이전트를 실행하고 컨테이너를 동적으로 관리하기 위해 아래의 준비물이 필요합니다.

 

필수 준비물

  • AWS Access Key
  • AWS IAM 권한
    • AmazonEC2ContainerRegistryPowerUser 권한을 가진 IAM 사용자 생성
  • AWS ECR (Elastic Container Registry)

 

AWS ECR(Elastic Container Registry)에 repository 생성하기

ECR (EC2 Container Registry)은 Docker Container의 이미지를 저장하는 Repository 서비스

IAM 인증을 통해 이미지의 push / pull 권한을 제어할 수 있습니다.

ECR 생성

리포지토리 생성을 선택합니다.

지정된 IAM 사용자만 ECR 리포지토리에 접근할 수 있도록 프라이빗 리포지토리를 생성합니다

결과물

AWS IAM

IAM에서 권한을 준다.

  • ECR Permission - AmazonEC2ContainerRegistryPowerUser

이러면 Docker 이미지를 저장하기 위한 ECR Repository를 생성하였습니다.

젠키스 설치

# 도커 소켓 마운트 하기
docker run -itd --name jenkins -p 8080:8080 -v /var/run/docker.sock:/var/run/docker.sock -v /usr/bin/docker:/usr/bin/docker jenkins/jenkins:jdk17

명령어를 살펴보면 /var/run/docker.sock:/var/run/docker.sock 이라는 볼륨 마운트가 있습니다.

docker exec -it jenkins /bin/bash

위 명령어를 통해 젠킨스 내부에서 docker명령어가 잘 실행 되는지 한번 확인해보면 됩니다.

docker exec jenkins cat /var/jenkins_home/secrets/initialAdminPassword

이제 다시 호스트로 빠져나와서 위 명령어를 입력하면 젠킨스 초기 접속 비밀번호를 확인할 수 있습니다.

그리고 서버의 8005번 포트(혹은 설정한 다른 포트)로 접속해보면 젠킨스 gui로 접속할 수 있습니다.

여기에다가 위에서 알아낸 비밀번호를 입력 해주면 됩니다.

플러그인 설치 suggested를 선택합니다. 나중에 필요한 것들 추가로 설치해도 됩니다.

플러그인 설치 suggested를 선택합니다. 나중에 필요한 것들 추가로 설치해도 됩니다.

Jenkins 페이지 접근을 위한 계정 설정을 진행합니다.

뒤에 나오는 과정을 따라 플러그인을 설치하고, admin 계정을 생성하면 됩니다.

이후 플러그인 설치가 진행되며, 접속 URL은 http://{Jenkins 접속하는 EC2 퍼블릭 주소}:8080로 접속하면 Jenkins에 오신 것을 환영합니다. 가 보입니다.

진키스 파이파라인 구성

Jenkins 관리 - Plugins

에 접속해서 필요한 플러그인을 추가로 설치합니다. 설치했던 플러그인들은 다음과 같습니다.

  • DockeFile라인
  • AWS Crential
  • Docker
  • Amazon ECR

Jenkins 관리 → Credentials → Add credentials

필요한 credentails 정보는 다음과 같다.

  • GitHub Token 등록
  • .env 파일 등록
  • ECR_ID AWS Credentials

다음과 같이 등록해주면 됩니다.

ENV파일을 등록합니다.

Mac에서는 command + shift + . 사용하면 숨김 파일을 볼 수 있습니다.

젠키스 파이프라인 만들기

Dashboard → 새로운 Item

CI/CD를 적용할 깃 레포지토리 주소를 넣어줍니다.

Build Trigger를 Github hook trigger for GitScm Polling으로 체크합니다.

참고) MSA 방식을 사용하였고 한 레포로 같이 진행을 하기 때문에 브런치로 관리합니다.

파이프라인 코드

Jenkin에 접속하는 EC2는 아래와 같이 인바인드 규칙이 되어 있습니다.

22포트 SSH 내 IP

8080 포트 Jenkins 내 IP

ssh -i pem파일경로 ec2-user@퍼블릭IP

퍼블릭 IP:8080으로 접속하면 다음과 같은 화면을 볼 수 있는데 어드민 계정의 암호를 입력해야 하는데 화면에 보이는 파일에 암호가 적혀있다.

Jenkins Pipeline 구성

Pipeline파이프라인

Agnet any 어떤 Jenkins에 일을 시킬 것인가?

stage: 어떤 일들을 처리할 것인지 일련의 stage

Steps: 한 스테이지 안에서의 단계로 일련의 step을 보여줌

작성한 Jenkinsfile이다.

pipeline {
    agent any
    environment {
        ENV_FILE = credentials('DEV_BACK_MEMBER_ENV')
        ENV_FILE_PRODUCT = credentials('DEV_BACK_PRODUCT_ENV')
        AWS_CREDENTIALS = 'ECR_ID'
    }
    stages {
        stage('github-clone') {
            steps {
                git branch: 'main', credentialsId: 'github-token', url: 'https://github.com/*******.git'
            }
        }
        stage('Prepare .env File') {
            steps {
                script {
                    writeFile file: './member/.env', text: "${ENV_FILE}"
                    sh 'cat ./member/.env'
                }
            }
        }
        stage('Build API Project') {
            steps {
                script {
                    // 프로젝트 권한 변경
                    sh 'chmod +x ./member/gradlew'
                    // 프로젝트 빌드
                    dir('./member') {
                        sh './gradlew build -x test'
                    }
                }
            }
        }
        stage('Docker Build & Push') {
            steps {
                script {
                    def app = docker.build("********.dkr.ecr.ap-northeast-2.amazonaws.com/cwave01/back-member", "./member")

                        docker.withRegistry("https://********.dkr.ecr.ap-northeast-2.amazonaws.com", "ecr:ap-northeast-2:${AWS_CREDENTIALS}") {
                            app.push("dev-member")
                            app.push("latest")
                        }
                    // 기존의 이미지 삭제
                    sh 'docker rmi $(docker images -f "dangling=true" -q) || true'
                }
            }
        }
    }
}

빌드를 많이 하니 메모리 초과 에러가 떴다. none 태그가 생기는 것을 방지하기 위하여

sh 'docker rmi $(docker images -f "dangling=true" -q) || true'을 추가했습니다. docker rmi는 docker image rm의 alias로 동일한 커맨드입니다.

'IT > cloud' 카테고리의 다른 글

AWS Certificate Manager(ACM)을 활용한 CloudFront HTTPS 적용  (0) 2025.02.17
서브도메인을 사용하기 위해 Route 53, CloudFront, S3, ACM 설정하기  (0) 2025.02.17
Jenkins + GitHub 프라이빗 서브넷 환경, CI 구축의 어려움  (0) 2025.02.14
[Ansible] lac를 통한 클라우드 인프라 구축-2  (0) 2025.02.13
[Ansible] lac를 통한 클라우드 인프라 구축-1  (0) 2025.02.13
'IT/cloud' 카테고리의 다른 글
  • AWS Certificate Manager(ACM)을 활용한 CloudFront HTTPS 적용
  • 서브도메인을 사용하기 위해 Route 53, CloudFront, S3, ACM 설정하기
  • Jenkins + GitHub 프라이빗 서브넷 환경, CI 구축의 어려움
  • [Ansible] lac를 통한 클라우드 인프라 구축-2
lakedata
lakedata
lakedata 님의 블로그 입니다.
  • lakedata
    lakedata 님의 블로그
    lakedata
  • 전체
    오늘
    어제
    • 분류 전체보기 (94)
      • IT (33)
        • cloud (12)
        • spring (3)
        • architecture (15)
        • etc (3)
      • 자격증 (23)
        • 정처기 (16)
        • AWS DVA (6)
        • AWS DOP (1)
      • 코딩테스트 (33)
        • 알고리즘 (15)
        • 백준 (12)
        • 프로그래머스 (5)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • github
  • 공지사항

  • 인기 글

  • 태그

    알고리즘
    spring boot
    Spring
    AWS
    Java
    SQL
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
lakedata
Jenkins을 이용하여 Docker Image를 ECR로 올리기 with Github, 퍼블릭 서브넷
상단으로

티스토리툴바