Search
moon
sun

Jenkins 배치 220개를 Temporal로 옮기며 고민한 것들

URL
생성 일시
2026/10/20 03:01
최종 편집 일시
2026/10/20 03:01
태그
인프랩
파일과 미디어
어느 날 한 개발자분께 메시지가 왔습니다. 배치가 실행되지 않아 확인해 보니 Jenkins의 디스크가 가득 차 멈춰 있었습니다. 빌드 이력 보존 설정(logRotator)이 빠진 잡들의 이력이 정리되지 않고 계속 쌓인 것이 원인이었습니다. 그 사이 큐에는 실행을 기다리는 배치가 3,000건 가까이 쌓였습니다. 쌓여 있던 빌드 이력을 정리해 Jenkins를 다시 띄웠지만, 큐에 밀린 배치를 그대로 실행하면 사용자 알림이 엉뚱한 시점에 나갈 수 있었습니다. 결국 큐를 전부 비우고 백엔드 개발자분들이 다시 돌려야 할 배치를 직접 골라 수동으로 실행했습니다. 이 글에서는 이런 일이 반복되던 배치 시스템을 Jenkins에서 Temporal로 옮기며 고민한 것들을 정리했습니다. 기존 배치 구조 Jenkins는 인프런과 랠릿, 내부 서비스 등에 배치 시스템으로 사용되어 왔습니다. 서비스마다 개발/운영 Jenkins를 하나씩 띄워 EC2 12대에서 Jenkins가 각각 단독으로 동작했습니다. 잡 220개가 하루에 약 15,900번 실행됐습니다. 각 서비스는 배치 코드를 Docker 이미지로 빌드하고, Groovy로 작성한 Jenkins 잡은 파이프라인에서 그 이미지를 docker run 하거나 서비스의 배치용 API를 curl로 호출했습니다. Jenkins에서 겪은 문제 한 번 멈추면 모든 배치가 멈추는 Jenkins Jenkins는 잡 정의, 빌드 이력, 로그, 배치 이미지를 모두 디스크에 저장하고, 디스크가 가득 차면 모든 배치가 멈춥니다. 이 문제는 Jenkins를 도입한 시기부터 거의 분기마다 반복됐습니다. 빌드 이력 보존 개수를 제한하고 디스크도 여러 번 늘렸지만 원인이 매번 조금씩 달라 근본적으로 막기는 어려웠습니다. 플러그인도 Jenkins를 멈추게 했습니다. Jenkins는 대부분의 기능을 플러그인으로 추가하고 플러그인끼리 서로 의존합니다. 2024년 10월에는 Datadog 플러그인을 새로 설치하고 재시작했는데 이미 쓰고 있던 GitHub 플러그인과 의존성이 맞지 않아 Jenkins가 아예 뜨지 않았습니다. Jenkins와 GitHub 플러그인을 업그레이드해 다시 띄울 때까지 그 Jenkins의 배치는 하나도 실행되지 않았고, 복구한 뒤에는 놓친 배치를 찾아 하나씩 다시 실행해야 했습니다. 이런 문제는 재시작하기 전에는 발견하는 것이 어렵고, 버전과 플러그인 구성이 조금씩 다른 Jenkins 12대를 업데이트할 때마다 같은 위험을 감수해야 했습니다. 실패해도 모르는 배치 Jenkins에서는 Slack 알림을 보내는 함수를 공용 Groovy 라이브러리(Jenkins Shared Library)로 만들어 두었지만, 언제 알림을 보낼지는 잡마다 Groovy 파일에 직접 설정해야 했습니다. 그러다 보니 어떤 상황을 실패로 보고 알림을 보낼지도 잡마다 달랐습니다. 한 데이터 동기화 잡은 중간 단계가 DB 인증 오류로 계속 실패했는데도 마지막 단계가 성공하면서 잡 전체가 SUCCESS로 기록돼 알림이 한 번도 오지 않았습니다. 설정 실수이긴 하지만 잡 220개가 각자 알림을 설정하는 구조라면 이런 실수는 어디선가 계속 생길 수밖에 없습니다. 게다가 Jenkins 자체가 멈추면 잡이 실패하지도 끝나지도 않아서 알림이 아예 나가지 않았습니다. 평소에는 놀고, 몰리면 부족한 서버 배치는 정해진 시각에 잠깐 돌고 끝나는데 Jenkins 서버는 24시간 켜져 있어야 합니다. 호스트별 평균 CPU 사용률은 계정 관련 배치가 몰린 2대를 빼면 6%도 되지 않았습니다. 반대로 배치가 몰리는 시간에는 같은 EC2에서 잡들이 자원을 나눠 써야 해서 무거운 잡이 자원을 점유하면 다른 잡의 실행이 뒤로 밀릴 수 있었습니다. 그래서 사용자가 적은 새벽 시간대에 배치를 몰아서 돌리기 어려웠고 여러 시간대로 나눠 실행해야 했습니다.