cron을 사용할 때는 이렇게 하자
서버를 운영할 때 예정된 시각에 맞춰 사용자의 원하는 명령이나 잡(job)을 수행해주는 cron은 정말 유용하게 사용될 수 있다. 하지만, 간혹 예기치 않게 수행되지 않거나, 우리가 원하는 동작으로 수행되지 않을 때가 있다.
이럴 경우에 미리 대비를 해놓지 않았다면, 편하게 지내려다가 낭패를 볼 수 있다. 때문에 이번 기회를 통해 정리하려고 한다.
0. cron 문법
cron은 문법을 갖추고 있다. 이 문법을 모른다면 사실 상 사용하기 어렵다. 하지만, 사용하다보면 모르기에도 어려운 문법 형태를 갖추고 있기 때문에 잘 기억을 해두었다가 다양한 형식으로 조정해보도록 하자.
시각을 표현하는 형태는 총 5개의 요소로 모두 띄어쓰기로 구분짓고 있다.
첫번째는 minute(분) —> 0~59
두번째는 hour(시간) —> 0~23
세번째는 day(날 혹은 일) —> 1~31
네번째는 month(달 혹은 월) —> 1 ~ 12
다섯번째는 day of the week(요일) —> 0(sun) ~ 6(sat)
로 구성되어 있으며, 각각 옆에 나와있는 숫자로 작성할 수 있다.
모든 요소에 *(별표)로 표시하게 되면, 어떤 요일이든지(day of the week) 매달(month), 매일(day), 매시간(hour), 매분(minute)마다 실행한다는 의미로 해당 시각으로 크론을 작성하게 되면 명령이나 잡을 매분마다 실행하게 된다.
예를 들어, 서버 개발자인 내가 크론을 이용하여 매주 수요일 오전 4시 30분에 '/home/ec2-user/workspace/database-backup.sh' 위치에 있는 데이터베이스 백업 스크립트를 실행시키고자 한다면 아래와 같은 형식으로 작성을 하게 된다.
30 4 * * 3 /home/ec2-user/workspace/database-backup.sh
추가로, 크론 문법에 대해서 간혹 헷갈릴 때가 있다면 아래의 링크에서 작성해보면 어느 시각에 실행될지 미리 예측해준다.
그렇다면, 이제 실무에서 크론을 사용할 때 주의해야 할 점은 무엇인지 알아보도록 하자.
1. 명령의 실행 권한
크론을 이용하여 명령이나 잡을 실행하도록 할 때, 실행하고자 하는 스크립트, 데몬, 프로세스 등에 대한 사용자 실행 권한을 생각해보아야 한다.
예를 들어, 루트 권한으로만 실행할 수 있는 nginx 서버가 주기적으로 종료되는 nginx에 대해서 주기적으로 상태 검사를 하고, 종료되어 있다면 실행하는 스크립트를 크론을 통해 실행한다고 가정해보자. 그렇다면 이 스크립트는 루트 권한으로 실행되어야 한다.
일반 사용자 cron 설정으로 스크립트를 수행하게 되면, permission denied 에러가 발생해 스크립트가 정상적으로 동작하지 않는다. 때문에, 루트가 가지고 있는 cron 설정 파일에서 수정을 해줘야 한다.
반대로, 일반 사용자 권한으로 실행해야 하는 스크립트라면 루트 사용자가 아니라 해당 스크립트를 실행하는 일반 사용자 계정을 크론 설정을 이용해 실행을 시켜야 한다.
# 일반 사용자 크론 설정 파일
crontab -e # 현재 로그인한 사용자 계정의 크론 설정 파일
/var/spool/cron/crontabs/{사용자 이름} # 일반 사용자 별 크론 설정 파일 디렉토리
# 루트 사용자 크론 설정 파일
sudo crontab -e # 루트 사용자 계정의 크론 설정 파일
/etc/crontab # 루트 사용자 계정의 크론 설정 파일
덧붙여 설명하자면, 루트 사용자 계정의 크론 설정 파일에서도 일반 사용자 계정의 명령을 수행할 수 있는 다양한 방법이 있다. 아래의 경우에는 크론 날짜 문법과 실행할 명령어 사이에 명령을 실행할 사용자 계정 이름을 넣은 것이다.
30 4 * * 3 ec2-user /home/ec2-user/workspace/database-backup.sh
단, 위의 설정을 crontab -e 명령어를 사용해서 작성할 경우에는 동작을 제대로 안 하는 경우가 있으니 주의해야 한다. 그런 경우에는 따로 로그인 시에 명령어를 전달받아야 하는 인터랙티브가 없다면 아래와 같이 설정을 해줘도 무방하다.
30 4 * * 3 su ec2-user -c "/home/ec2-user/workspace/database-backup.sh"
2. 서버 시간
크론은 예정된 시각에 따라 수행되는 것이기 때문에, 크론을 실행할 때 서버 시간도 굉장히 많은 영향을 미치게 된다.
예를 들어, 크론 설정을 다 해놓고 나서 다음에 확인 해보니 예정된 시각에 수행이 안 되고 엉뚱한 시각에 수행되는 경우가 종종 있다.
sudo rm /etc/localtime
sudo ln -s /usr/share/zoneinfo/Asia/Seoul /etc/localtime # 한국 시간으로 설정
# cron 데몬 재시작 명령어
sudo service cron restart 혹은 sudo systemctl restart cron.service
# cron 데몬 상태 확인 명령어
sudo service cron status 혹은 sudo systemctl status cron.service
여기서 한가지 유의할 점이라고 한다면 무조건 cron 데몬을 재시작 시켜줘야 서버 시간에 대해서 반영이 된다.