Dockerのバックアップの考え方とその方法について


 Dockerコンテナは基本的にバックアップは不要だと思います。といいますか、不要になるように設計する必要があると思います。

 Dockerは拡張性の高さが売りの1つである仮想化エンジンです。DockerコンテナのベースとなるDockerイメージはリードオンリーですし、もし更新が発生しない、若しくは更新情報が無視できるDockerコンテナがあったとしたら、Dockerとして最高のパフォーマンスを発揮できると思います。また、必要性に応じて短時間でコンテナの作成・削除を行いたいというニーズがあった場合でも満足できると思います。

 必要になったら必要なだけDockerコンテナを起動して、不要になったり、トラブルが発生した場合は、問答無用に削除する使い方が出来ます。

 よって、Dockerコンテナ内のデータが更新されないようなシステムを作れば、Dockerにとっても好都合ということになります。

 しかし、どんなサービスでも、システムとしてとらえた場合、システム運用として必要な更新データが必ずあるのではないでしょうか。例えばログファイルなどです。

 システム内のデータについてはお構いなしで、トラブったらなにも考えずにリブートとか、壊れたら即作り直しなどが許されるシステムなら大丈夫なのかもしれませんが、そうでない場合は保存しておきたい情報は何かしらあるはずです。

 それでも私の意見としましては、Dockerコンテナのバックアップは、行わないほうが良いと考えます。

 つまり、Dockerコンテナのバックアップを行わずに、Dockerコンテナ内の更新データを保存する方法があれば、これらのモヤモヤが解決できることになります。

 このニーズを解決してくれる仕組みがDockerには用意されてます。

 それは、Dockerコンテナ外のディスク領域をマウントして利用できるデータボリュームという機能です。Dockerコンテナ内の永続的に必要なデータは、このデータボリューム領域に保存することで、Dockerコンテナが障害で消えてしまったとしても、大事なデータは残ることになります。

 よって、Dockerコンテナのバックアップは行わずに、データボリューム内のデータだけをきちんとバックアップしておけば良いことになります。

 では、どのようにデータボリュームのバックアップを行えば良いのでしょうか。

 

Dockerのデータボリュームのバックアップの考え方

 データボリュームでのバックアップを考える前に、データボリュームとはどういうものかについて理解しておく必要があります。

 データボリュームについては、Docker公式ドキュメント(日本語あり)に詳しく書かれてますので、そちらをご参照いただければと思います。また、本サイトでも、紹介させていただいてます(Dockerのデータボリュームについてもう少し詳しい説明)ので、ご利用いただけると嬉しいです。

 Dockerコンテナ内の更新データを含んだ全データをアーカイブするコマンドとして「docker export」があります。このコマンドは、現状のDockerコンテナの状態をtarファイルに保存するコマンドです。しかし、このコマンドはコンテナ内の更新データイメージ(コンテナレイヤー)とコンテナの起動に使用したDockerイメージをアーカイブするコマンドですので、Dockerコンテナにマウントされているデータボリュームはアーカイブされません。

 ですので、データボリュームのバックアップとしては利用できません。

 あとは、以下の2つの方法が考えられます。

  1. コンテナの中で、データボリュームがマウントされているマウントポイント以下のデータをアーカイブして、そのファイルをコンテナから取り出して保管する
  2. Dockerコンテナの外にある、データボリュームの実体に何らかの方法でアクセスして、データをアーカイブする

「1」の方法は一見単純明快そうですが、実は落とし穴があります。

 通常、Dockerコンテナは、サービスのメインプロセスの起動と共に生成されます。ApacheのWebサービスのコンテナであればメインプロセスはhttpdになります。mysqlのDBサービスの場合は、mysqldになります。

 バックアップを取得する場合は、バックアップ対象ファイルがCloseされている状態で行うのが定石です。しかし、「1」の方法では、バックアップを取得するために、サービスのプロセスを終了すると、Dockerコンテナも停止してしまいます。この状態では、Dockerコンテナ内部からデータボリュームにアクセスできません。

 systemdを起動するDockerコンテナを作成して、そのsystemd配下でサービスを起動するようにすれば、解決するかもしれませんが、今度はsystemdに関してのバックアップを検討する必要が出てくるかもしれません。にわとりと卵状態ですね。

よって、「2」の考え方で進めた方が無難と思います。

 「2」の方は、どのようにデータボリュームの実体にアクセスするかがポイントになります。

 データボリュームはDockerデーモンによって管理されておりますが、実体は「Docker Root Dir」パラメータとして定義されているディレクトリ下に存在します。「Docker Root Dir」パラメータは「docker info」コマンドで確認できます。DockerホストがLinuxの場合は、デフォルトは「/var/lib/docker」です。

 データボリュームの実体のある場所は、「docker volume」コマンドを駆使すれば、その物理パスを調べることが出来ます。しかし、対象のデータボリュームの物理パスが判明したところで、そこにDockerホストから直接アクセスしてバックアップして良いという記述は、Docker社の公式ドキュメントからは見つけられませんでした。なんとなくバックアップできそうな気はするのですが、Docker社が出来るという方法でないと、思いもしないトラブルが発生しかねません。

 Dockerのバックアップについて色々調べているうちに、「docker run」のオプションである「- -volumes-from」というオプションの存在にたどり着きました。

※Docker公式Doc内のサイト内検索で「バックアップ」というキーワードで検索すると「コンテナでデータを管理」というページが見つかりまして、そのページ内に情報がありました。

 このオプションでDockerコンテナのID若しくは名前を指定してコンテナを起動すると、オプションで指定したDockerコンテナが使用しているデータボリュームを自分にマウントして、Dockerコンテナを起動することが出来るという魔法のようなオプションです。

 もちろん、停止しているDockerコンテナを「- -volumes-from」で指定することも可能です!

 次の章でこのオプションを使ったバックアップを行う方法を紹介いたします。

 

(注意)
本記事は、データボリュームのデータをtarでバックアップする方法になりますので、商用DBなど、莫大な量のデータをバックアップすることは運用的に無理と思います。よって、tarでバックアップ取得が可能なシステムを対象とさせていただきます。

■ 本記事の目次に戻る ■

 

 

「- -volumes-from」オプションを使ったDockerのデータボリュームのバックアップの方法

 「- -volumes-from」オプションを使ったバックアップの方法は以下の流れになります。

※以下の内容は、Docker公式サイトの情報では一部省略されている箇所がありましたので、その部分を補ったものになっております。

  1. バックアップ対象データボリュームのマウントポイントを調べる。これは、バックアップ対象データボリュームを使用しているDockerコンテナ(以下コンテナAと記す)の詳細情報を「docker inspect」コマンドを使用して調べる。
  2. コンテナAを停止する
  3. tarなどのアーカイブソフトを起動するためのバックアップコンテナ(以下コンテナBと記す)を起動する。起動する際のオプションに「- -volumes-from コンテナA」を付与する。またコンテナA内で実行するコマンドとして、「1」で判明したマウントポイント内のファイルをアーカイブするtarコマンドを記述する。(マウントポイントが複数個あった場合は複数回実行する)
  4. データボリュームをアーカイブしたファイルをコンテナBから取り出す。
  5. コンテナAを起動する
  6. コンテナBから取り出したアーカイブしたファイルをバックアップする

 上の手順では、「1」と「3」がポイントになります。

 コンテナA内で使用しているデータボリュームのマウントポイントが判らないと、「3」でどこをアーカイブして良いか判断できないということです。

 ここを自動化しないと、コンテナの種類の数だけバックアップスクリプトが存在することになります。

 対象コンテナを指定するだけで、そのコンテナ内のデータボリュームのマウントポイントを自動的に調べるスクリプトを自作しようと、少しだけ頑張ろうと思ったこともあったのですが、もしかしたら同じことを考えてて、自作してしまっている人がいるかもと思い、2時間だけ調べようと決めて調べてみました。

 そして、見つけました!次の章で紹介させていただきます。

■ 本記事の目次に戻る ■

Dockerのデータボリュームのバックアップツールboombatower/docker-backupの紹介

 DockerHUB内で「boombatower/docker-backup」を検索すると出てきます。説明文は英語です。

 対象のDockerコンテナを「- -volumes-from」オプションで指定して、「docker run」で起動して使用します。

 ちなみに、このツールの心臓部は非常にシンプルなシェルスクリプトです。実行内容が明確に分かるので安心して使うことが出来ます。でも、ご使用になる場合は「自己責任」でお願いします!

 前の章で、バックアップ対象コンテナ内のデータボリューム情報を取得するところがポイントで、その情報は「docker inspect」で調べると書きましたが、スクリプトを覗いてみたところ、このツールは、対象コンテナ内のOS情報を参照して調べてました。

 「docker inspect」の情報ですと、Dockerコンテナに関する情報しか出力されませんが、対象コンテナ内のOS情報だと、Docker関連の情報以外の情報も含まれてます。よって「docker inspect」の情報を使用するよりも、柔軟な対応が出来てとても良いと思います。

 前置きはこのくらいにして、このツールを使用したバックアップを、実例を使ってご紹介します。

 

検証環境について: バックアップ対象コンテナ情報

 コンテナ名:dataserver1

 データボリューム情報:/opt/data1,/var/log

 使用シェル:bash

 

 1.バックアップ対象コンテナを停止する

$ docker stop dataserver1

 2.バックアップツールを起動する

$ docker run --rm --volumes-from dataserver1 -v $(pwd):/backup boombatower/docker-backup backup

 3.カレントディレクトリ内にデータボリュームのバックアップファイル「backup.tar.xz」が作成されていることを確認する

$ ls -l

 4.バックアップ対象コンテナを停止する

$ docker start dataserver1

 5.バックアップファイルを安全な場所にコピーする

手順省略

 

 以上です。データボリューム情報は特に指定する必要はありません。ツール内で自動取得です。

 この方法ですと、バックアップ対象コンテナ名(若しくはID)の情報だけでデータボリュームのバックアップを行うことが出来ます。

 このツールはリストアもサポートしてます。申し訳ございませんが、リストア機能に関しましては割愛させていただきます。自分では検証済みです。

■ 本記事の目次に戻る ■

まとめ

 今回は、Dockerにおけるバックアップの考え方から、手動での取得方法、更に半自動での取得方法について長々と書かせていただきました。

 私は、Dockerコンテナはdocker-composeを使用して管理してるのですが、docker-composeを使う場合は、複数コンテナで1つのサービスを作ることが多いです。

 その環境にこのバックアップツールを適用した場合、docker-composeが秀逸なだけに、バックアップを複数回行う面倒さが際立ってました。

 現在は、docker-composeの「ps」オプションでコンテナ群のIDを取得して、そのIDリスト内のコンテナに対して1つずつバックアップを行うスクリプトを自作して運用しております。

 なので今は、docker-composeの環境単位に、docker-compose.ymlファイルが存在するディレクトリを指定してスクリプトを実行するだけでバックアップが完了するようになりました。

 皆さんはDockerのバックアップについてどのようなお考えをお持ちでしょうか。もしご意見などございましたら是非コメントをお願いいたします。

 より良い環境構築のために参考にさせていただきたいです。

 長くなりましたが、最後までお読みいただき本当にありがとうございました。

■ 本記事の目次に戻る ■


コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です