WebPiki
tutorial

Cron 표현식 완벽 가이드 — 스케줄 자동화의 기본

Cron 표현식 문법, 예제, 자주 쓰는 패턴을 정리했다. 리눅스 crontab부터 GitHub Actions까지.

서버에서 매일 새벽 3시에 DB 백업을 돌리거나, 매시간 캐시를 갱신하거나, 매주 월요일에 리포트를 보내야 할 때. 이런 반복 작업을 예약하는 데 cron이 쓰인다. 리눅스 시스템 관리의 기본이면서, GitHub Actions, Kubernetes CronJob, AWS EventBridge 등에서도 동일한 표현식을 사용한다.

Cron 표현식 구조

기본 형태는 5개 필드다:

┌───────────── 분 (0-59)
│ ┌───────────── 시 (0-23)
│ │ ┌───────────── 일 (1-31)
│ │ │ ┌───────────── 월 (1-12)
│ │ │ │ ┌───────────── 요일 (0-6, 0=일요일)
│ │ │ │ │
* * * * *

각 필드에 올 수 있는 값:

기호의미예시
*모든 값* * * * * = 매분
숫자특정 값30 9 * * * = 매일 9시 30분
,여러 값0,30 * * * * = 매시 0분과 30분
-범위1-5 = 1~5
/간격*/10 * * * * = 10분마다

자주 쓰는 패턴

시간 기반

* * * * *        매분
*/5 * * * *      5분마다
0 * * * *        매시 정각
0 */2 * * *      2시간마다
30 9 * * *       매일 오전 9시 30분
0 0 * * *        매일 자정
0 9,18 * * *     매일 오전 9시, 오후 6시

요일 기반

0 9 * * 1        매주 월요일 오전 9시
0 9 * * 1-5      평일 오전 9시
0 0 * * 0        매주 일요일 자정
0 18 * * 5       매주 금요일 오후 6시

날짜 기반

0 0 1 * *        매월 1일 자정
0 0 1,15 * *     매월 1일, 15일 자정
0 9 1 1 *        매년 1월 1일 오전 9시
0 0 * * 1#1      매월 첫 번째 월요일 (일부 시스템)

crontab 사용법

리눅스에서 cron 작업을 관리하려면 crontab 명령어를 쓴다.

# 현재 사용자의 cron 작업 목록 보기
crontab -l

# cron 작업 편집
crontab -e

# 특정 사용자의 cron 작업 보기 (root 권한 필요)
sudo crontab -u www-data -l

crontab -e로 열리는 파일에 한 줄에 하나씩 작성한다:

# 매일 새벽 3시에 DB 백업
0 3 * * * /home/user/scripts/backup.sh >> /var/log/backup.log 2>&1

# 10분마다 헬스체크
*/10 * * * * curl -s https://mysite.com/health > /dev/null

>> /var/log/backup.log 2>&1 부분은 출력과 에러를 로그 파일에 기록하라는 뜻이다. 이걸 안 하면 cron이 보내는 메일로 출력이 갈 수 있다.

주의할 점

시간대(timezone). 시스템 시간대를 확인해야 한다. UTC로 설정된 서버에서 0 9 * * *은 한국 시간 오후 6시가 된다.

timedatectl  # 현재 시스템 시간대 확인

환경변수. cron은 사용자의 쉘 환경을 그대로 로드하지 않는다. PATH, HOME 등이 다를 수 있어서, 스크립트에서 절대 경로를 쓰는 게 안전하다.

# crontab 파일 상단에 환경변수 지정 가능
PATH=/usr/local/bin:/usr/bin:/bin

겹침 방지. 작업이 실행 시간보다 오래 걸리면 다음 실행과 겹칠 수 있다. flock으로 잠금을 거는 게 일반적인 해결책이다:

*/5 * * * * flock -n /tmp/myjob.lock /home/user/scripts/slow-job.sh

GitHub Actions에서 cron

GitHub Actions의 schedule 트리거도 cron 표현식을 쓴다.

on:
  schedule:
    - cron: '0 9 * * 1'  # 매주 월요일 9시 (UTC)

주의: GitHub Actions의 시간대는 항상 UTC이고, 정확한 시각에 실행된다는 보장이 없다. 부하가 많을 때는 몇 분~수십 분 딜레이가 발생할 수 있다.

Kubernetes CronJob

쿠버네티스에서도 동일한 표현식을 사용한다:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: db-backup
spec:
  schedule: "0 3 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: my-backup-image
          restartPolicy: OnFailure

concurrencyPolicy 설정으로 이전 작업이 아직 실행 중일 때의 동작을 제어할 수 있다: Allow(동시 실행 허용), Forbid(새 작업 건너뜀), Replace(이전 작업 종료 후 새로 시작).

AWS EventBridge (CloudWatch Events)

AWS는 cron 표현식에 6개 필드를 쓴다 (연도 추가):

cron(분 시 일 월 요일 연도)
cron(0 9 ? * MON-FRI *)  # 평일 9시 UTC

?는 "지정 안 함"이라는 뜻으로, 일과 요일 중 하나에 반드시 써야 한다. 표준 cron과 살짝 문법이 다르니 AWS 문서를 꼭 참고해야 한다.

디버깅

cron 작업이 안 돌 때 확인할 것들:

# cron 서비스가 돌고 있는지
systemctl status cron

# cron 실행 로그
grep CRON /var/log/syslog

# 스크립트 권한 확인 (실행 권한 있어야 함)
chmod +x /home/user/scripts/backup.sh

권한 문제가 제일 많다. 스크립트를 직접 실행하면 되는데 cron에서만 안 되는 경우, 대부분 PATH나 파일 권한 문제다.

표현식이 내가 원하는 대로 동작하는지 미리 확인하고 싶으면 Cron 표현식 생성기를 써보자. 각 필드를 GUI로 설정하면 다음 실행 시간을 미리 보여준다. */15 3-6 * * 1-5 같은 복잡한 표현식도 한눈에 확인할 수 있다.

#cron#자동화#리눅스#DevOps#스케줄링

관련 글