VPSのイメージバックアップをddを使ってネットワーク越しに取る

2 min read読了の目安(約2400字

私が管理している tomacheese.com の Web サイトは ConoHa の VPS 上で動作しています。
当然定期的にフルでバックアップを取りたいのですが、ConoHa 側が用意しているイメージ保存は探し回る限りダウンロードできず、保存から 90 日を経過すると自動で削除されてしまう仕様になっています。
これではあまりバックアップの意味がないので、(本来サーバが起動中に dd でバックアップ取るべきじゃないけれど)ネットワーク越しで ddssh を使いバックアップを取るようにしました。その記録です。

注意事項

この記事に記載されている内容を実行し、発生したいかなる問題について執筆者は一切責任を負いません。自己責任でお願いします。

環境

ローカル

  • Linux Mint 19.2 Tina (cat /etc/*-release)
  • Coreutils(dd): 8.28 (apt version coreutils)
  • OpenSSH: 7.6 (ssh -V)
  • gzip: 1.6 (gzip -V)

リモート

  • CentOS 7.6.1810 (cat /etc/*-release)
  • Coreutils(dd): 8.22 (yum info coreutils)
  • OpenSSH: 7.4 (ssh -V)
  • gzip: 1.5 (gzip -V)

コマンド

ssh -p <ポート> -i <認証鍵パス> <ユーザー名>@<VPSのIP> sudo dd if=<バックアップを取るデバイスファイルパス> status=progress | gzip - | dd of=<保存先パス> 2>&1 | tee <ログファイルパス>

実行する前に、<> で囲まれているところを埋める必要があります。それぞれの意味や例は以下。

  • <ポート>: SSH のポートです。変えているならば設定してください。
  • <認証鍵パス>: 公開鍵認証方式での秘密鍵のパスを指定してください。公開鍵認証方式で接続しないなら設定する必要はありません。
  • <ユーザー名>: SSH のログインユーザー名です。root とか。(公開サーバで root ログインはダメだぞ)
  • <VPSのIP>: 対象 VPS(リモート)の IP アドレスを設定してください。
  • <バックアップを取るデバイスファイルパス>: バックアップを取る対象 VPS(リモート)のデバイスファイルパスを設定してください。たとえば /dev/sda1 とか。
  • <保存先パス>: ローカルで保存する先を指定してください。拡張子は .gz<サーバ名>.img.gz とかがよいと思います。
  • <ログファイルパス>: ログを取るならば設定してください。ログがいらないなら 2>&1 | tee 以降不要です。

詳しい解説

まず、このコマンドを実行してリモートとローカルで実行されるコマンドがそれぞれどれなのかをはっきりしなければ頭がこんがらがるでしょう(私はこんがらがるのでいつもいったん分解します)。整理します。

sudo dd if=<バックアップを取るデバイスファイルパス> status=progress
ssh -p <ポート> -i <認証鍵パス> <ユーザー名>@<VPSのIP>

gzip -
dd of=<保存先パス> 2>&1
tee <ログファイルパス>

パイプを改行してしまっていますが、上がリモート、下がローカルです。

  1. まず、ssh でリモートサーバに接続します。その後、dd コマンドをリモートで実行させます。
    ddof を設定しないと stdout 、つまり標準出力に吐き出されるので、それをローカルのパイプでキャッチします。
    なお、ddstatus=progress を設定すると画像のように進捗状況が出力できます。SIGUSR1 シグナルを送る(pkill -USR1 dd)のが割と多く出てきますが、Coreutils のバージョンがそれなりであれば status=progress が使えるはずです。
  2. その後、ローカルで gzip 圧縮し、圧縮データを標準出力に吐き出します。ネットワークが貧弱ならリモートで圧縮してから受信してもよいと思いますが、試してませんしパイプをリモートで実行させる方法をよく理解してません。
  3. パイプをまた使い dd コマンドでファイル出力します。if を設定しないと標準入力(stdin)を使用するので標準出力から gzip での圧縮データを受け取り、of でファイルに出しています。

圧縮については気になるならば bzip2 とかでもよいのかもしれませんが、圧縮に時間がかかって結果的に全体処理が遅くなってもどうかと思うので gzip を選択しています。
gzip でも 50GB のディスクイメージを 35GB くらいには圧縮できるので、十分かなと。

時間としてはネットワークやローカルのスペックにもよりますが、1 時間は基本掛かると思います…。その間にサーバ側で変なことが起こらないことを願いましょう。

本来、バックアップを取る時にバックアップを取られる側のサーバ(リモート)が動作しているというのは絶対に好ましくない状態ではありますが、VPS の場合リモートがオンラインでないと当然どうしようもないので、止められるものはなるべく止めてからバックアップを取る…くらいはしておきましょう。