VPSファイルのGoogle Driveへの自動バックアップ

さくらVPSなどバックアップツールを提供していないVPSで自動でバックアップを実施して、Googleドライブへファイルを保存する


バックアップポリシー

  • MondoRescueを用いたサーバ丸ごとバックアップではなく、指定フォルダのみ
    • WordPressなどのWebホスト情報
    • gitリポジトリ
    • などなど
  • 頻度
    • 一週間に一度のフルバックアップを3カ月分保持
    • 毎日の差分バックアップを一週間分保持
  • バックアップファイルは暗号化してGoogle Driveに保存

使用ツール

  • フォルダファイルのコピー … rsync
  • mysqlのコピー … mysqldump
  • Google Driveへのアップロード … rclone
  • 定期実行 … cron

rsync

rsyncは古くからあるフォルダ間の同期ツールです。差分コピーやsshを介したリモートフォルダとの同期など高機能なツールです

使用方法はシンプルで

% rsync -a <source> <destination>

で、sourceフォルダのファイルをdestination以下にコピーしてくれます。すでにdestinationフォルダに同一のファイルが存在する場合はスキップされるため効率的です。-aオプションはアーカイブモードで、ファイルの所有者情報などは保持したままコピーされます。ただし、以前の実行からsourceフォルダでファイルが削除された場合でもdestinationからは削除されません。削除する場合は--deleteオプションを使用します

差分バックアップは--compare-destオプションでベースフォルダを指定して実行します

% rsync -a <source> --compare-dest=<full_backup> <diff_backup>

上記コマンドで、full_backup後に更新されたファイルががdiff_backupにコピーされます。--compare-destは複数回指定することが可能で、差分バックアップからの差分を取得することも可能です

rclone

rcloneはコマンドラインで使用できる、クラウドストレージ間のファイル転送プログラムです。公式ページにあるように、Google Drive、Amazon S3、OneDriveをはじめかなり多くのサイトに対応しています。今回はGoogle Driveを使用します

インストール

Ubuntu 18.04の場合はaptでさくっとインストールできます

% sudo apt install rclone

自分の環境は16.xだっためaptでインストールすることはできません。コンパイル済みのバイナリをダウンロードして使用することになりますが、公式ページに準備されているスクリプトでダウンロード&コピーが可能です

% curl https://rclone.org/install.sh | sudo bash
% rclone --version
rclone v1.51.0
- os/arch: linux/amd64
- go version: go1.13.7
設定

リモートストレージにアクセスするためには、あらかじめ設定が必要です。設定はrclone configコマンドで行います。以下はGoogle Driveようの設定例ですが、公式ページに各リモート用に詳細はマニュアルがあるため参照してください

% rclone config
2020/03/10 08:36:03 NOTICE: Config file "~/.config/rclone/rclone.conf" not found - using defaults
No remotes found - make a new one
n) New remote
s) Set configuration password
q) Quit config
n/s/q> n
name> gdrive
Type of storage to configure.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
 1 / 1Fichier
   \ "fichier"
 2 / Alias for an existing remote
   \ "alias"
...
12 / Google Cloud Storage (this is not Google Drive)
   \ "google cloud storage"
13 / Google Drive
   \ "drive"
14 / Google Photos
   \ "google photos"
15 / Hubic
   \ "hubic"
...
Storage> 13  # Google Driveの13を選択
** See help for drive backend at: https://rclone.org/drive/ **

Google Application Client Id
Setting your own is recommended.
See https://rclone.org/drive/#making-your-own-client-id for how to create your own.
If you leave this blank, it will use an internal key which is low performance.
Enter a string value. Press Enter for the default ("").
client_id> [Enter] # 空欄でOK
Google Application Client Secret
Setting your own is recommended.
Enter a string value. Press Enter for the default ("").
client_secret> [Enter] # 空欄でOK
Scope that rclone should use when requesting access from drive.
Enter a string value. Press Enter for the default ("").
Choose a number from below, or type in your own value
 1 / Full access all files, excluding Application Data Folder.
   \ "drive"
 2 / Read-only access to file metadata and file contents.
   \ "drive.readonly"
   / Access to files created by rclone only.
 3 | These are visible in the drive website.
   | File authorization is revoked when the user deauthorizes the app.
   \ "drive.file"
   / Allows read and write access to the Application Data folder.
 4 | This is not visible in the drive website.
   \ "drive.appfolder"
   / Allows read-only access to file metadata but
 5 | does not allow any access to read or download file content.
   \ "drive.metadata.readonly"
scope> 1 # コピーと削除も行うので1
ID of the root folder
Leave blank normally.

Fill in to access "Computers" folders (see docs), or for rclone to use
a non root folder as its starting point.

Note that if this is blank, the first time rclone runs it will fill it
in with the ID of the root folder.

Enter a string value. Press Enter for the default ("").
root_folder_id> [Enter] # 空欄でOK
Service Account Credentials JSON file path
Leave blank normally.
Needed only if you want use SA instead of interactive login.
Enter a string value. Press Enter for the default ("").
service_account_file> [Enter] # 空欄でOK
Edit advanced config? (y/n)
y) Yes
n) No (default)
y/n> n # NoでOK
Remote config
Use auto config?
 * Say Y if not sure
 * Say N if you are working on a remote or headless machine
y) Yes (default)
n) No
y/n> n # リモート上でブラウザを立ち上げれない場合はNo
Please go to the following link: https://accounts.google.com/o/oauth2/auth?access_type=offline&client_id=20239847832903847.apps.googleusercontent.com&redirect_uri=urn%3Aietf%3Awg%3Aeauth%3A2.0%3Aeob&respomse_typo=code&scope=htttps%3asdf2F%2Fwww.googleapis.com%2Fauth%2Fdrive&state=rak9ztM0a8da908d7fA
Log in and authorize rclone for access
Enter verification code> ************** # 上記URLでアクセス許可後に表示されたコードをコピー
Configure this as a team drive?
y) Yes
n) No (default)
y/n> n # TeamドライブにアクセスしなければNoでOK
--------------------
[gdrive]
type = drive
scope = drive
token = {"access_token":"*********","token_type":"****","refresh_token":"******","expiry":"****"}
--------------------
y) Yes this is OK (default)
e) Edit this remote
d) Delete this remote
y/e/d> y # Yesでconfigを~/.config/rclone/rclone.configに保存

ポイントは上記でUse auto config?をNoにして、ローカルホストで手動で表示されたリンクをブラウザで表示されて、rcloneでのGoogle Driveアクセスを許可し、表示されたコードをEnter verification code>に貼り付けるところです

設定後、以下のコマンドでルートフォルダが表示されることを確認します (gdriveは上記で設定したリモート名です)

% rclone lsd gdrive:
ファイルのコピー

コピーは以下のコマンドです、リモートのパスはフォルダです。存在しなかった場合はフォルダが作成され、その下にファイルがコピーされます

% rclone copy local_file gdrive:remote_folder
ファイルの削除
% rclone delete gdrive:remote_file

ヘルパースクリプト

バックアップ自体はこれまでの各種コマンドの組み合わせで実現できますが、差分バックアップ時のベースアーカイブの特定や、古いアーカイブの削除などを実行するための便利スクリプトを利用して、実際にcronで実行するコマンドを実現していきます

必要パッケージ

上記で解説したrsync, rclone以外に以下のパッケージが必要です

% sudo apt install p7z-full

バックアップコマンド準備

  • バックアップ用の作業フォルダを作成して、GitHubからスクリプトをダウンロードします
% mkdir /var/tmp/backup # バックアップ作業フォルダ
% cd /var/tmp/backup
% git clone https://github.com/udon-code/vps_utils.git vps_utils
% ./vps_utils/scripts/backup_to_cloud.py -h
usage: backup_to_cloud.py [-h] -s path [-r <rclone path>] [-d folder] [-i]
                          [-P password] [-z] [--nocompress] [--mysql] [-n]
                          [-v] [-q] [--clean_local_after days] [--cleanall]
                          [--clean_remote_after days]

optional arguments:
  -h, --help            show this help message and exit
  -s path, --src path   Source folder(s). Can be specified multiple times
  -r <rclone path>, --remote <rclone path>
                        Remote path (<rclone remote name>:<remote folder>)
                        (ex. gdrive:backup)
  -d folder, --dst folder
                        Output folder, created a temporary one if omitted
  -i, --incremental     Backup differential from the latest full+diff backup.
                        (note: mySql backup doesnt support differential back)
  -P password, --password password
                        If specified, encrypt zip file with given password
  -z, --zip             Use zip instead of zip (default is 7z)
  --nocompress          Skip compression
  --mysql               Save mysql database (may require root privilege)
  -n, --noexec          dry run
  -v, --verbose         Verbose mode
  -q, --quiet           Quiet mode
  --clean_local_after days
                        Delete old backup files older than specified days(In
                        incremental mode, delete old *_diff after a full
                        backup before specified days)(In fullbackup mode,
                        delete old full backup before specified days)(Delete
                        compressed file when --remote presents)
  --cleanall            Delete everything but the latest archive
  --clean_remote_after days
                        Delete remote file older than specified days
  • バックアップ対象フォルダの設定
% vi weekly_backup.sh
#!/bin/bash

BACKUP_CMD=`dirname $0`/vps_utils/scripts/backup_to_cloud.py
LOCAL_DST=/var/tmp/backup/work
REMOTE_DST="gdrive:Backup"

echo ""
echo "-----------------------------------"
echo "Start backup ... " `date`

set -x
${BACKUP_CMD} -v \
  -d ${LOCAL_DST} \
  -r ${REMOTE_DST} \
  -P hogehoge \
  --clean_local_after 1 \
  --clean_remote_after 90 \
  -s /var/www \
  -s /home \

set +x
echo ""
echo "End backup ... " `date`
echo "------------------------------------"

% vi daily_backup.sh
#!/bin/bash

BACKUP_CMD=`dirname $0`/vps_utils/scripts/backup_to_cloud.py
LOCAL_DST=/var/tmp/backup/work
REMOTE_DST="gdrive:Backup"

echo ""
echo "-----------------------------------"
echo "Start backup ... " `date`

set -x
${BACKUP_CMD} -v -i \
  -d ${LOCAL_DST} \
  -r ${REMOTE_DST} \
  -P hogehoge \
  --clean_local_after 1 \
  --clean_remote_after 7 \
  -s /var/www \
  -s /home \

set +x
echo ""
echo "End backup ... " `date`
echo "------------------------------------"

-P hogehogeの部分は適当なパスワードを設定します

  • 動作確認
% ./weekly_backup.sh     # フルバックアップ
% ./daily_backup.sh  # 差分バックアップ

それぞれリモートフォルダに 20200101_121314.7z20200101_121314_diff.7zのアーカイブがアップロードされていればOKです。念のためダウンロード、展開してバックアップが出来ていることを確認します

cronで定期実行

最後にcronに登録して定期的に実行します

% crontab -e
10 1 * * 0   /var/tmp/backup/weekly_backup.sh >> /var/tmp/backup/weekly.log
10 1 * * 1-6 /var/tmp/backup/daily_backup.sh >> /var/tmp/backup/daily.log

おすすめ