linux crontab으로 github 소스 코드 백업 & S3 업로드 스케쥴링

Jiumn·2023년 6월 13일
0

개요

리눅스 명령어라고는 ls, cd, mkdir, rm 밖에 몰랐던 사람이 crontab으로 github 소스코드 백업 스케쥴링을 구현하게 된 과정을 소개한다.

linux crontab으로 소스코드 백업 스케쥴링

목표는 정해진 주기마다 자동으로 master branch를 git pull하고 해당 소스코드를 압축한 후 S3 버킷에 업로드하는 것이다.

<작업 순서>
1. 쉘 스크립트 작성 (master branch git pull, 해당 소스 코드 압축 파일 생성, S3에 압축 파일 업로드)
2. crontab 등록 (해당 작업을 반복하도록)

1. shell script 작성

리눅스에서 특정 주기에 따라 작업을 반복하려면 crontab에 시간과 명령어를 등록해야 한다. crontab에 명령어를 바로 작성해도 되지만 내용이 길어질 경우 shell script를 작성해서 해당 파일을 실행하게 한다.

shell script는 .sh 확장자로 된 파일로 shell 명령어들을 모아서 만든 배치(batch) 파일이다. 쉘 스크립트, 말 그대로 쉘이 읽어서 실행해주는 파일인 것이다. 쉘에는 bash, ksh, csh 등 다양한 종류가 있는데 어떤 쉘로 실행시킬지 결정해주기 위해 쉘 스크립트 맨 위에 선언해줘야 한다. 나는 bash 쉘로 작성했다.

#!/bin/sh

맨 앞에 있는 # 때문에 주석으로 보고 대충 넘어갈 수도 있지만 빠뜨리면 실행이 안된다.

맨 윗 줄에 선언하고 그 아래에 스크립트를 작성해주면 된다.

문제: 리눅스 날짜 시간 포맷이 파일명으로 표시되지 않음

날짜와 시간을 파일 제목으로 업로드하기 위해 리눅스 날짜 시간 포맷을 사용했다.

NOWDATE=`date +%Y-%m-%d %H:%M:%S`

이렇게 입력했더니 S3에 파일명이 제대로 업로드되지 않는 문제가 발생했다.

원인: s3 객체 키 이름으로 사용할 수 없는 문자를 포함함

처음에는 리눅스에서 변수를 표현하는 문법에 문제가 있나 싶어서 날짜와 시간 사이에 이스케이프 처리를 하거나 공백을 지우기도 해보고 포맷을 따옴표가 아니라 $() 형태로 입력해보기도 했다. 계속 해결되지 않자 리눅스 문법이 잘못된 게 아니라 S3에 업로드됐을 때 문제가 발생하는 것 같다는 추측을 하고 AWS S3 사용 설명서 페이지를 찾아 봤다. 해당 매뉴얼에 S3 객체 키 이름으로 사용 가능한 문자의 목록이 있다.

해결: S3 객체 키 명명 지침을 지켜서 네이밍

특별한 처리가 필요한 문자와 피해야 하는 문자에 백슬래쉬(\)와 콜론(:)이 있었다. 백슬래쉬, 공백, 콜론을 모두 지우자 정상적으로 업로드가 됐다! S3 객체 키 명명 지침을 꼭 한번 읽어보자. 의외로 많은 제한이 있다.


2. crontab 작성

쉘 스크립트를 작성했다면 다음으로 crontab 파일을 열어서 작성한다.

crontab 에디터 열기

crontab -e

이 명령어를 입력하면 crontab 작성 화면이 뜨는데 굉장히 긴 주석이 포함되어 있다. 주석에는 crontab 사용 방법이 나와 있다.

크론 표현식

# 순서대로 '분 시 일 월 요일'을 의미
* * * * * [실행 경로]

별이 다섯개인 크론탭은 각 위치별로 실행되는 주기를 표현한다.

이렇게 다섯 가지를 나타내는데 각 자리를 숫자로 표현한다.

문제 2: service crontab start(restart) 입력 시 ubuntu 패스워드 입력 요구

많은 블로그에서 크론탭을 작성하고 나면 다음 명령어로 크론탭을 재실행시켜줘야 한다고 알려준다.

service crontab start
(또는)
service crontab restart

당연히 따라쳤는데 갑자기 ubuntu 패스워드를 요구하는 창이 나타났다.
(참고로 나는 puTTY로 ssh ppk 키를 등록하는 방식으로 접속했다.)

해결: root 계정으로 전환

이미 계정에 접속을 했는데도 불구하고 패스워드를 물어본다면 root 계정으로 사용자를 변경해준다.

# ubuntu → root 전환 시
sudo su

# root → ubuntu 전환 시
su -

sudo는 substitute user(다른 사용자)로 변환해주는 기능이다. (애초에는 super user do의 줄임말이었는데 이후 슈퍼 유저가 아닌 다른 사용자 권한을 부여할 수도 있게 돼서 의미가 조금 바뀌었다고 한다.)

sudo su 뒤에 전환을 원하는 계정을 써주면 되는데 비워두면 디폴트로 root 계정으로 전환된다. ubuntu로 돌아올 때는 su - 를 입력한다.

참고: service start 명령어 입력 필요 없음 → daemon에서 실행

service cron start를 입력하고도 cron이 정상적으로 실행이 되지 않는 것처럼 보였다. cron이 daemon으로 등록되어 있기 때문에 따로 시작 명령어를 작성하지 않아도 변경사항을 저장하면 자동으로 백그라운드에서 실행되는 것이다.

  • daemon(데몬): 백그라운드에서 항상 실행되고 있는 프로세스로 메모리에 상주해 있다가 사용자 요청이 오면 응답하는 프로세스. (유령, 악마라는 뜻을 가지고 있어 조용히 계속 실행되는 프로세스를 의미)

해결: 실행 경로를 절대경로로 입력할 것

crontab을 작성했지만 cron이 동작하지 않았던 이유는 실행 경로 문제 때문이었다.
실행 경로는 절대 경로로 입력해줘야 한다.

예를 들어 ubuntu의 backup이라는 폴더 안에 있는 backup.sh 파일을 실행시켜야 한다면 다음과 같이 작성해야 한다.

# 좋은 예
1 0 * * * /home/ubuntu/backup/backup.sh

# 나쁜 예
1 0 * * * /backup/backup.sh

현재 위치의 절대 경로를 확인하고 싶다면 pwd(Print Working Directory)를 입력하면 된다.

최종적으로 작성한 쉘 스크립트는 다음과 같다.

#!/bin/bash

#현재 시간 표시
NOWDATE=`date +%Y-%m-%d%H%M%S`

BACKUPNAME="$NOWDATE.tar.gz"

#git 폴더로 이동 후 git pull
cd /home/ubuntu/[디렉토리 경로]
git pull origin master

#디렉토리 압축
tar -cvzf $BACKUPNAME /home/ubuntu/[디렉토리 경로]

#S3 버킷으로 전송(put)
~/bin/s3cmd-2.1.0/s3cmd put $BACKUPNAME [S3 버킷 주소]/$BACKUPNAME

#ubuntu에 남은 파일 삭제
rm $BACKUPNAME

시행착오에 집중해서 작성했기 때문에 다음과 같이 생략한 부분들이 있다.

  • 디렉토리를 압축하려면 tar(tape archive)로 묶은 다음 압축해야 한다. (-cvzf 옵션 사용)
  • S3 버킷으로 전송하려면 s3cmd를 설치해야 한다.
    (내 경우 이미 ubuntu에 s3cmd가 설치되어 있어서 추가로 작업해줄 필요가 없었다.)
profile
Back-End Wep Developer. 꾸준함이 능력이다. Node.js, React.js를 주로 다룹니다.

0개의 댓글