쉘 스크립트로 S3 클리어하기

한라봉봉·2024년 8월 6일

ec2, linux 2023, s3(네이버 클라우드)

사용자가 업로드하여 공유하여 사용한 이후 삭제로직을 사용자에게 전가하기 애매한 서비스가 있다..
-> 주기적으로 기간이 지난 S3 경로저장 테이블 row들과 s3버킷 내 기간이 지난 폴더들을 삭제해 보자

배경지식

.sh 쉘 스크립트 파일에 관하여

.sh 파일은 일반적으로 Unix 계열 운영 체제에서 사용되는 쉘 스크립트 파일입니다. 이러한 스크립트는 시스템의 명령줄 인터페이스를 통해 여러 명령어를 자동으로 실행할 수 있게 도와줍니다. sh는 "shell"의 약자로, 다양한 쉘 환경에서 실행할 수 있는 스크립트를 작성하는 데 사용됩니다.

쉘 스크립트의 기본 구성 요소

  1. 해시뱅 (Shebang):
    스크립트의 첫 번째 줄에 #!/bin/bash와 같은 구문을 사용하여 어떤 셸을 사용할지 지정합니다. 이 예에서는 bash 셸을 사용하겠다는 의미입니다.
#!/bin/bash
  1. 주석:
    # 기호로 시작하는 줄은 주석으로, 스크립트의 설명이나 사용 방법 등을 작성하는 데 사용됩니다.
# 이 스크립트는 2일 전 데이터를 삭제합니다.

3.변수:
쉘 스크립트에서는 변수를 사용하여 데이터를 저장하고 관리할 수 있습니다. 변수에 값을 할당할 때는 = 기호를 사용합니다.

DB_HOST="service-dev.ck39dp9w2h39.ap-northeast-2.rds.amazonaws.com"

4.명령어 실행:
쉘 스크립트에서 명령어를 실행하려면 일반적인 명령줄에서 사용하는 것처럼 입력하면 됩니다.

date -d '2 days ago' +%Y-%m-%d
  1. 제어 구조:
    조건문과 반복문을 사용하여 스크립트의 흐름을 제어할 수 있습니다.
# 조건문 예제
if [ -d "/path/to/directory" ]; then
    echo "Directory exists."
fi

# 반복문 예제
for file in /path/to/files/*; do
    echo "Processing $file"
done

스케쥴러, 크론(Cron)

크론(Cron)은 Unix 계열 운영 체제에서 작업을 자동화하는 데 사용되는 시간 기반 스케줄러입니다. 크론을 사용하면 특정 시간에 스크립트나 명령을 자동으로 실행할 수 있습니다.

환경구성

1. EC2 인스턴스에 연결하여 다음 명령어로 필요한 패키지를 설치합니다

sudo dnf update -y
sudo dnf install -y mariadb105

위 명령어는 MariaDB 10.5 클라이언트를 설치합니다. Amazon Linux 2023에서는 MySQL 대신 MariaDB 클라이언트를 사용하는 것이 일반적입니다.

sudo apt update
sudo apt install mysql-client
systemctl status mysql

Ubuntu 20.04인 경우에서 mysql-client를 설치하면 되고, 위와같이 진행합니다.

apt list -a mysql-client //가능 리스트 확인
sudo apt install mysql-client=8.0.36-1ubuntu20.04

Ubuntu 20.04인 경우에서 mysql-client의 특정 버전을 지정하고 싶다면 위와같이 진행합니다.

설치가 완료되면 다음 명령어로 mysql 명령어가 정상적으로 설치되었는지 확인합니다.

mysql --version

2.AWS CLI 설치:

Ncloud Object Storage와 상호작용하기 위해 AWS CLI를 설치합니다:

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

3. AWS CLI 설정:

aws configure

여기서, Access Key ID와 Secret Access Key를 입력하고, Default region name은 ap-northeast-2(서울임)로 설정합니다. default output format 은 용도에 맞게 고르면 되는데(json|table|text|yaml|yaml-stream), 삭제 로직만 수행 할 예정이므로 text로 설정함.

4. 크론 설치(cron 패키지 설치)

Amazon Linux 2023에서는 cron 패키지가 기본적으로 설치되어 있지 않았음. 이 문제를 해결하기 위해 cron 패키지를 설치하고 서비스를 활성화함

dnf 패키지 관리자를 사용하여 cron을 설치합니다.

sudo dnf install -y cronie

Ubuntu 20.04인 경우 cron 패키지가 기본적으로 설치되어 있으므로 설치 과정은 건너뜀. 확인만 할것

5.cron 서비스 시작 및 활성화:

cron 서비스를 시작하고, 부팅 시 자동으로 시작되도록 활성화합니다.

sudo systemctl start crond
sudo systemctl enable crond

6. Crontab 명령어 확인:

crontab 명령어가 정상적으로 작동하는지 확인합니다.
이 명령어가 실행되고 현재 사용자에 대한 크론 작업 목록이 비어 있더라도 출력되면, crontab 명령어가 정상적으로 작동하는 것입니다.

crontab -l

7. 크론 데몬 확인:

크론 데몬이 정상적으로 실행 중인지 확인합니다.

sudo systemctl status crond
dpkg -l | grep cron

만약 크론 데몬이 실행 중이 아니라면 다음 명령어로 시작합니다.

sudo systemctl start crond

8. 서버 시간 확인

크론 작업은 서버의 기본 시간대에 따라 실행됩니다. 서버의 시간대가 예상한 것과 다른 경우, 크론 작업이 다른 시간에 실행될 수 있습니다.
시간대(Timezone) 확인:
서버의 시간대를 확인하려면 다음 명령어를 사용합니다:

date

만약 시간대가 예상과 다르다면, /etc/timezone을 편집하거나 timedatectl 명령어로 변경할 수 있습니다:

sudo timedatectl set-timezone Asia/Seoul

스크립트 파일의 위치 결정

나는 후보 1로 결정했다. 추후 수정이 많을 것 같아서..

후보1. 사용자 홈 디렉토리 내의 스크립트 디렉토리

경로: ~/scripts/
설명: 사용자의 홈 디렉토리 내에 scripts 디렉토리를 만들어 스크립트를 저장하면 개인 스크립트를 관리하기 쉽습니다
스크립트를 자주 수정하거나 업데이트해야 하는 경우 사용자 홈 디렉토리 내에 두는 것이 편리합니다.

후보2. 시스템의 공용 스크립트 디렉토리

경로: /usr/local/bin/ 또는 /usr/local/sbin/
설명: 시스템 전반에서 사용할 수 있도록 공용 디렉토리에 저장하면 모든 사용자가 해당 스크립트를 실행할 수 있습니다. 다만, 관리자 권한이 필요합니다.
시스템에 중요한 영향을 미치는 스크립트라면 관리자 권한이 필요한 디렉토리에 두어 접근을 제한하는 것이 좋습니다.

후보3. 프로젝트 관련 디렉토리

경로: 프로젝트의 특정 디렉토리 (예: /var/scripts/ 또는 /opt/myproject/scripts/)
설명: 특정 프로젝트와 관련된 스크립트는 해당 프로젝트 디렉토리에 저장하여 관련 파일과 함께 관리합니다.
여러 사용자가 사용하는 환경이라면 공용 디렉토리에 두어 모두가 쉽게 접근할 수 있도록 합니다.

스크립트 작성

아래 쉘 파일들을 위 경로에 생성, 작성
delete_db_entries.sh
delete_s3_folders.sh

MariaDB에서 2일 전 데이터 삭제

변수 사용: 데이터베이스 접속 정보를 변수에 저장하여 재사용 가능하게 합니다.
명령어 실행: mysql 명령어를 사용하여 데이터베이스에 연결하고 SQL 명령을 실행합니다.
날짜 계산: date 명령어를 사용하여 2일 전 날짜를 계산합니다.

#!/bin/bash

# 데이터베이스 접속 정보
DB_HOST="service-dev.ck39dp9w2h39.ap-northeast-2.rds.amazonaws.com"
DB_USER="your_db_user"
DB_PASSWORD="your_db_password"
DB_NAME="your_db_name"

# 2일 전 날짜 계산
DELETE_DATE=$(date -d '2 days ago' +%Y-%m-%d)

# 데이터베이스에 접속하여 2일 전 추가된 데이터를 삭제
/usr/bin/mysql -h $DB_HOST -u $DB_USER -p$DB_PASSWORD $DB_NAME -e "DELETE FROM contents WHERE upload_date = '$DELETE_DATE';"

Ncloud Object Storage에서 2일 전 폴더 삭제

AWS CLI 사용: aws s3 rm 명령어를 사용하여 S3 버킷에서 특정 날짜의 폴더를 삭제합니다.
날짜 계산: date 명령어를 사용하여 폴더 이름에 필요한 날짜를 동적으로 계산합니다.

#!/bin/bash

# S3 버킷 정보
ENDPOINT="https://kr.object.ncloudstorage.com"
REGION="kr-standard"
BUCKET="your_bucket_name"

# 2일 전 날짜 계산
DELETE_DATE=$(date -d '2 days ago' +%Y%m%d)

# img와 pdf 폴더에서 2일 전 폴더 삭제
/usr/local/bin/aws --endpoint-url=$ENDPOINT s3 rm s3://$BUCKET/img/$DELETE_DATE --recursive
/usr/local/bin/aws --endpoint-url=$ENDPOINT s3 rm s3://$BUCKET/pdf/$DELETE_DATE --recursive

환경 변수: cron 작업은 사용자의 환경 변수를 로드하지 않으므로, 명령어의 절대 경로를 지정하면 정확한 위치의 명령어를 실행할 수 있습니다. -> 대박중요함 제발

which mysql
which aws

위 명령어를 통해 절대경로를 확인, 적용한다.

/usr/bin/mysql
/usr/local/bin/aws

스크립트 실행

실행 권한 부여: 스크립트를 실행 가능하도록 권한을 부여합니다.

chmod +x delete_db_entries.sh
chmod +x delete_s3_folders.sh

스크립트 직접 실행

./delete_db_entries.sh
./delete_s3_folders.sh

줄 끝 문제 ($'\r': command not found)

이 오류는 스크립트 파일에 Windows 스타일의 줄 끝(CRLF)이 포함되어 있을 때 발생합니다. Unix 시스템에서는 LF를 사용해야 합니다. 이 문제는 파일을 Windows에서 편집한 경우에 자주 발생합니다.
1. 방법 1
vim이나 nano 같은 텍스트 편집기를 사용하여 스크립트의 줄 끝을 확인할 수 있습니다:

vim /home/ec2-user/script/delete_db_entries.sh
  1. 방법 2
    dos2unix 명령어 사용
    dos2unix는 Windows 형식의 줄 바꿈을 UNIX 형식으로 변환하는 유틸리티입니다. 이를 사용하여 스크립트 파일을 변환할 수 있습니다.
    dos2unix 설치:
    sudo apt update
    sudo apt install dos2unix
    파일 변환:
    dos2unix delete_s3_folders.sh

Cron 스케쥴러에 등록

1. 크론 작업을 편집

크론 작업을 수정하려면 다음 명령어를 사용하여 crontab을 편집합니다:

crontab -e

2. vim으로 크론 탭에서 원하는 스케쥴로 .sh 파일 실행설정

새벽 3시 30분에 스크립트가 실행되도록 설정했다.
자세한 사용법 참조: https://jdm.kr/blog/2

30 3 * * * /home/ec2-user/scripts/delete_db_entries.sh
30 3 * * * /home/ec2-user/scripts/delete_s3_folders.sh

3. 크론 작업 목록 확인

설정이 잘 되었는지 확인하려면 다음 명령어를 사용하여 현재 설정된 크론 작업 목록을 확인할 수 있습니다.

crontab -l

3. sudo를 사용하여 cron 서비스를 재시작합니다.

sudo systemctl restart crond

sudo systemctl restart cron // 우분투

로그

사실 아예 실행이 되지 않는 경우 로그가 나오지 않는다. 심지어 내 경우 보통 로그가 저장된다는 경로에도 없어서..
일단 실행시 쌓이도록 하는 로그는 아래와 같이 설정한다.

30 3 * * * /home/ec2-user/scripts/delete_db_entries.sh >> /home/ec2-user/logs/db_delete.log 2>&1
30 3 * * * /home/ec2-user/scripts/delete_s3_folders.sh >> /home/ec2-user/logs/s3_delete.log 2>&1
profile
백엔드 개발공부 로그를 기록합니다

0개의 댓글