
정기적인 반복 작업, 아직도 수동으로 처리하시나요?
새벽 3시에 데이터베이스 백업을 실행해야 하는데, 깜빡하고 잠들었다가 다음 날 아침에 경악하며 일어난 경험이 있으신가요? 혹은 매일 아침 특정 서버의 로그를 수집해 외부 저장소로 옮기는 작업을 매번 명령어를 입력하며 수행하고 있지는 않나요? 온프레미스(On-premise) 환경이나 클라우드 환경을 막론하고, 인프라 운영자에게 반복적인 수동 작업은 치명적인 실수와 운영 피로도를 유발하는 주범이에요.
쿠버네티스(Kubernetes) 환경에서는 이러한 문제를 해결하기 위해 크론잡(CronJob)이라는 강력한 도구를 제공해요. 크론잡은 리눅스의 크론(Cron) 시스템과 매우 유사한 방식으로 작동하며, 사용자가 설정한 특정 시간에 맞춰 컨테이너 기반의 작업을 자동으로 실행해줘요. 단순히 명령어를 실행하는 것을 넘어, 작업이 실패했을 때의 재시도 정책이나 이전 작업의 기록 관리까지 쿠버네티스가 직접 관리해준다는 점이 가장 큰 매력이에요.
이 글은 단순히 이론을 설명하는 데 그치지 않아요. 실제로 운영 환경에서 바로 적용할 수 있는 크론잡 실전 예제를 바탕으로, 설정 파일 작성부터 배포, 그리고 작업이 제대로 돌아가는지 확인하는 검증 과정까지 아주 상세하게 다룰 예정이에요. 이 과정을 모두 마치고 나면, 여러분은 더 이상 정해진 시간에 알람을 맞추고 명령어를 입력할 필요가 없게 될 거예요.
- 실무에서 바로 쓰는 크론잡 매니페스트(Manifest) 작성법
- 클러스터에 배포하고 동작 상태를 실시간으로 감시하는 방법
- 작업이 성공했는지 로그를 통해 완벽하게 검증하는 절차
- 자주 발생하는 설정 오류와 해결을 위한 트러블슈팅 가이드
실습 전 반드시 확인해야 할 사전 준비 사항
크론잡을 성공적으로 실행하기 위해서는 단순히 명령어 하나를 아는 것보다, 현재 운영 중인 쿠버네티스 환경이 어떤 상태인지 파악하는 것이 훨씬 중요해요. 준비되지 않은 상태에서 무작정 YAML 파일을 적용했다가는 리소스 부족으로 인해 작업이 무한히 지연되거나, 의도치 않은 중복 작업이 발생해 시스템 부하를 일으킬 수 있거든요.
가장 먼저 확인해야 할 것은 kubectl 접근 권한이에요. 크론잡을 생성하고 관리하려면 클러스터의 리소스를 제어할 수 있는 적절한 권한이 필요해요. 또한, 실행하고자 하는 작업이 담긴 컨테이너 이미지가 이미 레지스트리(Registry)에 등록되어 있어야 하며, 쿠버네티스 노드들이 해당 이미지를 가져올 수 있는 네트워크 환경인지도 점검해야 해요.
특히 주의 깊게 살펴봐야 할 부분은 스케줄링 규칙이에요. 크론잡은 리눅스의 crontab 문법을 따르는데, 분, 시, 일, 월, 요일의 순서를 정확히 지켜야 해요. 만약 잘못된 형식을 입력하면 쿠버네티스는 에러를 내뱉으며 생성을 거부하거나, 아예 실행되지 않는 상황이 발생할 수 있어요. 또한, 작업이 실행될 때 사용하는 ServiceAccount의 권한이 작업 내용(예: 다른 리소스 조회)에 충분한지도 미리 따져봐야 해요.
환경 및 설정 기준 비교
작업의 성격에 따라 크론잡의 설정 옵션을 다르게 가져가야 해요. 아래 표를 참고해서 여러분의 작업에 어떤 정책이 적합할지 결정해 보세요.
| 설정 항목 | 옵션 유형 | 특징 및 권장 용도 |
|---|---|---|
| 동시성 정책 (Concurrency Policy) | Allow | 이전 작업이 끝나지 않아도 새 작업을 실행해요. 독립적인 작업에 적합해요. |
| 동시성 정책 (Concurrency Policy) | Forbid | 이전 작업이 진행 중이면 새 작업을 실행하지 않아요. 데이터 충돌 방지에 필수적이에요. |
| 동시성 정책 (Concurrency Policy) | Replace | 이전 작업을 강제로 종료하고 새 작업을 시작해요. 항상 최신 상태 유지가 중요할 때 사용해요. |
| 기록 유지 (History Limit) | SuccessfulJobsLimit | 성공한 작업의 로그를 몇 개까지 남길지 결정해요. 디스크 공간 관리를 위해 조절이 필요해요. |
| 기록 유지 (History Limit) | FailedJobsLimit | 실패한 작업의 기록을 유지해요. 문제 분석을 위해 최소 3개 이상을 권장해요. |
크론잡이 실행되는 노드의 자원(CPU, 메모리)이 부족하면 작업이 Pending 상태에 머물 수 있어요. 실습 전 노드의 여유 자원을 반드시 확인하세요.
크론잡 실전 예제: 배포부터 로그 확인까지 5단계
이제 본격적으로 실습을 시작해 볼게요. 이번 예제에서는 매일 특정 시간에 시스템의 상태를 점검하고 결과를 출력하는 간단한 시스템 체크 크론잡을 만들어 볼 거예요. 이 과정을 통해 매니페스트의 구조와 쿠버네티스 명령어를 익힐 수 있어요.
STEP 1. 실행용 매니페스트(Manifest) 작성하기
먼저 크론잡의 설계도라고 할 수 있는 YAML 파일을 작성해야 해요. 메모장이나 VS Code 같은 에디터를 열고 아래 내용을 작성해 주세요. 이 예제는 매 분마다 실행되도록 설정되어 있어, 실습 시 동작을 바로 확인할 수 있어요.
apiVersion: batch/v1
kind: CronJob
metadata:
name: system-check-cronjob
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Forbid
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: checker
image: busybox
command:
- /bin/sh
- -c
- "date; echo 'System check completed successfully!'"
restartPolicy: OnFailure
작성한 코드의 핵심 포인트를 짚어 드릴게요. schedule: “*/1 * * * *”는 1분마다 작업을 실행하라는 의미예요. concurrencyPolicy: Forbid는 앞선 작업이 끝나지 않았다면 다음 작업을 실행하지 말라는 명령으로, 중복 실행을 방지하는 안전장치예요. 마지막으로 restartPolicy: OnFailure는 작업이 실패했을 때만 컨테이너를 재시작하도록 설정하여, 불필요한 무한 루프를 막아줘요.
STEP 2. 클러스터에 크론잡 배포하기
파일 작성이 완료되었다면, 이제 이 설계를 쿠버네티스 클러스터에 전달할 차례예요. 터미널을 열고 파일이 저장된 디렉토리로 이동한 뒤, kubectl apply 명령어를 사용해 주세요.
kubectl apply -f cronjob.yaml
명령어를 입력했을 때 cronjob.batch/system-check-cronjob created라는 메시지가 출력된다면 성공적으로 배포된 거예요. 만약 에러가 발생한다면, YAML 파일의 들여쓰기(Indentation)가 정확한지, 혹은 오타가 없는지 다시 한번 꼼꼼히 확인해 보세요. 쿠버네티스 설정 파일은 띄어쓰기 하나에도 매우 민감하답니다.
STEP 3. 동작 상태 및 생성된 Job 확인하기
크론잡은 그 자체로 실행되는 것이 아니라, 스케줄 시간에 맞춰 Job이라는 객체를 생성하고, 그 Job이 다시 Pod를 만들어 실제 작업을 수행해요. 따라서 우리는 계층적으로 상태를 확인해야 해요.
먼저 크론잡 자체가 잘 등록되었는지 확인해 보세요.
kubectl get cronjob
출력 결과에서 LAST SCHEDULE 항목에 최근 실행 시간이 찍혀 있다면 정상이에요. 그다음, 실제로 생성된 Job이 있는지 확인합니다.
kubectl get jobs
여기서 Job의 상태가 COMPLETED로 표시되어야 작업이 성공적으로 끝난 거예요. 만약 Error나 Failed가 보인다면 작업 내용에 문제가 있는 것이니 즉시 조사가 필요해요.
STEP 4. 작업 로그(Log)를 통한 상세 검증
작업이 성공했다고 해도, 실제로 컨테이너 내부에서 어떤 일이 벌어졌는지 확인하는 과정은 반드시 필요해요. 로그를 확인하기 위해서는 먼저 작업이 실행된 Pod의 이름을 알아내야 해요.
kubectl get pods
목록에서 system-check-cronjob-xxxxx와 같은 이름을 가진 Pod를 찾으세요. 이름이 확인되었다면 아래 명령어로 로그를 출력해 보세요.
kubectl logs [POD_NAME]
로그에 우리가 설정했던 ‘System check completed successfully!’라는 문구가 출력된다면 완벽하게 성공한 거예요. 이 과정은 데이터베이스 백업이나 로그 수집 작업이 의도한 대로 데이터를 잘 생성했는지 검증할 때 핵심적인 단계가 돼요.
STEP 5. 고급 설정: 리소스 제한 및 타임존 설정
실무에서는 단순한 명령 실행을 넘어, 시스템 자원을 효율적으로 관리해야 해요. 크론잡에도 일반 Pod와 마찬가지로 resources 설정을 추가하는 것이 권장돼요. CPU와 메모리의 최소(requests) 및 최대(limits) 사용량을 명시함으로써, 특정 크론잡이 클러스터 전체의 자원을 고갈시키는 상황을 방지할 수 있어요.
또한, 매우 중요한 팁 하나를 드릴게요. 바로 타임존(Timezone) 설정이에요. 쿠버네티스 클러스터의 기본 시간은 보통 UTC(세계 협정시)로 설정되어 있어요. 만약 여러분이 한국 시간(KST) 기준으로 매일 오전 9시에 작업을 실행하고 싶어 “0 9 * * *”라고 설정했다면, 실제로는 한국 시간 기준 오후 6시에 작업이 돌아가게 돼요. 이를 방지하기 위해 최신 쿠버네티스 버전에서는 timeZone 필드를 지원하므로, 반드시 timeZone: "Asia/Seoul" 설정을 추가하여 혼선을 예방하세요.
실무에서는 작업이 성공했는지 여부를 판단하기 위해 외부 모니터링 도구(예: Prometheus)를 연동하여 성공/실패 횟수를 그래프로 시각화하여 관리하는 것이 일반적이에요.
자주 하는 실수와 해결법
크론잡을 운영하다 보면 예상치 못한 상황에 직면하게 돼요. 현장에서 가장 자주 발생하는 5가지 사례와 그 해결책을 정리해 드릴게요.
- ❌ 스케줄 설정 오류 → 잘못된 크론 표현식을 사용하여 작업이 실행되지 않거나 원치 않는 시간에 실행됨 → ✅ crontab.guru 같은 온라인 검증 도구를 사용하여 스케줄 형식을 반드시 미리 테스트하세요.
- ❌ 이미지 풀링 실패 (ImagePullBackOff) → 지정한 컨테이너 이미지를 노드가 가져오지 못함 → ✅ 이미지 이름, 태그가 정확한지, 그리고 이미지가 저장된 레지스트리에 대한 인증(ImagePullSecrets)이 설정되었는지 확인하세요.
- ❌ 중복 작업 발생으로 인한 리소스 과부하 → 이전 작업이 끝나기 전에 새 작업이 실행되어 메모리 부족 발생 → ✅ concurrencyPolicy: Forbid 옵션을 설정하여 앞선 작업이 종료된 후에만 새 작업이 시작되도록 강제하세요.
- ❌ 타임존 불일치 → 한국 시간 기준으로 설정했으나 UTC 기준으로 작동하여 시간이 어긋남 → ✅ 매니페스트의 spec 하위에 timeZone: “Asia/Seoul”을 명시적으로 작성하세요.
- ❌ 권한 부족 (Forbidden) → 작업 내부에서 API 서버의 다른 리소스를 조회하려 하나 권한이 없음 → ✅ 작업에 할당된 ServiceAccount에 필요한 RBAC(Role-Based Access Control) 권한을 부여하세요.
자주 묻는 질문
Q. 크론잡을 기다리지 않고 지금 즉시 강제로 실행할 수 있나요?
네, 가능해요! kubectl create job --from=cronjob/[크론잡이름] [새로운-잡-이름] 명령어를 사용하면 스케줄과 상관없이 즉시 Job을 생성하여 실행할 수 있어요. 테스트 용도로 아주 유용해요.
Q. 실행된 작업 기록이 너무 많이 쌓여서 서버 용량이 걱정돼요.
그럴 때는 successfulJobsHistoryLimit과 failedJobsHistoryLimit 설정을 사용하세요. 이 값을 낮게 설정하면 쿠버네티스가 오래된 Job과 Pod 기록을 자동으로 삭제하여 저장 공간을 효율적으로 관리해줘요.
Q. 작업이 실패했을 때 자동으로 다시 시도하게 할 수 있나요?
그럼요. Pod의 restartPolicy를 OnFailure로 설정하면, 컨테이너 내부 프로세스가 에러로 종료되었을 때 쿠버네티스가 자동으로 다시 시작을 시도해요.
Q. 크론잡이 실행될 때 특정 환경 변수를 넣어주고 싶어요.
Pod 템플릿 내의 env 항목을 사용하면 돼요. 매니페스트의 container 설정 안에 환경 변수 이름과 값을 정의하면 작업 실행 시 그대로 전달돼요.
Q. 특정 네임스페이스에 있는 크론잡을 관리하려면 어떻게 하나요?
명령어 뒤에 -n [네임스페이스이름] 옵션을 붙여주면 해당 네임스페이스 내의 크론잡을 조회하거나 관리할 수 있어요.
성공적인 자동화를 위한 마지막 점검
지금까지 크론잡(CronJob)의 기초부터 실전 배포, 그리고 문제 해결 방법까지 깊이 있게 살펴보았어요. 자동화는 운영자의 손을 자유롭게 해주지만, 그만큼 정교한 설정과 지속적인 모니터링이 뒷받침되어야 해요. 오늘 배운 내용을 바탕으로 여러분의 인프라에 안전한 자동화 체계를 구축해 보세요.
- 스케줄 형식은 반드시 검증 도구로 미리 확인하기
- 중복 실행 방지를 위해 ConcurrencyPolicy 설정 검토하기
- 타임존 설정을 통해 KST(한국 시간) 기준 맞추기
- 리소스 제한(Requests/Limits)을 설정해 시스템 보호하기
- 성공/실패 기록 한도(History Limit)를 설정해 디스크 관리하기
- 작업 완료 후 로그를 통해 실제 데이터 검증 습관 갖기
이제 여러분이 할 일은 명확해요. 바로 지금, 운영 중인 환경과 유사한 테스트 클러스터에서 방금 배운 크론잡 실전 예제를 직접 타이핑하고 실행해 보는 것이에요. 이론으로 보는 것과 직접 명령어를 입력하며 에러를 만나는 것은 하늘과 땅 차이랍니다.
만약 실습 도중 예상치 못한 에러 메시지를 마주하거나, 설정이 꼬여서 해결하기 어렵다면 혼자 고민하지 마세요. 댓글로 질문을 남겨 주시면 제가 아는 범위 내에서 최대한 상세히 답변해 드릴게요. 여러분의 성공적인 데브옵스(DevOps) 여정을 응원해요!
관련하여 더 깊이 있는 학습을 원하신다면 아래 글들도 함께 읽어보시는 것을 추천해요.
– 쿠버네티스 크론잡 기본 개념 글
– 클러스터 구축 입문 글