at, cron 및 systemd 타이머를 이용한 작업 스케줄링

LinuxBeginner
지금 연습하기

소개

Linux 관리자는 여러 가지 방법으로 작업을 예약합니다. at 명령은 일회성 작업을 예약하고, cron 은 간단한 시간 필드를 사용하여 반복적인 작업을 예약하며, systemd 타이머는 systemd 의 의존성 및 로깅 모델을 사용하여 systemd 서비스를 예약합니다.

이 실습에서는 하나의 명령 스크립트를 만들고 세 가지 방식으로 예약해 봅니다. 스케줄러 서비스를 확인하고, 일회성 at 작업을 큐에 추가하며, cron 드롭인 파일을 구성하고, systemd 서비스와 타이머 쌍을 생성한 뒤, 타이머가 실행하는 서비스를 수동으로 테스트합니다.

스케줄러 확인 및 작업 스크립트 생성

이 단계에서는 스케줄러 서비스가 실행 중인지 확인하고, 모든 예약된 작업에서 호출할 작은 스크립트를 하나 생성합니다.

프로젝트 디렉토리로 이동합니다.

cd /home/labex/project

일회성 작업 데몬과 cron 데몬을 확인합니다. systemctl is-active는 서비스가 현재 실행 중일 때 active를 출력합니다.

systemctl is-active atd crond

기존 systemd 타이머를 나열합니다. 출력 결과에는 다음 실행 시간, 타이머 유닛, 그리고 활성화하는 서비스 유닛이 표시됩니다.

systemctl list-timers --all --no-pager | sed -n '1,10p'

로그 파일에 타임스탬프가 찍힌 줄을 추가하는 스크립트를 생성합니다. 첫 번째 인수인 $1은 어떤 스케줄러가 스크립트를 실행했는지 식별하는 레이블이 됩니다.

cat > /home/labex/project/scheduled-note.sh <<'EOF'
#!/bin/bash
echo "$(date '+%F %T') $1" >> /home/labex/project/schedule-events.log
EOF

스크립트를 실행 가능하게 만듭니다.

chmod 755 /home/labex/project/scheduled-note.sh

스크립트를 수동으로 한 번 실행합니다.

/home/labex/project/scheduled-note.sh manual-run
tail -n 1 /home/labex/project/schedule-events.log

로그 줄은 manual-run으로 끝나야 합니다.

일회성 at 작업 큐에 추가

이 단계에서는 at을 사용하여 일회성 작업을 예약합니다. 이는 임시 유지 관리 작업과 같이 미래의 특정 시점에 한 번만 수행해야 하는 작업에 유용합니다.

지금부터 2 시간 후에 스크립트가 실행되도록 예약합니다. 실행할 명령은 at으로 파이프됩니다.

echo "/home/labex/project/scheduled-note.sh at-job" | at now + 2 hours

큐에 대기 중인 작업을 나열합니다.

atq

첫 번째 atq 줄에서 작업 ID 를 저장합니다. 작업 ID 는 출력의 첫 번째 필드입니다.

job_id="$(atq | awk 'NR==1 {print $1}')"
echo "$job_id" > /home/labex/project/at-job.id
cat /home/labex/project/at-job.id

대기 중인 작업 내용을 확인합니다. at -c는 생성된 작업 스크립트를 출력하며, 마지막 줄에는 예약한 명령이 포함되어 있어야 합니다.

at -c "$job_id" | tail -n 12

cron 드롭인 파일 구성

이 단계에서는 /etc/cron.d에 파일을 생성하여 반복적인 cron 작업을 구성합니다. 이 디렉토리의 파일에는 사용자 필드가 포함되어 있어 시스템이 어떤 계정으로 명령을 실행해야 하는지 알 수 있습니다.

labex 사용자로 매분 스크립트를 실행하는 cron 파일을 생성합니다. PATH 줄은 cron 이 명령을 찾을 수 있는 예측 가능한 경로를 제공합니다.

sudo tee /etc/cron.d/rhcsa-schedule-demo >/dev/null <<'EOF'
SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
* * * * * labex /home/labex/project/scheduled-note.sh cron-job
EOF

파일 모드를 644로 설정합니다. cron 파일은 읽을 수 있어야 하며 일반 사용자가 수정할 수 없어야 합니다.

sudo chmod 644 /etc/cron.d/rhcsa-schedule-demo

crond를 다시 로드하여 파일을 즉시 인식하도록 합니다.

sudo systemctl reload crond

생성한 파일을 확인합니다.

sudo cat /etc/cron.d/rhcsa-schedule-demo

스케줄 필드 * * * * *는 매분을 의미합니다.

systemd 서비스 및 타이머 생성

이 단계에서는 systemd 서비스와 이를 활성화하는 타이머를 생성합니다. 타이머는 명령을 직접 실행하지 않고 서비스 유닛을 시작합니다.

시스템 서비스는 사용자의 작업 디렉토리가 아닌 시스템 실행 경로에서 명령을 실행해야 합니다. 스크립트 복사본을 /usr/local/bin 아래에 설치합니다.

sudo install -m 755 /home/labex/project/scheduled-note.sh /usr/local/bin/rhcsa-scheduled-note
sudo restorecon /usr/local/bin/rhcsa-scheduled-note 2>/dev/null || true
ls -l /usr/local/bin/rhcsa-scheduled-note

서비스 유닛을 생성합니다. Type=oneshot은 실행 후 종료되는 명령에 적합합니다.

sudo tee /etc/systemd/system/rhcsa-schedule-demo.service >/dev/null <<'EOF'
[Unit]
Description=Write RHCSA schedule demo entry

[Service]
Type=oneshot
User=labex
ExecStart=/usr/local/bin/rhcsa-scheduled-note timer-job
EOF

타이머 유닛을 생성합니다. OnBootSec=2min은 부팅 후 첫 실행을 예약하고, OnUnitActiveSec=5min은 이전 활성화 시점을 기준으로 이후 실행을 예약합니다.

sudo tee /etc/systemd/system/rhcsa-schedule-demo.timer >/dev/null <<'EOF'
[Unit]
Description=Run RHCSA schedule demo periodically

[Timer]
OnBootSec=2min
OnUnitActiveSec=5min
Unit=rhcsa-schedule-demo.service

[Install]
WantedBy=timers.target
EOF

systemd 를 다시 로드하고, 부팅 시 타이머가 활성화되도록 설정한 뒤 즉시 시작합니다. enable과 start를 분리하면 어떤 명령이 타이머를 영구적으로 만들고 어떤 명령이 즉시 활성화하는지 명확해집니다.

sudo systemctl daemon-reload
sudo systemctl enable rhcsa-schedule-demo.timer
sudo systemctl start rhcsa-schedule-demo.timer

타이머를 확인합니다.

systemctl list-timers rhcsa-schedule-demo.timer --all --no-pager

타이머가 목록에 나타나야 하며, rhcsa-schedule-demo.service를 활성화해야 합니다.

타이머 서비스 테스트 및 at 작업 제거

이 단계에서는 타이머가 사용하는 서비스를 수동으로 시작합니다. 이는 다음 예약된 타이머 활성화를 기다리지 않고 즉시 명령을 검증합니다. 또한 연습용으로 생성했던 대기 중인 at 작업을 제거합니다.

서비스를 수동으로 시작합니다.

sudo systemctl start rhcsa-schedule-demo.service

로그를 확인합니다.

tail -n 5 /home/labex/project/schedule-events.log

한 줄이 timer-job으로 끝나야 합니다.

이전에 저장한 작업 ID 를 사용하여 대기 중인 at 작업을 제거합니다.

job_id="$(cat /home/labex/project/at-job.id)"
atrm "$job_id"

작업이 더 이상 큐에 없는지 확인합니다.

atq

요약

세 가지 스케줄링 방법을 실습했습니다. atd, crond 및 systemd 타이머를 확인하고, 재사용 가능한 예약 명령 스크립트를 만들었으며, 일회성 at 작업을 큐에 추가 및 확인하고, 반복적인 cron 드롭인 파일을 구성했습니다. 또한 /usr/local/bin 아래에 서비스 안전 명령을 설치하고, systemd 서비스와 타이머 쌍을 생성했으며, 타이머 서비스를 수동으로 테스트하고 임시 at 작업을 제거했습니다.