[Jenkins] 젠킨스와 도커를 활용한 배포와 테스트 자동화

728x90
반응형

배포와 테스트 자동화

이번 실습 또한 지난 글에서 하던 것에 이어서 진행한다.

실습 레포지토리: https://github.com/bestlalala/jenkins-practice.git

1. 컨테이너 생성 자동화

Jenkinsfile에 Docker 컨테이너를 생성하고 실행하는 코드를 추가하여 CI/CD 파이프라인을 완성할 수 있다.
예를 들어, 컨테이너를 자동으로 생성하려면 Jenkinsfile에 다음과 같은 단계를 추가한다.

stage('Run Docker Container') {
    steps {
        sh 'docker run -d --name 컨테이너이름 -p 외부포트:내부포트 이미지이름'
    }
}
  • docker run 명령어는 Docker 이미지를 기반으로 컨테이너를 생성하고 실행한다.
  • -d 옵션은 컨테이너를 백그라운드에서 실행하도록 설정한다.
  • --name 옵션은 컨테이너의 이름을 지정한다.
  • -p 옵션은 외부와 내부 포트를 매핑하여 호스트에서 애플리케이션에 접근할 수 있도록 한다.

배포 단계에서 컨테이너 실행

Jenkinsfile의 deploy 단계에 아래와 같은 코드를 추가하면, 빌드된 이미지를 바로 실행할 수 있다.

stage('deploy'){
  steps{
      sh "docker run -d --rm -p 8765:8080 --name calculator bestlalala/calculator"
  }
}

이 코드는 Jenkins 파이프라인에서 Docker 이미지를 배포 후 자동으로 실행하게 한다.

⛔️ 컨테이너 이름 충돌 해결

같은 이름의 컨테이너가 이미 실행 중이면 오류가 발생할 수 있다. 이를 방지하기 위해 기존 컨테이너를 중지하고 삭제해야 한다. 아래 명령어를 사용하면 된다:

docker ps              # 실행 중인 컨테이너 목록 확인
docker stop calculator # 실행 중인 컨테이너 중지
docker rm calculator   # 중지된 컨테이너 삭제

이 명령어로 이름 충돌 문제를 해결한 뒤 새 컨테이너를 생성하면 오류 없이 파이프라인이 동작한다.

🪄 기존 컨테이너 제거 후 새 컨테이너 실행 자동화

매번 빌드할 때마다 컨테이너를 삭제하고 빌드할 필요 없이, deploy 단계에서 실행 중인 컨테이너를 중지 및 제거한 후 새 컨테이너를 실행하게 할 수 있다. 이러한 방식은 안정적인 배포 환경을 유지하는 데 매우 유용하다. 이를 통해 포트 충돌이나 리소스 중복 문제를 방지할 수 있다.

stage('deploy'){
   steps{
       sh 'docker rm -f calculator || true'  // 기존 컨테이너 제거
       sh "docker run -d --rm -p 8765:8080 --name calculator bestlalala/calculator"
   }
}

2. 인수 테스트 자동화

1) 테스트 스크립트 작성

루트 디렉터리에 테스트 스크립트를 작성하여 애플리케이션의 주요 기능을 자동으로 검증할 수 있다.

예시로 다음과 같이 작성한다: acceptance\_test.sh

#!/bin/bash
response=$(curl -s "http://localhost:8765/sum?a=10&b=3")
echo "Server response: $response"

if [ "$response" -eq 13 ]; then
  echo "Test passed"
else
  echo "Test failed"
  exit 1
fi
  • curl 명령어를 사용해 특정 API 엔드포인트를 호출하고, 응답값을 변수로 저장한다.
  • 조건문으로 응답값이 예상값(13)과 일치하는지 확인하여, 테스트 성공 여부를 판단한다.

 

2) Jenkinsfile에 테스트 단계 추가

Jenkinsfile에 해당 스크립트를 실행하는 단계를 추가한다:

stage('acceptance test'){
  steps{
      sleep 60
      sh 'chmod +x acceptance_test.sh && ./acceptance_test.sh'
  }
}
  • sleep 60은 컨테이너가 완전히 실행될 때까지 60초를 기다리는 역할을 한다.

여기서 sleep을 사용하는 이유는 컨테이너가 실행이 되고나서 다음 명령어를 실행하도록 하기 위해서다.

docker run -d 명령은 비동기 방식으로 실행되기 때문에, 연속해서 테스트하는 명령을 사용하면 컨테이너가 만들어지기 전에 테스트를 해서 실행은 제대로 되는데 테스트 단계에서 실패로 판정하는 경우가 발생할 수 있다.

 

젠킨스 빌드 로그 확인

Jenkins의 Console Output에서 파이프라인의 각 단계가 제대로 실행되었는지 확인할 수 있다.

sleep 60 명령 때문에 도커 컨테이너를 생성하고 나서 1분동안 기다리는 것을 확인할 수 있다.

1분 간 sleep

콘솔 확인

Pipeline console을 확인해보면 다음과 같이 테스트 스크립트 실행이 성공한 것을 확인할 수 있다.


3. Post 블록으로 리소스 관리

Jenkins 파이프라인에서 post 블록은 특정 스테이지나 전체 파이프라인의 실행이 완료된 후, 추가로 수행할 작업을 정의하는 데 사용된다. 파이프라인의 성공 여부와 관계없이 항상 실행되거나, 특정 조건에 따라 실행되도록 설정할 수 있다.

1) post 블록 구조 및 주요 요소

post {
    always {
        // 항상 실행되는 작업
    }
    success {
        // 파이프라인이 성공했을 때만 실행
    }
    failure {
        // 파이프라인이 실패했을 때만 실행
    }
    unstable {
        // 빌드가 unstable 상태일 때 실행
    }
    aborted {
        // 빌드가 중단되었을 때 실행
    }
}

 

2) 자주 사용하는 옵션

  • always: 파이프라인의 성공 여부와 상관없이 항상 실행되는 블록.
    • 주로 리소스 정리 작업에 사용.
  • success: 파이프라인이 성공했을 때만 실행.
    • 성공 시 알림 발송, 결과 저장 등.
  • failure: 파이프라인이 실패했을 때만 실행.
    • 실패 원인 분석, 오류 로그 저장, 알림 발송 등.
  • unstable: 테스트 실패 등으로 빌드가 불안정(unstable) 상태일 때 실행.
  • aborted: 빌드가 사용자에 의해 중단되었을 때 실행.

 

3) Clean up 스테이지 예시

파이프라인 실행 후 리소스를 정리하여 서버를 효율적으로 관리하기 위해, post 블록을 사용하여 컨테이너를 중지하는 코드를 추가한다:

post {
   always {
       sh 'docker stop calculator || true'  // 컨테이너 중지
   }
}
  • always 블록은 파이프라인 성공 여부와 관계없이 항상 실행된다.
  • 중복 실행 오류를 방지하기 위해 || true를 추가하여 중지할 컨테이너가 없더라도 오류가 발생하지 않도록 설정한다.

이렇게 하면 파이프라인이 종료될 때마다 자동으로 리소스가 정리되며, 서버 상태를 깨끗하게 유지할 수 있다.

728x90
반응형