IntelliJ HTTP Client를 활용한 Jenkins CI/CD 무중단 배포 및 자동 롤백 전략 (Docker & K8s)

IntelliJ HTTP Client를 활용한 Jenkins CI/CD 무중단 배포 및 자동 롤백 전략 (Docker & K8s)

1. 서론

개발자들에게 친숙한 IDE인 인텔리제이(IntelliJ IDEA)에는 강력한 API 테스트 도구인 .http 클라이언트가 내장되어 있습니다. 많은 분들이 이를 단순히 로컬 개발 환경에서 API를 호출해보는 용도로만 사용하지만, 사실 이 도구는 CI/CD 파이프라인의 핵심 안정성 검증 도구로 확장될 수 있는 잠재력을 가지고 있습니다. 특히 서비스 배포 과정에서 “배포 후 정상 작동 여부”를 사람이 직접 확인하는 것이 아니라, 스크립트를 통해 자동으로 검증하고 문제가 발생했을 때 즉시 이전 버전으로 되돌리는(Rollback) 전략은 서비스의 신뢰성을 결정짓는 중요한 요소입니다.

오늘은 IntelliJ HTTP Client의 CLI 버전인 ijhttp를 활용하여, 배포 직후 자동으로 API 테스트를 수행하고 그 결과에 따라 서비스 오픈 여부를 결정하는 고도화된 CI/CD 파이프라인 구축 방법에 대해 알아보겠습니다. 요청하신 시나리오에 맞춰 Nginx를 통해 트래픽을 제어(All Deny)하고, Ansible 기반의 Docker 환경과 Kubernetes(K8s) 환경 두 가지 케이스로 나누어, 테스트 실패 시 자동으로 롤백하여 서비스 장애를 원천 차단하는 전략을 상세하게 다루겠습니다.

2. 본론

1. IntelliJ HTTP Client CLI (ijhttp)와 Assertions의 이해

CI 환경에서 인텔리제이의 HTTP Client를 사용하기 위해서는 GUI가 아닌 CLI 환경에서 동작하는 ijhttp 도구가 필요합니다. 젯브레인(JetBrains)에서는 이를 위해 도커 이미지(jetbrains/intellij-http-client)를 제공합니다. 핵심은 .http 파일 내에 자바스크립트 기반의 검증 로직(Assertions)을 심는 것입니다.

핵심 원리:

  1. .http 파일에 client.test(...) 함수를 작성하여 응답 코드(200 OK)와 데이터 구조를 검증합니다.
  2. Jenkins 파이프라인에서 ijhttp 명령어를 실행합니다.
  3. 테스트가 실패(Assert Fail)하면 ijhttp는 비정상 종료 코드(Exit Code 1)를 반환합니다.
  4. Jenkins는 이 에러를 감지하여 즉시 배포 중단 및 롤백 스테이지를 실행합니다.

[.http 파일 작성 예시: health-check.http]

HTTP

GET http://{{host}}/health
Accept: application/json

> {%
client.test("Status code is 200", function() {
    client.assert(response.status === 200, "Response status is not 200");
});

client.test("Service is Up", function() {
    client.assert(response.body.status === "UP", "Service Status is not UP");
});
%}
2. 시나리오 1 – Jenkins + Ansible + Docker 환경의 배포 및 롤백 전략

이 환경에서는 Ansible이 배포의 주체이며, Nginx가 앞단에서 리버스 프록시 역할을 수행합니다. 전략의 핵심은 Nginx 설정 변경을 통해 외부 접근을 차단하고, 내부 포트로 테스트를 수행한 뒤 안전할 때만 다시 문을 여는 것입니다.

[배포 프로세스 상세]

  1. 서비스 차단 (Nginx Block):Ansible을 통해 Nginx 설정 파일에 deny all; 구문을 추가하거나, 점검 페이지를 띄우는 설정으로 교체한 후 Nginx를 리로드합니다. 이 시점부터 외부 사용자는 서비스에 접근할 수 없습니다.
  2. 신규 버전 배포 (Docker Deploy):기존 컨테이너를 내리지 않고 유지하거나(블루/그린 준비), 혹은 중단 후 신규 이미지를 기반으로 컨테이너를 실행합니다.
  3. HTTP Client 테스트 (Health Check):Jenkins에서 ijhttp 도커 컨테이너를 실행하여, 배포된 서비스의 내부 포트(예: localhost:8080) 로 직접 요청을 보냅니다. Nginx를 거치지 않고 직접 찌르는 것이 핵심입니다.
  4. 분기 처리 (Decision Making):
    • 성공 시: Ansible이 Nginx 설정을 원복(deny all 제거)하고 리로드하여 서비스를 오픈합니다.
    • 실패 시 (Assert Fail): Jenkins의 catch 블록이 실행됩니다. Ansible Playbook을 호출하여 신규 컨테이너를 제거하고, 백업해둔 이전 버전의 이미지를 다시 실행(Rollback)한 후 Nginx 차단을 해제합니다.

[Jenkins Pipeline 의사 코드]

Groovy

stage('Deploy & Test') {
    try {
        sh 'ansible-playbook nginx_block.yml' // 1. 차단
        sh 'ansible-playbook deploy_app.yml'  // 2. 배포
        
        // 3. 테스트 (실패 시 에러 발생으로 catch로 이동)
        sh 'docker run --rm -v $(pwd):/work -w /work jetbrains/intellij-http-client \
            -e host=Internal_IP:Port health-check.http'
            
        sh 'ansible-playbook nginx_open.yml'  // 4. 성공 시 오픈
    } catch (Exception e) {
        currentBuild.result = 'FAILURE'
        // 5. 실패 시 롤백 수행
        sh 'ansible-playbook rollback_app.yml'
        sh 'ansible-playbook nginx_open.yml' // 이전 버전으로 오픈
        error("Deployment failed due to health check failure.")
    }
}
3. 시나리오 2 – Jenkins + K8s 오케스트레이션 환경의 배포 및 롤백 전략

Kubernetes 환경에서는 Ingress Controller가 Nginx 역할을 대신하는 경우가 많습니다. K8s의 자체적인 롤링 업데이트 기능이 있지만, 더욱 확실한 검증을 위해 kubectl과 ijhttp를 조합하여 제어합니다.

[배포 프로세스 상세]

  1. 트래픽 차단 (Ingress Control):kubectl patch ingress 명령어를 사용하여 Ingress의 어노테이션을 수정, 모든 트래픽을 차단하거나 점검용 백엔드 서비스로 라우팅을 변경합니다. (All Deny 효과)
  2. 신규 배포 (Kubectl Apply):kubectl apply -f deployment.yaml을 실행하여 새로운 이미지를 배포합니다. kubectl rollout status 명령어를 통해 파드가 정상적으로 Running 상태가 될 때까지 대기합니다.
  3. HTTP Client 테스트 (Service Check):K8s 클러스터 내부 네트워크에 접근 가능한 Jenkins 에이전트 혹은 임시 파드(Pod)를 통해 ijhttp를 실행합니다. 이때 타겟은 서비스(Service)의 ClusterIP나 파드의 IP입니다.
  4. 분기 처리 및 롤백 (Rollout Undo):
    • 성공 시: Ingress 설정을 원래대로 복구하여 외부 트래픽을 유입시킵니다.
    • 실패 시: Jenkins에서 kubectl rollout undo deployment/my-service 명령어를 실행합니다. K8s는 즉시 이전 리비전으로 파드를 교체합니다. 롤백이 완료(rollout status 확인)되면 Ingress 차단을 해제합니다.

[주의사항 및 팁]

K8s 환경에서는 배포 중간에 트래픽을 완전히 끊는 것보다, Canary 배포와 유사하게 신규 파드용 Service를 따로 만들어서 테스트하는 것이 더 우아한 방법일 수 있습니다. 하지만, 요청하신 “Nginx 차단 후 배포” 전략은 데이터베이스 마이그레이션이 포함된 배포처럼 트래픽 유입이 절대 없어야 하는 상황에서 매우 유용합니다.

4. HTTP Client 활용 시의 장점과 고려사항

이 전략의 가장 큰 장점은 “테스트 코드의 자산화“입니다. Postman 컬렉션 등은 별도로 관리해야 하지만, .http 파일은 프로젝트 소스 코드(Git)와 함께 관리되므로 버전 관리가 용이하고 개발자가 로컬에서 테스트한 시나리오를 그대로 운영 배포 검증에 사용할 수 있습니다.

  • 환경 변수 분리: http-client.env.json 파일을 활용하여 개발(Dev), 검증(Staging), 운영(Prod) 환경의 호스트 주소를 분리하여 관리해야 합니다. ijhttp 실행 시 -e prod 옵션으로 쉽게 환경을 교체할 수 있습니다.
  • 구체적인 Assert: 단순히 200 OK만 체크하지 말고, 필수 필드 값 유무나 응답 시간(Latency)까지 체크하여 서비스 품질을 보장해야 합니다.

3. 결론

지금까지 IntelliJ HTTP Client를 활용하여 Jenkins, Ansible, Docker, Kubernetes 환경에서 안전한 배포 파이프라인을 구축하는 방법에 대해 알아보았습니다. 서비스 장애는 배포 직후에 가장 많이 발생합니다. 단순히 “배포가 완료되었다”는 쉘 스크립트의 종료 코드를 믿지 말고, 실제 애플리케이션이 HTTP 요청에 대해 올바른 비즈니스 로직으로 응답하는지 검증하는 과정이 필수적입니다.

Nginx를 활용한 트래픽 제어와 ijhttp를 통한 애플리케이션 계층의 정밀한 테스트, 그리고 자동화된 롤백 로직의 결합은 시스템 운영의 안정성을 획기적으로 높여줄 것입니다. 오늘 소개한 가이드를 바탕으로 여러분의 CI/CD 파이프라인을 한 단계 업그레이드해보시기 바랍니다.


댓글 남기기