컨테이너로 CI/CD 환경 구성 및 테스트_1

duckiee·2023년 1월 10일
0

이번 포스트 시리즈는 Ec2 인스턴스를 컨테이너로 구성해서 CI/CD 파이프라인을 구축할 것이다.
완성된 구성도는 아래와 같다.

테스트에 사용한 EC2 용도는 아래와 같다.

  1. Jenkins, Clair VM
  • Jenkins 컨테이너를 사용하여 CI/CD 파이프라인 구성
  • Clair 컨테이너를 사용하여 코드 취약점 분석
  1. Nexus, SonarQube VM
  • Nexus 컨테이너를 사용하여 외부 아티팩트 캐싱, 도커허브 이미지 캐싱, 커스텀 도커 이미지 보관
  • Nexus 컨테이너, S3 버킷을 연동하여 Blob 스토리지 사용
  • SonarQube 컨테이너를 사용하여 코드 품질 분석 및 결과 확인
  1. Deploy VM
  • Nexus 컨테이너와 연동된 blob 스토리지에 저장된 도커이미지 pull
  • 도커 기반 Spring App 실행

- Jenkins, Clair VM

CI/CD 파이프 라인을 진행할때 Clair, Jenkins 환경의 컨테이너가 필요하며
컨테이너 정보 및 이미지는 아래와 같다

젠킨스 파일로 정의한 CI/CD 파이프 라인은 아래와 같다.

1. Checkout and Pull Codes from Github Repository

  • 깃허브 코드를 Jenkins 컨테이너 홈 디렉터리로 가져오는 작업
# 깃허브 코드를 가져오는 작업
stage('Checkout and Pull Codes from Github Repository'){
            steps{
                checkout scm
            }
        }

2. Build Base Image by Docker

  • 관련 레포지토리 : nexus-custom-repository
  • 젠킨스 컨테이너 내부에서 넥서스 컨테이너로 도커 로그인
  • base-image 디렉터리에 위치한 Dockerfile(SpringApp 이미지) 빌드
  • mainDir : 젠킨스 컨테이너에 위치한 프로젝트 디렉터리
  • nexusID : 넥서스 서비스 ID
  • nexusPW : 넥서스 서비스 PW
  • nexusUrl : 넥서스 컨테이너 VM priv IP:5000( nexus-custom-repository)
  • nexusProxyUrl : 넥서스 컨테이너 VM priv IP:5001
  • repository : 넥서스 서비스에서 커스텀 도커 이미지를 보관할 레포지토리명
  • baseImageTag : 넥서스 레포지토리에 저장할 이미지 태그명

        stage('Build Base Image by Docker') {
            steps {
                sh """
                cd ${mainDir}/base-image
                echo '${nexusPW}' | docker login -u '${nexusID}' --password-stdin ${nexusUrl}
                echo '${nexusPW}' | docker login -u '${nexusID}' --password-stdin ${nexusProxyUrl}
                docker build -t ${nexusUrl}/${repository}:${baseImageTag} .
                docker push ${nexusUrl}/${repository}:${baseImageTag}
                """
            }
        }     

3. Scan Static Codes Quality by Jacoco and SonarQube

  • 젠킨스 컨테이너 내부에서 Jacoco, SonarQube 사용하여 코드 테스트
    관련 레포지토리 구성 : nexus-artifact-repository
        stage('Scan Static Codes Quality by Jacoco and SonarQube') {
            steps {
                sh """
                cd ${mainDir}
                ./gradlew jacocoTestCoverageVerification --info
                ./gradlew jacocoTestReport --info
                ./gradlew sonarqube --info
                """
            }
        }        

4. Clean and Build Codes by Gradle

  • gradlew 스크립트를 사용하여 코드 빌드
        stage('Clean and Build Codes by Gradle') {
            steps {
                sh """
                cd ${mainDir}
                ./gradlew clean build --info
                """
            }
        }

5. Build Docker Image by Jib & Push to Nexus Custom Repository

  • 관련 레포지토리 : nexus-custom-repository
  • 빌드된 코드는 jib 모듈에 의해 넥서스 레포지토리에 업로드된다
  • appImageTag : 레포지토리에 업로드할 이미지 태그명
        stage('Build Docker Image by Jib & Push to Nexus Custom Repository') {
            steps {
                sh """
                    cd ${mainDir}
                    ./gradlew jib -Djib.to.image=${nexusUrl}/${repository}:${appImageTag} -DsendCredentialsOverHttp=true -Djib.console='plain'
                """
            }
        }

6. Build Docker Image by Jib & Push to AWS ECR Repository

  • 빌드된 코드는 jib 모듈에 의해 ECR 레포지토리에 업로드된다
  • appImageTag : 레포지토리에 업로드할 이미지 태그명
        stage('Build Docker Image by Jib & Push to AWS ECR Repository') {
            steps {
                withAWS(region:"${region}", credentials:"aws-key") {
                    ecrLogin()
                    sh """
                        curl -O https://amazon-ecr-credential-helper-releases.s3.us-east-2.amazonaws.com/0.4.0/linux-amd64/${ecrLoginHelper}
                        chmod +x ${ecrLoginHelper}
                        mv ${ecrLoginHelper} /usr/local/bin/
                        cd ${mainDir}
                        ./gradlew jib -Djib.to.image=${ecrUrl}/${repository}:${appImageTag} -Djib.console='plain'
                    """
                }
            }
        }        

7. Scan Security CVE at Clair Scanner

  • 젠킨스 컨테이너 내부에서 clair-scanner 바이너리 설치 및 취약점 스캔 실행
  • clair-scanner 리포트를 clair.log 파일로 저장
        stage('Scan Security CVE at Clair Scanner') {
            steps {
                script {
                    try {
                        jenkins_ip = sh(script: "docker inspect -f '{{ .NetworkSettings.IPAddress }}' jenkins", returnStdout: true).trim()
                        clair_ip = sh(script: "docker inspect -f '{{ .NetworkSettings.IPAddress }}' clair", returnStdout: true).trim()
                        sh """
                            apt update
                            apt install -y wget
                            docker pull ${nexusUrl}/${repository}:${appImageTag}
                            wget https://github.com/arminc/clair-scanner/releases/download/v12/clair-scanner_linux_amd64
                            chmod +x clair-scanner_linux_amd64
                            mv clair-scanner_linux_amd64 /usr/local/bin/clair-scanner
                        """
                        sh "clair-scanner --ip ${jenkins_ip} --clair='http://${clair_ip}:6060' --log='clair.log' \
                                --report='report.txt' ${nexusUrl}/${repository}:${appImageTag}"
                    } catch (err) {
                        echo err.getMessage()
                    }
                }
                echo currentBuild.result
            }
        }

8. Deploy Nexus Repository to AWS EC2 VM

  • 젠킨스 컨테이너 Deploy VM으로 접속하며 넥서스 레포지토리에 로그인
  • docker run 명령어를 사용하여 넥서스 레포지토리에 저장된 도커 이미지 다운로드 및 컨테이너 실행
        stage('Deploy Nexus Repository to AWS EC2 VM'){
            steps{
                sshagent(credentials : ["deploy-key"]) {
                    sh "ssh -o StrictHostKeyChecking=no ubuntu@${deployHost} \
                      'echo \"${nexusPW}" | docker login -u ${nexusID} --password-stdin ${nexusUrl}; \
                      docker run -d -p 81:8080 -t ${nexusUrl}/${repository}:${appImageTag};'"
                }
            }
        }

9. Deploy AWS ECR Repository to AWS EC2 VM

  • 젠킨스 컨테이너 Deploy VM으로 접속하며 ECR 레포지토리에 로그인
  • docker run 명령어를 사용하여 ECR 레포지토리에 저장된 도커 이미지 다운로드 및 컨테이너 실행
stage('Deploy AWS ECR Repository to AWS EC2 VM'){
            steps{
                sshagent(credentials : ["deploy-key"]) {
                    sh "ssh -o StrictHostKeyChecking=no ubuntu@${deployHost} \
                     'aws ecr get-login-password --region ${region} | docker login --username AWS --password-stdin ${ecrUrl}/${repository}; \
                      docker run -d -p 82:8080 -t ${ecrUrl}/${repository}:${appImageTag};'"
                }
            }
profile
DevOps로 진화하기

0개의 댓글