전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]

티스토리 뷰

Onetime job 또는 schedule job의 실행 시간을 예약하는 방법을 설명합니다.

Onetime job 실행 예약

one time job 예약은 'at'라는 명령을 사용하여 예약합니다.

at <실행시간>

실행시간은 아래와 같은 유형으로 지정할 수 있습니다.

  • now+Xmin OR now+xhour : ex) at now+10min, at now+3hour
  • teatime, teatime tomorrow, teamtime + Xday: teatime은 오후 4시임. ex) at teamtime+5day
  • noon, noon tomorrow, noon + Xday: ex) at noon, at noon+3day
  • <시:분> <월> <일> <년도>: ex) at 17:30 July 22 2020

at 명령을 입력하고 Enter를 치면 수행할 명령을 입력할 수 있습니다.

저장하고 job을 등록하려면 CTRL-D를 클릭하십시오. '<EOT>'라고 표시되고 job등록이 완료됩니다.

또는 아래와 같이 Pipe를 이용하여 등록할 수도 있습니다.

<명령> | at <실행시간>

예) echo "Run in 1min" > ret | at now+1min

 

등록된 job 보기: atq OR at -l

등록된 job을 볼때는 atq 또는 at -l 명령을 이용합니다.

queue는 a에서 z까지 있으며 job은 각 queue에 일련번호로 등록됩니다.

위 예는 'a' queue에 21,22,23번으로 job 3개가 등록된것입니다.

특정 queue에 job을 등록할때는 at -q <queue> <실행시간>과 같이 '-q'옵션을 이용하십시오.

 

강제로 job실행하기: aq -c <작업번호>

아래와 같이 환경변수값들이 나오고 끝에 쯤에 실행한 결과를 볼 수 있습니다.

 

job 삭제하기: aqrm <작업번호>
특정 job을 삭제합니다. <작업번호>는 쉼표로 구분하여 여러개 지정할 수 있습니다.

 

Schedule Job 실행 예약

주기적으로 수행되는 job을 등록할 때는 crontab 명령을 이용합니다.

  • job 등록/편집: crontab -e
  • job 목록 보기: crontab -l
  • job 모두 삭제: crontab -r

job등록 방법은 /etc/crontab의 내용을 참조하면 됩니다.

[root@bastion ~]# cat /etc/crontab
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed
패턴 설명 예제
* 매 분, 매 시간, 매일, 매월, 매 요일 수행됨 * * * * * echo "매 분마다 수행"
* 10 * * * echo "매일 10:00 ~ 10:59까지 매분마다 수행"
*/x x시간 주기마다 수행 */5 * * * * echo "매 5분마다 수행"
x,y,z x,y,z 시간에 수행 10,30 * * * * echo "매 10분, 30분에 수행"
x-y x에서 y시간 사이에 수행 */5 9-12 * * 1-5 echo "월~금까지 9시에서 12시 사이에 매 5분마다 수행"

 

crontab -e를 실행하면 기본 에디터로 등록한 job목록이 로딩됩니다.

* 10-11 * * * echo "run every 1 min between 10-11 " >> ~/crontab.txt

 

등록된 job은 물리적으로 /var/spool/cron/${USER}파일에 기록됩니다.

[root@bastion ~]# ls -l /var/spool/cron
total 4
-rw------- 1 root root 124 Jul 17 10:44 root

[root@bastion ~]# cat /var/spool/cron/root
* 10-11 * * * echo "run every 1 min between 10-11 " >> ~/crontab.txt

 

crontab -l 로 job리스트를 볼 수 있고, crontab -r 로 모든 job을 삭제할 수 있습니다.

[root@bastion ~]# crontab -l
* 10-11 * * * echo "run every 1 min between 10-11 " >> ~/crontab.txt
[root@bastion ~]# crontab -r
[root@bastion ~]# crontab -l
no crontab for root

 

crontab 로그: /var/log/cron파일에 기록됩니다.

[root@bastion ~]# tail -f /var/log/cron
Jul 17 10:52:01 bastion crond[1122]: (root) RELOAD (/var/spool/cron/root)
Jul 17 10:52:01 bastion CROND[19877]: (root) CMD (echo "run every 1 min between 10-11 " >> ~/crontab2.txt)
Jul 17 10:52:10 bastion crontab[19890]: (root) BEGIN EDIT (root)
Jul 17 10:52:28 bastion crontab[19890]: (root) REPLACE (root)
Jul 17 10:52:28 bastion crontab[19890]: (root) END EDIT (root)
Jul 17 10:53:01 bastion crond[1122]: (root) RELOAD (/var/spool/cron/root)
Jul 17 10:53:01 bastion CROND[19946]: (root) CMD (echo "run every 1 min between 10-11 " >> ~/crontab.txt)
Jul 17 10:53:04 bastion crontab[19951]: (root) LIST (root)
Jul 17 10:53:10 bastion crontab[19956]: (root) DELETE (root)
Jul 17 10:53:13 bastion crontab[19959]: (root) LIST (root)

 

System schedule job 관리

지금까지는 user job을 1회 수행 또는 반복수행하기 위해 어떻게 등록하는지 배웠습니다.

이제는 System에서 사용하는 schedule job을 어떻게 관리하는지 배워보겠습니다.

system job의 shell script는 수행 주기에 따라 /etc/houly, /etc/cron.daily, /etc/cron.weekly, /etc/cron.monthly 등의 디렉토리 하위에 있습니다.

그리고 실제 그 shell script들이 수행되게 하려면 /etc/cron.d 디렉토리 하위에 호출하는 crontab 파일을 만들어야 합니다.

기본으로는 아래와 같이 0hourly라는 파일만 있습니다.

[root@bastion etc]# cd /etc/cron.d
[root@bastion cron.d]# ls -al
total 24
drwxr-xr-x.  2 root root  4096 Jul 17 14:56 .
drwxr-xr-x. 97 root root 12288 Jul 20 10:04 ..
-rw-r--r--.  1 root root   128 Aug  9  2019 0hourly

[root@bastion cron.d]# cat 0hourly
# Run the hourly jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
01 * * * * root run-parts /etc/cron.hourly

위와 같이 필요한 환경변수를 정의하고 crontab으로 주기(매 1시간), 실행user(root), 실행명령(run-parts /etc/cron.hourly)을 정의합니다.

System job의 실행 보장 방법: anacrontab

System job은 어떠한 경우에도 반드시 실행되어야 합니다. 예를 들어 1일 배치 프로그램의 실행 시점에 갑자기 server가 재시작되었다고 하더라도 재시작 후에는 그 프로그램이 실행되어야 합니다.

이를 가능하게 하는것이 anacrontab입니다.

/etc/anacrontab 파일에 아래와 같이 필요한 환경 변수와 수행주기, 실행 전 대기 시간, 이름, 명령들을 등록합니다.

[root@bastion cron.d]# cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron

# See anacron(8) and anacrontab(5) for details.

SHELL=/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root
# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=45
# the jobs will be started during the following hours only
START_HOURS_RANGE=3-22

#period in days   delay in minutes   job-identifier   command
1	5	cron.daily		nice run-parts /etc/cron.daily
7	25	cron.weekly		nice run-parts /etc/cron.weekly
@monthly 45	cron.monthly		nice run-parts /etc/cron.monthly

그렇다면 crond (cron daemon)는 어떻게 각 명령이 실행되었는지 알 수 있을까요?

/var/spool/anacron디렉토리로 이동하여 그 안의 파일들을 보십시오. 아래와 같이 각 주기별 파일에 마지막으로 실행된 시간이 기록됩니다. crond는 이 시간을 확인하여 실행여부를 판단합니다.

[root@bastion anacron]# cd /var/spool/anacron
[root@bastion anacron]# ls -l
total 12
-rw-------. 1 root root 9 Jul 20 03:53 cron.daily
-rw-------. 1 root root 9 Jul  3 03:20 cron.monthly
-rw-------. 1 root root 9 Jul 15 03:33 cron.weekly
[root@bastion anacron]# cat cron.daily
20200720

cron job 수행 로그는 user job과 동일하게 /var/log/cron파일에 기록됩니다.

 

System job 등록 테스트

자 그럼 Red Hat System Administration II: 반복문, 조건문, 재귀식 사용에서 작성한 fixtz라는 프로그램을 system cron job으로 등록하는걸 테스트해 보겠습니다.

fixtz는 /root/bin 디렉토리에 있습니다.  없다면 위 링크의 글을 참조하여 만드십시오.

[root@bastion bin]# which fixtz
/root/bin/fixtz

우리는 이 프로그램을 매 2분마다 수행할겁니다. /etc디렉토리 밑으로 이동하고, 'cron.min'이라는 디렉토리를 만듭니다.

그리고 그 디렉토리에 fixtz를 호출하는 script를 작성합니다.

[root@bastion etc]# cd /etc
[root@bastion etc]# mkdir -p /etc/cron.min
[root@bastion etc]# cd cron.min
[root@bastion etc]# vim tz

#!/bin/bash
fixtz America/Toronto
fixtz
exit 0

 

이제 /etc/cron.d로 이동한 후 /etc/cron.min 디렉토리의 프로그램을 schdule job으로 등록할 0min이라는 파일을 만듭니다.

PATH에 fixtz를 실행하기 위해 /root/bin을 추가해줘야 합니다.

[root@bastion cron.min]# cd /etc/cron.d
[root@bastion cron.d]# vim 0min
# Run the every 2 min jobs
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
MAILTO=root
*/2 * * * * root run-parts /etc/cron.min

tail -f /var/log/cron 명령으로 2분 마다 tz명령이 정상적으로 실행되는지 확인합니다.

[root@bastion cron.d]# tail -f /var/log/cron
Jul 20 10:32:02 bastion run-parts(/etc/cron.min)[26757]: finished tz
Jul 20 10:34:01 bastion CROND[26911]: (root) CMD (run-parts /etc/cron.min)
Jul 20 10:34:01 bastion run-parts(/etc/cron.min)[26911]: starting tz
Jul 20 10:34:01 bastion run-parts(/etc/cron.min)[26932]: finished tz
Jul 20 10:36:01 bastion CROND[27090]: (root) CMD (run-parts /etc/cron.min)
Jul 20 10:36:01 bastion run-parts(/etc/cron.min)[27090]: starting tz
Jul 20 10:36:01 bastion run-parts(/etc/cron.min)[27111]: finished tz

 

systemd timer

systemd timer는 systemd(system daemon)의 실행주기를 지정하는 기능입니다.

각 system daemon마다 설정하는 파일과 항목은 다릅니다. 아래는 sysstat라는 패키지의 예입니다.

sysstat는 /usr/lib/systemd/system/sysstat-collect.timer라는 파일의 [Timer]항목에서 지정합니다.

즉 sysstat는 매 10분마다 수행됩니다.

sh-4.4# yum install -y sysstat
....
sh-4.4# cd /usr/lib/systemd/system
sh-4.4# ls -al sysstat-*
-rw-r--r-- 1 root root 389 May 14  2019 sysstat-collect.service
-rw-r--r-- 1 root root 325 May 14  2019 sysstat-collect.timer
-rw-r--r-- 1 root root 369 May 14  2019 sysstat-summary.service
-rw-r--r-- 1 root root 356 May 14  2019 sysstat-summary.timer
sh-4.4# vi sysstat-collect.timer

...
[Unit]
Description=Run system activity accounting tool every 10 minutes

[Timer]
OnCalendar=*:00/10

[Install]
WantedBy=sysstat.service

설정을 변경해 봅시다.

설정을 변경할 때는 반드시 /usr/lib/systemd/system하위의 파일을 /etc/systemd/system디렉토리로 복사한 후 수정하여야 합니다.

왜냐하면 systemd가 설정파일을 읽는 우선순위가 /etc/*, /run/*, /usr/lib/* 순서이기 때문입니다. 패키지 설치시의 설정은 /usr/lib/systemd/system에 그대로 두고, /etc/systemd/system에서 재정의하는 방법을 쓰는것이 좋습니다.

변경 후 systemctl daemon-reload명령을 이용하여 systemd에 변경 사항을 알립니다. 이 명령은 systemd 관리자 설정을 다시 로드합니다.

# cp /usr/lib/systemd/stsstat-collect.timer /etc/systemd/system
# cd /etc/systemd/system
# vi sysstat-collect.timer
...
[Timer]
OnCalendar=*:00/2
...

# systemctl daemon-reload
# systemctl enable --now sysstat-collect.timer

/var/log/sa디렉토리에 시스템활동 데이터가 수집됨
# watch ls -al /var/log/sa
# 

 

임시 파일 관리

systemd로 구동되는 서비스들은 각자 임시 디렉토리와 파일들을 사용합니다. 그 임시 디렉토리와 파일을 생성 및 정리해주는 서비스가 systemd-tmpfiles-setup와 systemd-tmpfiles-clean입니다. 

systemd가 OS 부팅 시 제일 먼저 실행하는 서비스는 systemd-tmpfiles-setup입니다.

systemd-tmpfiles-setup은 아래 디렉토리에서 각 서비스에서 사용하는 임시 디렉토리와 파일들의 설정 정보를 읽습니다.

/etc/tmpfiles.d/*.conf, /run/tmpfiles.d/*.conf, /usr/lib/tmpfiles.d/*.conf

동일한 파일이 있으면 /etc -> /run -> /usr/lib의 우선순위대로 설정 정보를 읽습니다.

그리고 systemd-tmpfiles-clean서비스는 /etc/systemd/system/systemd-tmpfiles-clean.timer(없으면 /usr/lib/tmpfiles.d/systemd-tmpfiles-clean.timer)에 정의된 주기에 따라 실행됩니다.

실행 시 각 임시 디렉토리와 파일을 생성 또는 정리하는 옵션은 systemd-tmpfiles-setup 서비스가 읽은 정보를 이용합니다.

임시파일 설정

/etc/tmpfiles.d, /run/tmpfiles.d, /usr/lib/tmpfiles.d 디렉토리 하위에는 각 서비스별 임시파일 설정이 있습니다.

예를 들어 openssh.conf와 systemd.conf의 내용은 아래와 같습니다.

각 column은 Type,  경로, UGO권한, user, group, Age, Arguments로 구성됩니다. systemd-tmpfiles --clean이 실행될때 Age에 지정한 기간동안 접근이 없으면 그 디렉토리나 파일은 삭제됩니다. 

자세한 것은 man tmpfiles.d를 참조하십시오.

몇 가지 예제 및 설명은 다음과 같습니다.

d /run/systemd/seats 0755 root root -

파일과 디렉터리를 만들 경우 사용자 root와 그룹 root가 소유하는 디렉터리 /run/systemd/ seats(없을 경우)를 만들고 권한을 rwxr-xr-x로 설정합니다. 이 디렉터리는 자동으로 삭제되지 않습니다. 즉, systemd-tmpfiles --clean 수행 시 지워지지 않습니다. 

D /home/student 0700 student student 1d

/home/student 디렉터리가 없는 경우 해당 디렉터리를 만듭니다. 해당 디렉터리가 있는 경우는 모든 내용을 지웁니다. systemd-tmpfiles --clean을 실행할 경우 1일 이상 액세스, 변경 또는 수정하지 않은 모든 파일을 제거합니다.

L /run/fstablink - root root - /etc/fstab

/etc/fstab을 가리키는 심볼릭 링크 /run/fstablink를 만듭니다. systemd-tmpfiles --clean 수행 시 자동으로 지워지지 않습니다. 

 

임시파일 정리 실행 주기 설정

/etc/systemd/system/systemd-tmpfiles-clean.timer (없으면 /usr/lib/systemd/system/systemd-tmpfiles-clean.timer)파일의 내용은 아래와 같습니다.

OnBootSec는 OS부팅 시 systemd-tmpfiles-clean서비스가 시작될 대기 시간이고, OnUnitActiveSec가 실행주기입니다.

위 설정을 변경하려면 아래와 같이 작업하십시오.

  • systemd-tmpfiles-clean.timer파일을 /etc/systemd/system으로 복사
  • 설정 내용 변경
  • systemctl daemon-reload 수행하여 변경 내용 system daemon에 알림
  • systemctl enable --now systemd-tmpfiles-clean.timer 수행

 

수동으로 임시파일 정리

systemd-tmpfiles --clean 명령을 수행하면 됩니다.

systemd-tmpfiles-setup이 수집한 각 서비스의 임시디렉토리/파일 설정정보를 참조하여 정리를 수행합니다.

 

 

댓글

전자책 출간 알림 [마이크로서비스패턴 쉽게 개발하기]