Vultr APIを使ってSnapshot機能でバックアップしちゃう

2018年6月4日

Vultrには有料のバックアップオプションとは別に、当面の間無料のスナップショット機能があります。データベースの内容を含むサイトデータは毎晩自動で別サーバーにバックアップを取っているのですが、サーバー丸ごとのバックアップもあるといいよね。

API経由でサーバー情報を取得してみる

APIを利用するにはAPIキーを取得する必要があります。

さらにAPIにアクセスするアドレスの登録も。セキュリティの問題で、どこからでもサーバーをいじくりまわすのは危ないということで登録されたIPアドレス以外からのアクセスは禁じられている模様。

Vultr API設定画面

固定IPなんてないぞ!と思ったけど、よく考えたらこのサーバー自身が固定IP持ってた!

#! /bin/sh
KEY='*****'
ENDPOINT='https://api.vultr.com'
curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/server/list

試しにサーバー情報を取ってみました。APIキーはcurlの-Hオプションで渡してやります。(とAPIマニュアルに書いてあった)

{"1******0":{"SUBID":"1******0","os":"FreeBSD 11 x64","ram":"1024 MB","disk":"Virtual 25 GB",~以下略~

こんな情報が返ってきた。

API経由でスナップショットを触ってみる

スナップショットリストを取得する

スナップショットリストを取得するには先ほどのスクリプト中のアドレスを/v1/server/listから/v1/snapshot/listに書き換えるだけ。

{
"f***********1":{"SNAPSHOTID":"f***********1","date_created":"2018-06-02 06:00:34",~略~},
"7***********f":{"SNAPSHOTID":"7***********f","date_created":"2018-06-02 21:58:51",~略~},
"8***********d":{"SNAPSHOTID":"8***********d","date_created":"2018-06-03 22:35:28",~略~}
}

こんな情報が返ってきた。わかりやすいように改行を入れてあります。

スナップショットを作成する

スナップショットを作成するには最初に取得したサーバー情報中のサーバーID(SUBID)を指定する必要があります。

#! /bin/sh
KEY='*****'
SERVERID='1******0'
ENDPOINT='https://api.vultr.com'
curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/snapshot/create --data "SUBID=${SERVERID}"

実行したら即スナップショットIDが返ってきた。これで作られるらしい。

{"SNAPSHOTID":"b***********e"}

スナップショットリストを取得するとこんな感じ。

"b***********e":{"SNAPSHOTID":"b***********e","date_created":"2018-06-04 06:16:48","description":"","size":"0","status":"pending","OSID":"230","APPID":"0"}

該当部だけを抽出しました。ちゃんとできてるみたい。作成中なのでstatusはpendingになっています。

スナップショットを削除する

スナップショットの削除はスナップショットリストID(SNAPSHOTID)の指定が必要です。先ほど取得したスナップショットリストから、削除したいIDを抽出しましょう。

Vultr スナップショットリスト

普通は一番古いやつだね。ということで抽出。

#! /bin/sh
TEMPFILE=`mktemp ./vultr.XXXXXX`
KEY='*****'
SERVERID='1******0'
ENDPOINT='https://api.vultr.com'
curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/snapshot/list | tr '}' '\n' | grep -v '^$' |\
  sed 's/.*{//' | grep -v '"status":"pending"' | cut -d ',' -f 1,2 |\
  sed 's/.*SNAPSHOTID":"\([^"]*\)".*date_created":"\([^"]*\)".*/\2=\1/' | while read LINE;
do
echo $LINE >> $TEMPFILE
done
if test `cat $TEMPFILE | wc -l` -gt 1; then
  REMOVEID=`cat $TEMPFILE | sort | head -n 1 | cut -d '=' -f 2`
  curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/snapshot/destroy --data "SNAPSHOTID=${REMOVEID}"
  echo "${REMOVEID} is removed."
fi
rm $TEMPFILE

いちおうstatusがpendingのものを除外したうえで最も古いスナップショットのIDをひとつ抽出して削除しました。

毎晩バックアップを取ろう

というわけで最終的に毎晩バックアップを取るスクリプトを作りました。

スナップショットはディスクの内容全体のイメージファイルなので一つあたり25GBもの容量を食います。あまり使いすぎてお金取られると困るのでバックアップは一週間分のデータにしておこう。7日以上前のデータを自動削除します。

#! /bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
TEMPFILE=`mktemp ./vultr.XXXXXX`
KEY='*****'
SERVERID='1******0'
ENDPOINT='https://api.vultr.com'
curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/snapshot/list | tr '}' '\n' | grep -v '^$' |\
  sed 's/.*{//' | grep -v '"status":"pending"' | cut -d ',' -f 1,2 |\
  sed 's/.*SNAPSHOTID":"\([^"]*\)".*date_created":"\([^"]*\)".*/\2=\1/' | while read LINE;
do
echo $LINE >> $TEMPFILE
done
if test `cat $TEMPFILE | wc -l` -gt 6; then
  REMOVEID=`cat $TEMPFILE | sort | head -n 1 | cut -d '=' -f 2`
  curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/snapshot/destroy --data "SNAPSHOTID=${REMOVEID}"
  echo "${REMOVEID} is removed."
fi
rm $TEMPFILE
curl -H "API-Key: ${KEY}" ${ENDPOINT}/v1/snapshot/create --data "SUBID=${SERVERID}" |\
  cut -d ':' -f 2 | sed 's/.*"\([^"]*\)".*/\1 is created./'

これを毎晩適当な時間にcronで走らせれば直近7日間のバックアップイメージが取れますよ。