해당 게시글은 내용 정리 목적으로 작성되었습니다. 틀린 내용이 있다면 언제든지 말씀해 주세요

이번 게시글에서는 AWS EC2에 젠킨스를 설치하는 방법에 대해서 소개해보겠다.

1. Amazon EC2 생성

1. Amazon Machine Image(AMI) : Amazon Linux 2023 AMI
(리눅스 버전에 따라서 젠킨스 설치가 달라지니 정확한 설치를 위해서 해당 AMI를 선택해야한다)

2. 인스턴스 유형 : t3.medium (선택)
3. 키페어 생성
4. 보안 그룹 생성 : 8080 포트와 22포트를 열어두어야함
5. 스토리지 8GB

2. EC2 SSH 접속

키페어 생성 위치로 이동한 다음 SSH를 통해서 EC2로 이동한다

cd {key-pair.pem 위치}
예시 : ssh -i "jenkins-key.pem" ec2-user@54.180.202.88

3. EC2 jenkins 설치

# 1. Jenkins 설치 전에 시스템 패키지를 최신 상태로 갱신
$ sudo yum update -y

# 2. Jenkins 패키지 저장소를 시스템의 YUM 레포지토리 목록에 추가
$ sudo wget -O /etc/yum.repos.d/jenkins.repo \
    https://pkg.jenkins.io/redhat-stable/jenkins.repo

# 3. Jenkins-CI의 GPG 키 가져오기
$ sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io-2023.key
# rpm --import 명령은 패키지를 설치할 때 해당 패키지가 신뢰할 수 있는 소스에서 온 것임을 확인하기 위해 사용되는 GPG 키를 가져온다

# 4. YUM 패키지 업그레이드
$ sudo yum upgrade

# 5. Java 설치 (Amazon Linux 2023)
$ sudo dnf install java-17-amazon-corretto -y

# 6. Jenkins 설치
$ sudo yum install jenkins -y

# 7. Jenkins 서비스 자동 시작 설정
$ sudo systemctl enable jenkins

# 8. Jenkins 서비스 시작
$ sudo systemctl start jenkins

9. Jenkins 상태 확인
$ sudo systemctl status jenkins

4. EC2에 Git 설치

# 패키지 목록 업데이트
$ sudo dnf update -y
# Git 설치
$ sudo dnf install git -y
# 설치 확인
$ git --version

5. EC2에 Docker 설치

# Docker 설치
$ sudo dnf install docker -y

# Docker 서비스 시작 및 자동 시작 설정
$ sudo systemctl start docker
$ sudo systemctl enable docker

# Docker 버전 확인
$ docker --version

# Jenkins 사용자를 docker 그룹에 추가
$ sudo usermod -aG docker jenkins

# Jenkins 재시작
$ sudo systemctl restart jenkins

6. 젠킨스 잠금 해제 및 Get Started Customize Jenkins

브라우저에 ec2 public ip, 포트 8080를 입력해서 젠킨스 서버에 접근한다
ex) http://xxx.xxxx.xxxx.xxxx:8080

아래 경로의 initialAdminPassword 파일에 접근해서 비밀번호를 확인한 후 입력한다

$ sudo cat /var/lib/jenkins/secrets/initialAdminPassword

  • Install suggeseted plugins를 선택한다
  • 유용한 젠킨스 플러그인을 설치해준다.
  • 어드민 계정 정보를 입력하고 젠킨스 접근 URL을 입력한다

7. 젠킨스 플러그인 설치

  • Jenkins 관리 > Plugins > Available plugins
    • Git Parameter (선택) : 배포 전 git branch 또는 Tag를 선택할 수 있다. 
    • AWS Credentials

8. Credentials 생성

  • github과 aws ecr credentials를 생성해야한다

1) github credentials 생성

Github Personal access tokens 생성

  • Github 사이트로 이동해서 토큰을 생성한다
  • Settings / Developer Settings / Personal access tokens (classic) / token 생성
  • github에서 repository 관련 권한을 허용한 상태로 만든다.

Github Credentials 등록

  • jenkins 관리 > Credentials > System > Glabal credentials > Add Credentials 으로 이동

  • Username with password Kind 선택
  • Scope는 Global로 선택
  • username에 github username을 입력한다
  • password에 github에서 생성한 토큰을 입력한다
  • ID는 파이프라인에서 참조할 수 있는 값이므로 의미 있는 이름으로 입력한다 (ex : github-credentials)

2) AWS ECR 배포 credentials 등록

  • AWS에서 IAM 정책, IAM 사용자를 미리 만들어야한다

IAM 정책 생성

https://docs.aws.amazon.com/ko_kr/AmazonECR/latest/userguide/image-push-iam.html
  • 위 링크에서 모든 리포지토리로 푸시하는 데 필요한 권한 JSON을 복사한다
  • 정책 생성으로 이동 후 JSON 값을 입력한다 

  • 아래 정책 JSON 참조 
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ecr:CompleteLayerUpload",
                "ecr:GetAuthorizationToken",
                "ecr:UploadLayerPart",
                "ecr:InitiateLayerUpload",
                "ecr:BatchCheckLayerAvailability",
                "ecr:PutImage"
            ],
            "Resource": "*"
        }
    ]
}

IAM 사용자 생성

  • 직접 정책 연결을 선택하고 미리 만들어둔 정책을 연결한다 

  • 사용자를 생성하고 사용자 상세에 들어간 다음 액세스키 만들기를 눌러서 키를 다운로드 받는다.

AWS ECR  Deploy Credentials 등록

  • jenkins 관리 > Credentials > System > Glabal credentials > Add Credentials 으로 이동

  • Kind를 AWS Credentials로 선택한다
  • Scope는 Glabal
  • ID는 파이프라인에서 참조하기 위해 명확하게 지어준다.
  • IAM 사용자의 액세스키인 Access Key ID와 Secret Access Key를 입력한다.

  • 위와 같이 두개의 Credentials가 생성되었는지 확인한다. 

9. AWS ECR 생성

  • Amazon ECR > 프라이빗 레지스트리 > 리포지토리 > 리포지토리 생성으로 이동한다
  • ECR Repository를 생성했으면 URI를 복사해둔다.
    • 파이프라인 작성 시 필요하다

10. 젠킨스 파이프라인 생성

  • 새로운 아이템 생성을 클릭하고 아이템 이름을 입력하고 파이프라인을 선택한 다음 OK를 누른다

  • 파이프 라인을 입력한다

파이프라인

pipeline {
    agent any
    options {
        timeout(time: 1, unit: 'HOURS')
    }

   environment {
        TIME_ZONE = 'Asia/Seoul'
        
        // GitHub
        GIT_TARGET_BRANCH = '배포할 브랜치 명'
        GIT_REPOSITORY_URL = 'Github repository URL'
        GIT_CREDENTIONALS_ID = 'Jenkins Github Credentials Id'


        // AWS ECR
        AWS_ECR_CREDENTIAL_ID = 'Jenkins AWS ECR Credentials Id'
        AWS_ECR_URI = 'ECR URI'
        AWS_ECR_IMAGE_NAME = 'ECR Image Name'
        AWS_REGION = 'ECR Region'
        
    }

    stages {
        stage('init') {
            steps {
                echo 'init stage'
                deleteDir()
            }
        }
        
        stage('Cloning Repository') {
            steps {
                echo 'Cloning Repository'
                git branch: "${GIT_TARGET_BRANCH}",
                    credentialsId: "${GIT_CREDENTIONALS_ID}",
                    url: "${GIT_REPOSITORY_URL}"
            }
        }
        
        stage('Build Gradle') {
            steps {
                echo 'Build Gradle'
                dir('.') {
                    sh '''
                        pwd
                        chmod +x ./gradlew
                        ./gradlew build --exclude-task test
                    '''
                }
            }
        }

        stage('Build Docker Image') {
            steps {
                script {
                    sh '''
                        docker build -t ${AWS_ECR_IMAGE_NAME} .
                        docker tag ${AWS_ECR_IMAGE_NAME} ${AWS_ECR_URI}/${AWS_ECR_IMAGE_NAME}:${BUILD_NUMBER}
                    '''
                }
            }
        }
        
        stage('Push to ECR') {
            steps {
              withCredentials([[$class: 'AmazonWebServicesCredentialsBinding', credentialsId: "${AWS_ECR_CREDENTIAL_ID}"]]) {
                    script {
                        sh '''
                        aws ecr get-login-password --region ${AWS_REGION} | docker login --username AWS --password-stdin ${AWS_ECR_URI}
                        docker push ${AWS_ECR_URI}/${AWS_ECR_IMAGE_NAME}:${BUILD_NUMBER}
                        
                        '''
                    }
                }
            }
        }
        
        stage('Clean Up Docker Images on Jenkins Server') {
            steps {
                echo 'Cleaning up unused Docker images on Jenkins server'
                sh "docker image prune -f --all"
            }
        }
    }

    post {
        success {
            echo 'Pipeline succeeded'
        }
        failure {
            echo 'Pipeline failed'
        }
    }
}
  • 파이프라인은 아래와 같이 진행된다.
  1. init 
    이전에 작업했던 내용들을 모두 초기화 한다
  2. Cloning Repository
    Github에서 Repository를 Clone 한다.
  3. Build Gradle
    소스 코드를 Gradle Build 한다
  4. Build Docker Image
    Docker Image Build 한다 (Dockerfile이 존재해야함)
  5. Push to ECR
    Docker Image를 AWS ECR로 Push한다
  6. Clean Up Docker Images on Jenkins Server
    Build한 Docker Image를 지운다.

여기서 중요한 것은 environment에 정의된 변수 값을 정확하게 입력해주어야 한다.

저장 후 지금 빌드를 누르게 되면 아래와 같이 성공한 것을 볼 수 있다.

  • 추천하는 방법은 파이프라인의 Stage를 하나씩 입력해서 한번씩 빌드해보면서 성공여부를 확인하는 것이다.

11. 젠킨스 시간 설정 (선택)

  • 젠킨스 시간은 기본적으로 UTC로 설정되어 있다. 한국 시간으로 설정하는 방법을 알아보자
# 현재 타임존 확인
$ timedatectl

# Asia/Seoul로 타임존을 변경한다
$ sudo timedatectl set-timezone Asia/Seoul

# 변경되었는지 확인
$ timedatectl

# 젠킨스 재시작
$ sudo systemctl restart jenkins
  • 젠킨스 관리 > System Information으로 이동하여 타임존이 Asia/Seoul으로 변경되었는지 확인한다 

12. 파이프라인 Gradle Build 시 전처리 작업 수행하기 (선택)

  • Build 하기 전 application.yml 이나 다른 설정 파일을 소스코드에 복사하는 경우가 있다.
    ....
        stage('Gradle Build before process') {
            steps {
                echo 'Gradle Build before process'
                script {
                    sh '''
                    mkdir -p ${WORKSPACE}/src/main/resources
                    sudo cp ${APPLICATION_YML} ${WORKSPACE}/src/main/resources/application.yml
                    '''
                }
            }
        }      
    ....
  • 위와 같이 Gradle Build 전 Stage를 추가한다.
  • ${APPLICATION_YML}는 파일이 위치한 전체 경로이고, ${WORKSPACE}는 소스코드 경로이다.
  • ${APPLICATION_YML}는 직접 environment에 추가해주어야한다   
  • 젠킨스가 sudo 명령어를 실행하기 위해서 권한을 추가한다
# sudo vi /etc/sudoers

적당한 곳에 아래 텍스트 추가
jenkins ALL=(ALL) NOPASSWD: ALL
읽기 전용 파일이므로 wq! 로 강제저장하고 종료

13. 원하는 Git Branch를 선택해서 배포하기 (선택)

  • Git Parameter 플러그인을 설치하고 파이프라인으로 이동한다

  • 빌드 매개변수를 활성화하고 Git Parameter를 선택한다.
  • Name에 브랜치 명에 접근할 수 있는 변수명을 입력한다 (중요)
  • Branch Filter는 정확히 브랜치 명만 가져올 수 있도록 필터링을 설정한다 origin/(.*)
  • 밑줄 친 속성 이외에도 원하는 값을 입력하면 된다.
  • 설정이 완료되었다면 파이프라인을 수정한다
   environment {
        ...
        GIT_TARGET_BRANCH = "${GIT_BRANCH_PARAMETER}"
        ...
    }
  • GIT_TARGET_BRANCH에 직접 브랜치 명을 입력했던 것을 GIT_Parameter name에 입력했던 값으로 변경한다. 
  • 브랜치 목록은 한번 배포한 다음에 적용되는 것으로 보인다. default 브랜치로 한번 배포한 다음 브랜치 목록이 잘 노출되는지 확인하자

  • 위와 같이 지금 빌드 버튼이 파라미터와 함께 빌드로 변경된 것을 볼 수 있다.
  • 브랜치를 선택한 다음 빌드하면 원하는 브랜치로 빌드가 되는 것을 볼 수 있다.
  • 마지막으로 AWS ECR에 Push 되었는지 확인해보자

  • 다음 글은 ECR Push 후 ECS에 배포하는 작업을 포스팅해 볼 예정입니다.
  • 도움이 되었다면 공감 한번씩 눌러주세요!

+ Recent posts