우리가 지금까지 구축한 파이프라인은 대부분 누군가 Github에 코드를 푸시(Push)하거나, 젠킨스 화면에서 수동으로 Build Now 버튼을 눌렀을 때(Event-Driven) 동작하는 방식이었습니다. 하지만 실무에서는 사람의 개입이나 특별한 이벤트 없이도 정해진 시간(스케줄)에 스스로 깨어나 묵묵히 돌아가야 하는 백그라운드 작업들이 매우 많습니다. 매일 밤 자정에 도는 무거운 대규모 E2E 통합 테스트, 매일 새벽 3시에 수행되는 데이터베이스 덤프 백업, 매주 월요일 아침 8시에 슬랙으로 전송되는 주간 빌드 통계 리포트 등이 대표적입니다.
이번 [Jenkins 실무 완벽 가이드] 시리즈에서는 인프라 엔지니어가 잠든 시간에도 기계가 스스로 일하게 만드는 Jenkins 스케줄러(Cron Trigger)의 완벽한 문법과 부하 분산 노하우에 대하여 3,000자 분량으로 아주 치밀하게 딥다이브 해보겠습니다.

⏰ 1. Build periodically vs Poll SCM (과거의 유산)
젠킨스의 트리거(Trigger) 메뉴를 보면 스케줄링을 설정할 수 있는 옵션이 크게 두 가지가 있습니다. 이 둘의 차이를 명확히 알아야 실무에서 헤매지 않습니다.
1. Poll SCM (더 이상 쓰지 않음):
"매 5분마다 Github에 들어가서 코드가 바뀌었는지 물어보고(Poll), 바뀌었으면 빌드해라"라는 뜻입니다. 과거 Github Webhook 기능이 빈약하던 시절에 쓰던 구시대적 유물입니다. 5분마다 젠킨스가 무의미하게 Github API를 찔러대므로 네트워크 낭비가 심합니다. 현대 CI/CD에서는 코드가 바뀌면 Github이 젠킨스를 먼저 찔러주는(Webhook) 방식을 사용하므로 Poll SCM은 실무에서 퇴출되었습니다.
2. Build periodically (이것이 진짜 Cron):
"코드가 바뀌었든 말든 묻지도 따지지도 않고, 내가 지정한 시간에 무조건 파이프라인을 1회 실행하라"는 뜻입니다. 백업, 통계 생성, 자정 통합 테스트 등 진정한 의미의 스케줄링(배치 작업)을 원할 때는 무조건 이 옵션을 사용해야 합니다.
✨ 2. 리눅스 Cron과의 차이점: 마법의 키워드 'H'
젠킨스의 스케줄링 문법은 리눅스의 표준 crontab 문법(분 시 일 월 요일)을 베이스로 합니다. 하지만 리눅스 크론을 그대로 쓰다 보면 대형 인프라 환경에서 심각한 서버 폭주(Spike) 현상이 발생합니다.
예를 들어, "매일 밤 12시 정각에 각 서비스의 백업을 수행해라"라는 뜻으로 50개의 Job에 0 0 * * * 라고 적어두었다고 칩시다. 11시 59분 59초에서 12시 00분 00초가 되는 순간, 젠킨스 서버는 50개의 무거운 파이프라인을 '동시에' 시작하려 들 것이고, CPU와 메모리가 임계점을 돌파하며 서버가 기절해 버립니다.
이러한 DDoS급 자폭을 막기 위해 젠킨스는 H (Hash)라는 독자적이고 천재적인 키워드를 도입했습니다. H 0 * * * 라고 적으면 "매일 밤 12시 00분부터 12시 59분 사이의 아무 랜덤한 시간(Hash 연산 기반)에 한 번 돌려라"라는 뜻이 됩니다. 50개의 Job에 모두 똑같이 H 0 * * *를 적어두면, 젠킨스는 내부 알고리즘에 따라 A 잡은 12시 5분에, B 잡은 12시 13분에, C 잡은 12시 42분에 스스로 시간을 분산시켜 차례대로 실행합니다. 서버 부하 분산(Load Balancing)이 코드 한 글자로 완벽하게 해결되는 마법입니다. 실무에서는 숫자를 명시하는 것보다 H를 쓰는 것을 강력한 Best Practice로 권장합니다.
💻 3. Declarative Pipeline 적용 코드 파헤치기
웹 UI 설정창(텍스트 박스)에 적을 수도 있지만, 우리는 모든 것을 코드로 관리하는 IaC(Infrastructure as Code)를 지향하므로 Jenkinsfile 내부에 직접 명시해야 합니다. pipeline 블록 최상단에 triggers 블록을 선언하여 스케줄을 박아 넣습니다.
pipeline {
agent any
// 이 파이프라인은 지정된 시간에 스스로 깨어납니다.
triggers {
// 1. 매일 밤 12시 ~ 새벽 1시 사이 랜덤 분산 실행 (가장 추천)
cron('H 0 * * *')
// 2. 주말(토, 일)을 제외하고, 평일(월~금) 새벽 2시 정각에 칼같이 실행하고 싶을 때
// cron('0 2 * * 1-5')
// 3. (극단적 예시) 2시간마다 1번씩 하루에 12번 실행
// cron('H H/2 * * *')
}
stages {
stage('Nightly Massive E2E Test') {
steps {
echo "🌙 심야 정기 통합 테스트(약 2시간 소요)를 시작합니다..."
// sh 'npm run test:e2e-all'
}
}
stage('Generate Daily Report') {
steps {
echo "테스트 통계를 집계하여 PDF 리포트를 생성합니다..."
}
}
}
post {
always {
echo "사장님과 팀장님이 계신 슬랙 채널로 리포트를 쏩니다!"
// slackSend ...
}
}
}
🎯 4. 마무리 및 다음 단계
지금까지 서버 부하를 막아주는 지능형 분산 키워드 `H`의 원리와, 파이프라인 코드로 배치 작업을 완벽하게 자동화하는 주기적 빌드(Cron Trigger) 설정법에 대해 3,000자의 밀도 높은 내용으로 살펴보았습니다. 이제 여러분은 새벽에 졸린 눈을 비비며 서버에 접속해 백업 스크립트를 누르던 노예 생활을 청산하고 진정한 데브옵스의 자유를 얻었습니다.
스케줄링을 통해 새벽에 빌드를 빵빵하게 돌리는 것까지는 좋았는데, 아침에 출근해 보니 "빌드가 1번 도는 데 30분이나 걸린다"는 충격적인 리포트를 받게 되었습니다. 원인을 분석해 보니, 젠킨스가 빌드를 할 때마다 수 기가바이트에 달하는 자바 라이브러리(Maven/Gradle)를 인터넷에서 처음부터 싹 다 새로 다운받고 있었던 것입니다! 이어지는 27단계 포스팅에서는 "한 번 받은 파일은 절대 다시 받지 않는다!" 빌드 속도를 10배 이상 끌어올리는 극강의 최적화 비법, 'Maven/Gradle 빌드 캐시(Cache) 완벽 마운트 전략'에 대해 아주 치밀하게 파헤쳐 보겠습니다!
'CI.CD > Jenkins' 카테고리의 다른 글
| [Jenkins] GitHub PR(Pull Request) 빌드 자동화 구축하기 (0) | 2026.07.22 |
|---|---|
| [Jenkins] Maven / Gradle 빌드 캐시 최적화 (빌드 시간 10배 단축의 비밀) (0) | 2026.07.22 |
| [Jenkins] Jenkins 백업 스크립트의 정석 (서버가 불타도 3분 만에 부활하기) (0) | 2026.07.22 |
| [Jenkins] Input Step: 상용 배포 전 수동 승인(결재) 결계 치기 (0) | 2026.07.22 |
| [Jenkins] Kubernetes(K8s) 완벽 연동: 무중단 배포 자동화의 끝판왕 (0) | 2026.07.22 |