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#스케줄링

Related Posts