7.6.2 크론잡: 예약된 작업 실행
앞서 우리는 잡(Job)을 통해 일회성 작업을 안정적으로 실행하고 관리하는 방법을 배웠습니다. 잡은 특정 작업을 한 번 수행하고 종료하는 데 매우 유용하지만, 만약 이러한 작업을 정해진 시간에 주기적으로 반복 실행해야 한다면 어떻게 해야 할까요? 예를 들어, 매일 자정에 데이터베이스 백업을 수행하거나, 매시간 시스템 상태 보고서를 생성하거나, 매주 월요일 아침에 특정 데이터를 동기화하는 등의 작업이 필요할 수 있습니다.
이러한 ‘예약된 작업’ 요구사항을 충족시키기 위해 쿠버네티스는 크론잡(CronJob)이라는 강력한 도구를 제공합니다. 크론잡은 이름에서 알 수 있듯이, 우리가 리눅스나 유닉스 시스템에서 흔히 사용하는 cron 유틸리티와 유사한 방식으로 동작합니다. 사용자는 특정 시간 또는 주기를 cron 형식으로 지정하고, 해당 스케줄에 맞춰 크론잡 컨트롤러가 내부적으로 잡(Job) 오브젝트를 생성하여 실행합니다. 즉, 크론잡은 ‘시간 관리자’ 역할을 하며, 정해진 시간이 되면 ‘일꾼(잡)’을 파견하여 실제 작업을 수행하도록 지시하는 것입니다.
크론잡을 사용하면, 반복적인 예약 작업을 수동으로 실행하는 번거로움에서 벗어나 자동화된 방식으로 안정적으로 관리할 수 있습니다. 이는 시스템 운영의 효율성을 크게 높여주고, 사람의 실수로 인한 작업 누락을 방지하는 데 도움을 줍니다. 마치 알람 시계처럼, 잊지 않고 정해진 시간에 우리 대신 일을 처리해주는 믿음직한 비서와 같다고 할 수 있습니다.
이제 크론잡이 어떻게 예약된 작업을 실행하고 관리하는지, 그 핵심적인 설정과 기능들을 자세히 살펴보겠습니다.
7.6.2.1 Cron 형식 스케줄링 (schedule)
크론잡의 가장 핵심적인 설정은 바로 언제 잡을 실행할지를 정의하는 스케줄입니다. 크론잡은 이 스케줄 정보를 spec.schedule 필드에 cron 형식의 문자열로 지정받습니다. 이 cron 형식은 전통적인 리눅스/유닉스의 cron 표현식과 거의 동일하며, 다음과 같이 5개 또는 6개의 필드로 구성됩니다 (일부 쿠버네티스 버전에서는 초(second) 단위 스케줄링을 지원하는 확장된 6개 필드 형식을 사용할 수도 있지만, 표준적으로는 5개 필드가 널리 사용됩니다).
<분> <시> <일> <월> <요일>
각 필드가 나타내는 의미와 허용되는 값은 다음과 같습니다.
- 분 (Minute): 0부터 59까지의 정수
- 시 (Hour): 0부터 23까지의 정수 (24시간제)
- 일 (Day of month): 1부터 31까지의 정수
- 월 (Month): 1부터 12까지의 정수, 또는 월의 영문 약자 (예: Jan, Feb, Mar 등)
- 요일 (Day of week): 0부터 7까지의 정수 (0과 7은 모두 일요일을 의미), 또는 요일의 영문 약자 (예: Sun, Mon, Tue 등)
각 필드에는 다음과 같은 특수 문자들을 사용할 수 있습니다.
- (별표): 해당 필드의 모든 값을 의미합니다. 예를 들어, 분 필드에 *를 사용하면 ‘매 분마다’라는 뜻이 됩니다.
- , (쉼표): 여러 값을 나열할 때 사용합니다. 예를 들어, 분 필드에 0,15,30,45를 사용하면 ‘0분, 15분, 30분, 45분에’라는 뜻이 됩니다.
- (하이픈): 값의 범위를 지정할 때 사용합니다. 예를 들어, 시 필드에 9-17을 사용하면 ‘오전 9시부터 오후 5시까지 매 시간’이라는 뜻이 됩니다.
- / (슬래시): 특정 값의 간격을 지정할 때 사용합니다. 예를 들어, 분 필드에 */5를 사용하면 ‘매 5분마다’ (0분, 5분, 10분, …)라는 뜻이 됩니다.
몇 가지 cron 표현식 예시:
- “0 * * * *”: 매 시간 0분에 실행 (예: 1:00, 2:00, 3:00 …)
- “*/15 * * * *”: 매 15분마다 실행 (예: 0분, 15분, 30분, 45분)
- “0 0 * * *”: 매일 자정(00:00)에 실행
- “0 0 1 * *”: 매월 1일 자정에 실행
- “0 0 * * 0” 또는 “0 0 * * SUN”: 매주 일요일 자정에 실행
- “30 9 * * 1-5”: 매주 월요일부터 금요일까지 오전 9시 30분에 실행
이 schedule 필드에 정의된 cron 표현식에 따라, 크론잡 컨트롤러는 지정된 시간이 되면 spec.jobTemplate 필드에 정의된 명세를 바탕으로 새로운 잡(Job) 오브젝트를 생성합니다. 이 잡은 다시 파드를 생성하여 실제 작업을 수행하게 됩니다. 스케줄은 UTC(협정 세계시)를 기준으로 해석될 수도 있고, 쿠버네티스 컨트롤러 매니저가 실행되는 시스템의 시간대를 따를 수도 있습니다. (일반적으로는 UTC 기준을 권장하거나, 명시적으로 시간대를 설정할 수 있는 기능이 추가될 수 있습니다. 사용하시는 쿠버네티스 버전의 문서를 확인하는 것이 좋습니다.)
이처럼 cron 형식을 통해 매우 유연하고 정교하게 작업 실행 스케줄을 정의할 수 있기 때문에, 다양한 주기적 작업 요구사항을 손쉽게 충족시킬 수 있습니다.
7.6.2.2 동시 실행 정책 (concurrencyPolicy)
크론잡이 정해진 스케줄에 따라 잡을 생성하다 보면, 이전에 시작된 잡이 아직 완료되지 않았는데 다음 실행 스케줄이 도래하는 경우가 발생할 수 있습니다. 예를 들어, 매 5분마다 실행되도록 설정된 작업이 있는데, 어떤 이유로 특정 작업이 5분 이상 소요되는 경우가 그렇습니다. 이때 크론잡이 어떻게 동작해야 할지를 결정하는 것이 바로 concurrencyPolicy 필드입니다.
concurrencyPolicy 필드에는 다음 세 가지 값 중 하나를 설정할 수 있습니다.
- Allow (기본값):이 정책을 사용하면 크론잡은 이전 잡의 완료 여부와 관계없이, 정해진 스케줄이 되면 항상 새로운 잡을 생성하여 동시에 실행합니다. 즉, 여러 개의 잡 인스턴스가 병렬로 실행될 수 있습니다.이 방식은 각 작업이 서로 독립적이고, 동시에 여러 인스턴스가 실행되어도 문제가 없는 경우에 적합합니다. 예를 들어, 매번 새로운 데이터를 처리하는 분석 작업이나, 각 실행이 서로 영향을 주지 않는 보고서 생성 작업 등이 해당될 수 있습니다.
하지만, 동시에 너무 많은 잡이 실행되면 클러스터의 리소스를 과도하게 소모할 수 있으므로 주의해야 합니다.
- Forbid:이 정책을 사용하면, 만약 이전 잡이 아직 실행 중이라면 다음 스케줄이 도래하더라도 새로운 잡을 생성하지 않고 건너뜁니다(skip). 즉, 동시에 여러 개의 잡 인스턴스가 실행되는 것을 금지합니다. 이전 잡이 완료된 후에야 다음 스케줄에 맞춰 새로운 잡이 생성될 수 있습니다.이 방식은 작업의 특성상 동시에 하나의 인스턴스만 실행되어야 하거나, 이전 작업의 결과가 다음 작업에 영향을 미치는 경우에 유용합니다. 예를 들어, 특정 리소스에 대한 잠금(lock)이 필요한 작업이나, 순차적인 데이터 처리가 중요한 백업 작업 등이 해당될 수 있습니다. 이 정책을 사용하면 의도치 않은 동시 실행으로 인한 데이터 충돌이나 리소스 경쟁을 방지할 수 있습니다.
- Replace:이 정책을 사용하면, 다음 스케줄이 도래했을 때 만약 이전 잡이 아직 실행 중이라면, 크론잡은 실행 중이던 이전 잡을 취소(삭제)하고 새로운 잡으로 대체합니다. 즉, 항상 가장 최근 스케줄의 잡만 실행되도록 보장합니다.이 방식은 항상 최신 상태의 작업만 유효하고, 이전 작업은 더 이상 의미가 없어지는 경우에 적합할 수 있습니다. 예를 들어, 특정 시스템의 상태를 주기적으로 스냅샷하는 작업에서, 새로운 스냅샷 작업이 시작되면 이전 스냅샷 작업은 중단되어도 괜찮은 경우가 있을 수 있습니다. 하지만 이 정책은 실행 중이던 작업을 강제로 중단시킬 수 있으므로, 작업의 성격을 신중히 고려하여 사용해야 합니다.
어떤 concurrencyPolicy를 선택할지는 실행하려는 작업의 특성, 리소스 제약, 그리고 동시 실행 시 발생할 수 있는 잠재적인 문제점들을 종합적으로 고려하여 결정해야 합니다. 기본값인 Allow는 유연하지만 리소스 관리에 주의가 필요하며, Forbid나 Replace는 특정 상황에서 작업의 안정성이나 일관성을 보장하는 데 도움이 될 수 있습니다.
7.6.2.3 잡 기록 관리 (successfulJobsHistoryLimit, failedJobsHistoryLimit)
크론잡은 스케줄에 따라 주기적으로 잡(Job)을 생성하고 실행합니다. 시간이 지남에 따라 이렇게 생성된 잡 오브젝트들과 그에 따른 파드 오브젝트들이 클러스터에 계속 쌓이게 되면, 쿠버네티스 API 서버에 부담을 주거나 리소스를 불필요하게 차지할 수 있습니다. 또한, 너무 많은 과거 기록은 관리를 어렵게 만들기도 합니다.
이러한 문제를 해결하기 위해 크론잡은 완료된 잡(성공 또는 실패)의 기록을 얼마나 보관할지를 제어하는 기능을 제공합니다. 바로 successfulJobsHistoryLimit와 failedJobsHistoryLimit 필드입니다.
- successfulJobsHistoryLimit 필드 (선택 사항):이 필드는 성공적으로 완료된 잡(Job) 오브젝트를 몇 개까지 보관할지를 지정합니다. 여기에 설정된 개수를 초과하는 오래된 성공 잡들은 자동으로 삭제됩니다.
- 기본값은 3입니다. 즉, 별도로 설정하지 않으면 최근 3개의 성공한 잡 기록이 유지됩니다.
- 이 값을 0으로 설정하면, 성공한 잡은 완료되는 즉시 기록이 삭제되어 보관되지 않습니다.
- 성공한 작업의 로그나 상태를 일정 기간 확인하고 싶다면 이 값을 적절히 설정하는 것이 좋습니다.
- failedJobsHistoryLimit 필드 (선택 사항):이 필드는 실패한 잡(Job) 오브젝트를 몇 개까지 보관할지를 지정합니다. 여기에 설정된 개수를 초과하는 오래된 실패 잡들은 자동으로 삭제됩니다.
- 기본값은 1입니다. 즉, 별도로 설정하지 않으면 최근 1개의 실패한 잡 기록이 유지됩니다.
- 이 값을 0으로 설정하면, 실패한 잡은 즉시 기록이 삭제되어 보관되지 않습니다.
- 실패한 작업의 원인을 분석하고 디버깅하기 위해서는 실패 로그와 파드 상태를 확인해야 하므로, 이 값을 너무 작게 설정하는 것은 권장되지 않습니다. 실패 원인 파악에 필요한 충분한 시간을 확보할 수 있도록 적절한 값을 설정하는 것이 중요합니다.
이 두 필드를 통해 사용자는 자신의 필요에 맞게 잡 기록의 보관 정책을 설정할 수 있습니다. 예를 들어, 성공한 작업은 자주 확인하지 않으므로 기록을 최소한으로 남기고, 실패한 작업은 원인 분석을 위해 좀 더 많은 기록을 남기고 싶다면 successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 5 와 같이 설정할 수 있습니다.
이러한 잡 기록 관리 기능은 클러스터의 자원을 효율적으로 사용하고, API 서버의 부하를 줄이며, 필요한 만큼의 과거 작업 이력만을 유지하여 관리를 용이하게 해줍니다. 마치 오래된 서류는 주기적으로 정리하여 중요한 서류만 남겨두는 것과 같이, 크론잡은 깔끔하게 자신의 작업 기록을 관리합니다.
지금까지 살펴본 schedule, concurrencyPolicy, 그리고 잡 기록 관리 설정들은 크론잡을 효과적으로 사용하기 위해 반드시 이해해야 하는 핵심 요소들입니다. 이러한 설정들을 통해 우리는 다양한 종류의 예약된 작업을 쿠버네티스 환경에서 안정적이고 효율적으로 자동화할 수 있게 됩니다.