크론탭(Crontab)으로 서버 작업 자동화하기
서버를 운영하다 보면 매일 반복해야 하는 작업들이 생깁니다. 로그 파일을 정리하거나, 데이터베이스를 백업하거나, SSL 인증서 갱신을 확인하거나, 특정 시간에 스크립트를 돌리는 일들입니다. 이런 걸 매번 직접 접속해서 수동으로 실행하면 번거롭기도 하고 깜빡하는 날이 반드시 생깁니다. 리눅스에서는 크론(Cron)이라는 도구가 이런 반복 작업을 자동으로 처리해줍니다. 이번 글에서는 크론탭이 무엇인지, 어떻게 설정하는지, 실무에서 어떤 식으로 활용하는지를 정리해보겠습니다.
크론이란 무엇인가
크론은 리눅스에 기본으로 내장되어 있는 작업 스케줄러입니다. 지정한 시간에 지정한 명령어를 자동으로 실행해줍니다. 별도로 설치할 필요 없이 대부분의 리눅스 배포판에 이미 들어가 있습니다.
크론탭(Crontab)은 크론 테이블(Cron Table)의 줄임말이고, 어떤 작업을 언제 실행할지 적어둔 설정 파일입니다. 사용자마다 자기만의 크론탭을 가질 수 있고, 시스템 전체에 적용되는 크론탭도 따로 있습니다.
크론 데몬은 시스템이 켜져 있는 동안 백그라운드에서 항상 돌고 있으면서, 매분마다 크론탭을 확인합니다. 현재 시간과 일치하는 작업이 있으면 실행하고, 없으면 넘어갑니다. 서버가 재부팅되어도 크론 데몬은 자동으로 다시 시작됩니다.
크론탭 기본 사용법
크론탭을 열려면 터미널에서 다음 명령어를 입력합니다.
crontab -e
처음 실행하면 어떤 편집기를 사용할지 물어봅니다. nano가 익숙하다면 nano를 선택하면 됩니다. 편집기가 열리면 여기에 작업 스케줄을 한 줄씩 추가하면 됩니다.
현재 등록된 크론탭을 확인하고 싶으면 이렇게 합니다.
crontab -l
크론탭을 전부 삭제하고 싶으면 이렇게 합니다. 주의해서 사용해야 합니다.
crontab -r
다른 사용자의 크론탭을 편집하려면 sudo와 -u 옵션을 사용합니다.
sudo crontab -u www-data -e
크론탭 시간 형식 이해하기
크론탭에서 가장 중요한 건 시간 형식입니다. 한 줄에 하나의 작업을 쓰는데, 형식은 이렇습니다.
분 시 일 월 요일 실행할명령어
각 자리에 들어갈 수 있는 값의 범위는 이렇습니다. 분은 0부터 59까지, 시는 0부터 23까지, 일은 1부터 31까지, 월은 1부터 12까지, 요일은 0부터 7까지인데 0과 7이 둘 다 일요일입니다.
별표는 “매번”이라는 뜻입니다. 해당 자리에 별표를 넣으면 그 단위의 모든 값에 해당된다는 의미입니다.
예시를 보면 바로 감이 옵니다.
0 3 * * * /home/ubuntu/backup.sh
이건 매일 새벽 3시 정각에 backup.sh를 실행하라는 뜻입니다. 분이 0이고 시가 3이고, 일 월 요일이 전부 별표이니까 매일 반복됩니다.
30 2 * * 0 /home/ubuntu/weekly-cleanup.sh
이건 매주 일요일 새벽 2시 30분에 실행하라는 뜻입니다. 요일 자리에 0이 들어갔으니 일요일입니다.
*/10 * * * * /home/ubuntu/check-server.sh
슬래시는 간격을 의미합니다. */10은 10분마다라는 뜻입니다. 즉 매 10분마다 서버 상태를 확인하는 스크립트를 실행합니다.
0 9-18 * * 1-5 /home/ubuntu/business-report.sh
하이픈은 범위를 나타냅니다. 시 자리에 9-18이면 오전 9시부터 오후 6시까지이고, 요일 자리에 1-5면 월요일부터 금요일까지입니다. 평일 업무시간에만 매시 정각에 실행되는 설정입니다.
0 0 1,15 * * /home/ubuntu/biweekly-task.sh
쉼표는 특정 값 여러 개를 지정할 때 씁니다. 일 자리에 1,15이면 매월 1일과 15일 자정에 실행합니다.
실무에서 자주 쓰는 크론탭 예시
데이터베이스 백업은 크론탭으로 가장 많이 자동화하는 작업입니다. MySQL 데이터베이스를 매일 새벽 4시에 백업하는 설정은 이렇습니다.
0 4 * * * mysqldump -u root -p'비밀번호' mydb > /backup/mydb_$(date +\%Y\%m\%d).sql
date 명령어를 넣으면 파일 이름에 날짜가 들어가서 매일 다른 파일로 저장됩니다. 크론탭에서 퍼센트 기호는 특수 문자로 취급되기 때문에 백슬래시로 이스케이프해야 합니다. 이걸 모르면 명령어가 제대로 동작하지 않아서 한참 헤매는 경우가 있습니다.
오래된 로그 파일을 정리하는 것도 흔합니다. 30일 이상 된 로그 파일을 매주 일요일에 삭제하는 설정입니다.
0 5 * * 0 find /var/log/myapp/ -name "*.log" -mtime +30 -delete
find 명령어의 -mtime +30은 수정된 지 30일이 지난 파일을 찾는다는 뜻이고, -delete는 찾은 파일을 삭제합니다.
서버가 정상적으로 돌고 있는지 주기적으로 확인하는 헬스체크도 자주 설정합니다.
*/5 * * * * curl -s -o /dev/null -w "%{http_code}" https://todayfunplay.com | grep -q "200" || echo "사이트 다운" >> /var/log/healthcheck.log
5분마다 사이트에 요청을 보내서 응답 코드가 200이 아니면 로그에 기록하는 설정입니다. 간단한 모니터링 용도로 쓸 수 있습니다.
이전 글에서 다뤘던 Let’s Encrypt 인증서 자동 갱신도 크론탭으로 설정합니다.
0 3 * * * certbot renew --quiet
매일 새벽 3시에 인증서 만료를 확인하고 필요하면 갱신합니다.
크론탭 작성 시 주의할 점
크론탭에서 가장 많이 실수하는 부분이 경로 문제입니다. 크론은 사용자가 직접 로그인한 셸 환경과 다른 환경에서 실행됩니다. 터미널에서는 잘 되는 명령어가 크론에서는 안 되는 경우가 흔한데, 환경 변수와 PATH가 다르기 때문입니다.
해결 방법은 간단합니다. 크론탭에서 명령어를 쓸 때는 항상 절대 경로를 사용하면 됩니다.
# 이렇게 하면 안 될 수 있음
* * * * * node /home/ubuntu/app.js
# 이렇게 절대 경로를 써야 확실함
* * * * * /usr/bin/node /home/ubuntu/app.js
명령어의 절대 경로를 모르겠으면 which 명령어로 확인할 수 있습니다.
which node
/usr/bin/node
스크립트 파일을 실행할 때는 실행 권한이 있는지도 확인해야 합니다. 이전 글에서 다뤘던 chmod로 실행 권한을 줘야 합니다.
chmod +x /home/ubuntu/backup.sh
크론탭에서 퍼센트 기호를 쓸 때는 반드시 백슬래시로 이스케이프해야 한다는 것도 중요합니다. 크론에서 퍼센트 기호는 줄바꿈으로 해석되기 때문에 이스케이프하지 않으면 명령어가 잘려서 실행됩니다.
크론 실행 결과 확인하기
크론이 제대로 동작하는지 확인하는 방법을 모르면 문제가 생겨도 알 수가 없습니다.
가장 기본적인 방법은 시스템 로그를 확인하는 겁니다.
grep CRON /var/log/syslog
이 명령어를 치면 크론이 실행한 작업의 로그가 나옵니다. 어떤 사용자의 어떤 명령어가 언제 실행됐는지 확인할 수 있습니다.
크론 작업의 출력 결과를 파일로 저장하고 싶으면 리다이렉션을 사용합니다.
0 3 * * * /home/ubuntu/backup.sh >> /var/log/backup.log 2>&1
는 출력을 파일에 추가하는 것이고, 2>&1은 에러 출력도 같은 파일에 저장하라는 뜻입니다. 이렇게 설정해두면 백업 스크립트의 실행 결과와 에러 메시지를 전부 로그 파일에서 확인할 수 있습니다.
반대로 출력이 필요 없으면 /dev/null로 보내서 버릴 수 있습니다.
0 3 * * * /home/ubuntu/backup.sh > /dev/null 2>&1
크론은 기본적으로 작업의 출력이 있으면 시스템 메일로 보냅니다. 메일 설정이 안 되어 있으면 “You have new mail”이라는 메시지가 계속 쌓일 수 있는데, 위처럼 출력을 /dev/null로 보내면 이 문제가 해결됩니다.
시스템 크론과 사용자 크론의 차이
지금까지 다룬 건 사용자 크론탭입니다. crontab -e로 편집하는 것이고, 해당 사용자의 권한으로 실행됩니다.
시스템 전체에 적용되는 크론 설정은 /etc/crontab 파일에 있습니다. 이 파일은 사용자 크론탭과 형식이 약간 다릅니다.
0 3 * * * root /home/ubuntu/backup.sh
시간 형식과 명령어 사이에 실행할 사용자 이름이 들어갑니다. 시스템 크론탭에서는 어떤 사용자 권한으로 실행할지 직접 지정해야 합니다.
/etc/cron.d/ 디렉토리에 개별 파일로 넣을 수도 있고, /etc/cron.daily/, /etc/cron.weekly/, /etc/cron.monthly/ 디렉토리에 스크립트를 넣으면 이름 그대로 매일, 매주, 매월 자동 실행됩니다. 이 디렉토리들은 시간을 세밀하게 지정할 필요 없이 스크립트만 넣으면 되기 때문에 편합니다.
크론 대신 사용할 수 있는 것들
크론은 단순한 반복 작업에는 충분하지만 한계가 있습니다. 작업 간 의존 관계를 설정하거나, 실패했을 때 재시도 로직을 넣거나, 실행 상태를 웹에서 모니터링하는 건 크론만으로는 어렵습니다.
이런 경우에는 systemd timer를 사용하는 방법이 있습니다. systemd는 리눅스의 서비스 관리 도구인데 타이머 기능도 가지고 있습니다. 크론보다 설정이 복잡하지만 서비스와 연동이 쉽고 로그 관리가 편합니다.
더 복잡한 작업 스케줄링이 필요하면 Jenkins, Airflow 같은 전문 도구를 쓰기도 합니다. 하지만 서버 한두 대를 운영하면서 기본적인 자동화를 하는 수준이라면 크론탭만으로 충분합니다.
마무리
크론탭은 리눅스 서버 운영에서 가장 기본적이면서도 실용적인 도구입니다. 시간 형식 다섯 자리와 실행할 명령어 한 줄이면 어떤 작업이든 자동화할 수 있습니다. 주의할 점은 절대 경로를 사용하는 것, 실행 권한을 확인하는 것, 로그를 남겨두는 것 정도입니다. 서버를 운영하기 시작했다면 백업과 로그 정리부터 크론탭으로 자동화해보는 걸 추천합니다. 다음 글에서는 서버 상태를 실시간으로 확인할 수 있는 모니터링 도구들을 비교해보겠습니다.
Leave a Reply