사내 프로젝트를 젠킨스를 통해 배포 자동화를 구축 후, 문제가 발생하게 된다.

상기의 이미지처럼, Jenkins Build Step을 쉘 스크립트로 비교적 간단하게 작성했다.

 

NestJS로 프로젝트를 구성했던 터라,

  1. npm run build 후(TypeScript compile to JavaScript)
  2. 생성된 dist 디렉토리의 main.js 실행이 필요했기에 pm2 기본 config 파일을 생성(ecosystem.config.js)
  3. 해당 config.js 파일 내부에 필요한 인스턴스 갯수와, 실행 파일의 경로를 작성해주었다.
// root/ecosystem.config.js

module.exports = {
  apps: [
    {
      name: 'primary',
      script: './dist/main.js',
      instances: 1,
      exec_mode: 'cluster',
    },
    {
      name: 'replica',
      script: './dist/main.js',
      instances: 13,
      exec_mode: 'cluster',
    },
  ],
};

위의 단계를 통해 프로젝트 레포지토리에 푸쉬 이벤트 발생 시, 레포지토리에서 웹 훅을 발생시켜 Jenkins 서버에서 자동으로

위 첫번째 사진의 Build Step들이 실행되도록 구축하였다.

 

요약

  • Jenkins Build Step에서 노드 프로세스 매니저인 Pm2를 config.js 실행 시키도록 설정
  • 위의 Jenkins jobs 이 끝난 후, 배포 성공 여부를 슬렉 알림으로 받음
  • 배포 서버에 정상적으로 변경 사항이 반영된 것까지 확인 후, 모든 것이 끝났다고 생각했다.

그러나, 문제는 여기서 발생하게 된다.

  • 배포 서버의 pm2 로그 확인을 위해 ssh로 접속 후, pm2 logs를 확인 해보았지만 .. 아무것도 보이지 않았다
  • 뭔가 잘못된 것을 직감 하고 배포 된 웹서버에 접속해보았지만...이게 웬일 ? 실제로 웹은 정상적으로 동작하고 있었다. (ㄷㄷㄷ...)
  • 다시 말하자면, 젠킨스에서 pm2 start와 reload가 잘 일어 났지만, 서버의 pm2 list엔 전혀 찾아 볼 수가 없었다.

왜 이런일이 발생한걸까? 처음부터 접근 방법이 잘못 되었던 것이다.

 

Jenkins 잡에서 실행되는 pm2 프로세스는 서버 로컬 환경이 아닌 젠킨스 내의 새로운 세션에서 실행된다.

따라서 이 새로운 세션에서 pm2를 실행한 것이니, 로컬 환경에서 직접 프로세스의 목록을 확인이 불가능 했던 것이다.

 

또한 pm2는 현재 사용자 세션과 관련된 프로세스 목록만 표시하기 때문에, 젠킨스 내부의 새로운 세션에서 실행되는 프로세스는 해당 세션에 대한 정보를 표시 할 수 없으며, pm2 list에서 보이지 않았던 것이다.

 

서버 로컬 환경에서 pm2 list가 나오지 않았던 이유를 알게됐다.. 하지만 왜? 젠킨스는 이렇게 동작하는 걸까 ?

기존 처음 젠킨스를 접하고, 쉘 스크립트로 파이프라인을 구축했을 때, 해당 서버의 로컬 환경에서 정의된 쉘 스크립트를 그대로 실행하는 줄 알았다. 

그러나, 젠킨스 잡은 젠킨스에서 실행되는 작업 단위로, 일반적으로 빌드, 배포, 테스트 등의 작업만을 수행 한다.

 

위에 설명한 바와 같이 젠킨스 잡은 새로운 세션에서 실행되며, 이는 젠킨스 잡이 독립된 환경에서 실행되도록 하는 데 목적이 있다.

  1. 환경 분리 : 젠킨스 잡은 여러 개의 빌드 또는 배포를 병렬로 실행할 수 있다. 이를 위해 각 Job은 독립된 환경에서 실행되어야 한다.
    즉, 각 Job은 자체적인 프로세스 그룹 또는 세션에서 실행되어 서로의 작업에 영향을 주지 않는다.
  2. 격리와 안정성 : 새로운 세션에서 Jenkins Job을 실행함으로써, 현재 사용자 세션 또는 기존의 실행 중인 프로세스에 영향을 주지 않고 독립적으로 실행될 수 있다. 이렇게 함으로써 잡의 실행 중에 발생하는 예외나 에러가 다른 프로세스에 영향을 주지 않고 안정적으로 처리 될 수 있다.
  3. 자원 관리: 젠킨스 잡이 별도의 세션에서 실행되면, 해당 세션에 할당된 자원(메모리, CPU등) 을 더 효율적으로 관리가 가능하다.

따라서 젠킨스 잡은 새로운 세션에서 실행되며, 젠킨스에서 실행되는 pm2 프로세스는 새로운 세션에서 실행되어 pm2 list를 통해 직접 빌드 스크립트에서 확인을 해야한다.

 

젠킨스 pm2가 새로운 세션에서 동작한다는 것을 인지한 후, 해당 빌드 스크립트(젠킨스 잡)에서 프로세스 로그를 표현하기엔 보기가 상당히 불편했기 때문에 다른 방법을 모색 해보았다.

 

자동 업데이트 스크립트 구성하기

젠킨스에 의해 실행될 스크립트를 먼저 작성.

#!/bin/bash
sudo npm install # yarn이나 npm 둘 다 하나만
npm run build
pm2 restart ecosystem.config.js

해당 파일을 프로젝트 루트 경로에 생성 해주고, Jenkins 잡 빌드 스크립트에서 해당 파일을 실행 시켜준다면,

처음 원했던 대로 새로운 세션에서 실행되지 않고 서버 로컬 환경에서 pm2 프로세스로 실행이 되며 서버 로그를 쉽게 확인이 가능했다.. !

 

+ Recent posts