Profile picture

[Shell Script] 도커 백업

JaehyoJJAng2023년 11월 15일

▶︎ 개요

도커 컨테이너를 tar File로 만들어 백업하는 작업을 셸 스크립트를 활용하여 해보려고 한다.


‣ 셸 스크립트

{% include codeHeader.html name="containerBackup.sh" %}

#!/usr/bin/bash


now=$(date +"%Y%m%d %T")
logDate=$(date +"%Y%m%d_%H%M")
logDir="/var/log/container/backup/logs"
logFile="$logDate.log"

exec 3>> "$logFile"
echo "===================================" >&3
echo "[$now] Docker Container 백업 작업 시작" >&3

if [[ ! -d "$logDir" ]]; then
    echo "[$now] $logDir 디렉토리를 생성합니다." >&3
    mkdir -p "$logDir"

    if [[ $? != 0 ]]; then
        echo "[$now] $logDir 디렉토리 생성 실패!" >&3
    else
        echo "[$now] $logDir 디렉토리 생성 성공!" >&3
    fi
else
    echo "[$now] $logDir 디렉토리가 이미 존재합니다." >&3
fi

echo "[$now] 백업에 사용될 변수를 정의 중입니다." >&3

# 백업 디렉토리 경로
echo "[$now] 1. 백업 디렉토리를 명시 .." >&3
backupDir="/var/log/container/backup"

# 백업 파일에 사용될 백업 날짜
echo "[$now] 2. 백업 날짜 명시 .." >&3
DATE=$(date +"%Y%m%d_%H%M")

# 백업할 도커 이미지 이름
echo "[$now] 3. 백업용 도커 이미지 명시 .." >&3
read -p "백업할 컨테이너명 입력 :" targetContainerName
dockerImageName="yshrim12/$targetContainerName"

# 백업 시작
echo "[$now] 백업을 시작합니다 .." >&3
echo "[$now] 저장할 디렉토리가 있는지 확인 합니다." >&3
if [[ ! -d "$backupDir" ]]; then
    # 디렉토리 생성
    echo "[$now] 저장용 디렉토리 $backupDir을 생성합니다" >&3
    mkdir -p "$backupDir"
    if [[ $? != 0 ]]; then
        echo "[$now] 저장용 디렉토리 $backupDir 생성 실패!" >&3
    else        
        echo "[$now] 저장용 디렉토리 $backupDir 생성 성공!" >&3
    fi

    # 권한 설정
    echo "[$now] 저장용 디렉토리 $backupDir의 권한을 수정 합니다." >&3
    chmod 755 -R "$backupDir"
    if [[ $? != 0 ]]; then
        echo "[$now] 저장용 디렉토리 $backupDir의 권한 수정에 실패하였습니다. ($?)" >&3
    else
        echo "[$now] 저장용 디렉토리 $backupDir의 권한 수정에 성공하였습니다" >&3
    fi
else
    echo "[$now] 저장용 디렉토리 $backupDir는 이미 존재합니다" >&3
fi

echo "[$now] 백업을 위해 구동중인 Container($targetContainerName)를 중지 합니다." >&3
docker stop "$targetContainerName"
if [[ $? != 0 ]]; then
    echo "[$now] 구동 중인 Container($targetContainerName)를 중지하는데 실패하였습니다. ($?)" >&3
else
    echo "[$now] 구동 중인 Container($targetContainerName)를 중지하는데 성공하였습니다. ($?)" >&3
fi

echo "[$now] Container의 현재 상태와 데이터를 Docker Image로 저장합니다." >&3
docker commit "$targetContainerName" "$dockerImageName"
if [[ $? != 0 ]]; then
    echo "[$now] $targetContainerName 컨테이너 이미지화 실패!" >&3
else
    echo "[$now] $targetContainerName 컨테이너 이미지화 성공!" >&3
fi

echo "[$now] Container의 현재 상태와 데이터를 tar File로 생성합니다." >&3
docker save -o "$backupDir/$DATE_$targetContainerName.tar" "$dockerImageName"
if [[ $? != 0 ]]; then
    echo "[$now] $targetContainerName 컨테이너를 tar File로 생성하는데 실패!" >&3
else
    echo "[$now] $targetContainerName 컨테이너를 tar File로 생성하는데 성공!"  >&3
fi

echo "[$now] 기존 컨테이너 재기동" >&3
docker restart "$targetContainerName"
if [[ $? != 0 ]]; then
    echo "[$now] $targetContainerName 컨테이너 재기동 실패!" >&3
else
    echo "[$now] $targetContainerName 컨테이너 재기동 성공!" >&3
fi

echo "===================================" >&3
echo "[$now] Docker Container 백업 작업 종료" >&3

cat "$logFile" >| "$logDir/$logFile"
rm -rf "$logFile"

‣ 코드 설명

if [[ ! -d "$logDir" ]]; then
    echo "[$now] $logDir 디렉토리를 생성합니다." >&3
    mkdir -p "$logDir"

    if [[ $? != 0 ]]; then
        echo "[$now] $logDir 디렉토리 생성 실패!" >&3
    else
        echo "[$now] $logDir 디렉토리 생성 성공!" >&3
    fi
else
    echo "[$now] $logDir 디렉토리가 이미 존재합니다." >&3
fi

로그 디렉토리가 존재하는지 검사


# 백업할 도커 이미지 이름
echo "[$now] 3. 백업용 도커 이미지 명시 .." >&3
read -p "백업할 컨테이너명 입력 :" targetContainerName
dockerImageName="yshrim12/$targetContainerName"

백업 컨테이너를 사용자에게 입력 받도록 함.


if [[ ! -d "$backupDir" ]]; then
    # 디렉토리 생성
    echo "[$now] 저장용 디렉토리 $backupDir을 생성합니다" >&3
    mkdir -p "$backupDir"
    if [[ $? != 0 ]]; then
        echo "[$now] 저장용 디렉토리 $backupDir 생성 실패!" >&3
    else        
        echo "[$now] 저장용 디렉토리 $backupDir 생성 성공!" >&3
    fi

    # 권한 설정
    echo "[$now] 저장용 디렉토리 $backupDir의 권한을 수정 합니다." >&3
    chmod 755 -R "$backupDir"
    if [[ $? != 0 ]]; then
        echo "[$now] 저장용 디렉토리 $backupDir의 권한 수정에 실패하였습니다. ($?)" >&3
    else
        echo "[$now] 저장용 디렉토리 $backupDir의 권한 수정에 성공하였습니다" >&3
    fi
else
    echo "[$now] 저장용 디렉토리 $backupDir는 이미 존재합니다" >&3
fi

백업 디렉토리가 존재하는지 검사


echo "[$now] 백업을 위해 구동중인 Container($targetContainerName)를 중지 합니다." >&3
docker stop "$targetContainerName"
if [[ $? != 0 ]]; then
    echo "[$now] 구동 중인 Container($targetContainerName)를 중지하는데 실패하였습니다. ($?)" >&3
else
    echo "[$now] 구동 중인 Container($targetContainerName)를 중지하는데 성공하였습니다. ($?)" >&3
fi

구동중인 컨테이너 중지

$?는 **명령어 종료 상태(Exit Status)**를 나타내는 특수 변수임.

이전 명령이 성공적으로 실행되면 0의 값을 가지고,

오류가 발생하면 다른 값을 가짐. 이 값은 일반적으로 다른 명령을 실행, 제어의 흐름을 결정할 때 많이 사용함.


echo "[$now] Container의 현재 상태와 데이터를 Docker Image로 저장합니다." >&3
docker commit "$targetContainerName" "$dockerImageName"
if [[ $? != 0 ]]; then
    echo "[$now] $targetContainerName 컨테이너 이미지화 실패!" >&3
else
    echo "[$now] $targetContainerName 컨테이너 이미지화 성공!" >&3
fi

입력된 컨테이너의 데이터와 상태를 도커 이미지화


echo "[$now] Container의 현재 상태와 데이터를 tar File로 생성합니다." >&3
docker save -o "$backupDir/$DATE_$targetContainerName.tar" "$dockerImageName"
if [[ $? != 0 ]]; then
    echo "[$now] $targetContainerName 컨테이너를 tar File로 생성하는데 실패!" >&3
else
    echo "[$now] $targetContainerName 컨테이너를 tar File로 생성하는데 성공!"  >&3
fi

저장된 도커 이미지를 기반으로 tar File로 생성


echo "[$now] 기존 컨테이너 재기동" >&3
docker restart "$targetContainerName"
if [[ $? != 0 ]]; then
    echo "[$now] $targetContainerName 컨테이너 재기동 실패!" >&3
else
    echo "[$now] $targetContainerName 컨테이너 재기동 성공!" >&3
fi

컨테이너를 재기동하며 마무리.


‣ 실행

해당 스크립트를 실행하면 아래와 같이 로그가 생성되며 정상적으로 작업이 수행됨.

sudo bash containerBackup.sh

image


Loading script...