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

Docker公式ロゴ1a
©2023 Docker Inc. All rights reserved

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

 DockerコンテナのベースとなるDockerイメージはリードオンリーですし、もし更新が発生しない、もしくは更新情報が無視できるDockerコンテナがあったとしたら、Dockerとして最高のパフォーマンスを発揮できると思います。

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

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

 例えばログファイルなどです。

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

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

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

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

 それは、Dockerコンテナ外のディスク領域をマウントして利用できるデータボリュームという機能です。

 本記事では、データボリュームについて簡単に解説した後、データボリュームの効率的なバックアップ方法をご紹介しております。

 Docker環境全般のバックアップの考え方に関しましては、別記事「Docker環境におけるバックアップ用ハザードマップの紹介」でご紹介しておりますので、よろしかったらご利用ください。

Dockerのデータボリュームとは

 データボリュームは、DockerホストのDisk領域上に作成された、Dockerコンテナにマウントすることが可能な仮想領域です。

 docker volumeコマンドで明示的に作成することができます。また、Dockerコンテナ起動時に、オプションでDockerホスト内の特定のディレクトリを指定して、Dockerコンテナにデータボリュームとしてマウントさせることも可能です。

 データボリュームは、明示的に削除する以外は基本的に削除されません。

 Dockerコンテナ内の永続的に必要なデータは、このデータボリューム領域に保存することで、Dockerコンテナが障害で消えてしまったとしても、大事なデータは残ることになります。

 データボリュームの詳細については、Docker公式ドキュメント(日本語あり)に詳しく書かれてますので、そちらをご参照いただければと思います。

 また、本サイトの別記事「Dockerのデータボリュームについてもう少し詳しい説明」でも紹介させていただいてますのでご利用ください。

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

 データボリュームに保存するデータは、ほとんどの場合、動的なデータ(頻繁に更新されるデータ)です。

 よって、バックアップするためにはDockerコンテナを停止して、保存データが更新されない状態にする必要があるでしょう。

 そのため、停止しているDockerコンテナ内のデータボリュームにアクセス可能な方法でバックアップできなければいけません。

 Dockerコンテナ内のファイルをtar形式で出力する場合はdocker exportコマンドがありまして、停止中のDockerコンテナであってもtarファイルに出力可能です。

 しかし、データボリューム内のファイルは対象外で出力されません。

 データボリュームのバックアップ方法としましては、以下の2つの方法が考えられます。

  1. docker cpコマンドでDockerコンテナ内のデータボリュームを指定してtarファイルにコピーする
  2. バックアップ対象のデータボリュームを他のDockerコンテナにマウントしてバックアップする

 1.のdocker cpコマンドを使用する方は、以下のフォーマットでコマンドを実行します。

$ docker cp [Dockerコンテナ名orコンテナID]:[バックアップ対象ディレクトリ名] - > [出力先のtarファイル名]

 docker cpコマンドはDockerコンテナとDockerホスト間でファイルの受け渡しを行う場合に使用しますが、コマンドの引数に「-(ハイフン)」を使用することによって入出力にtarファイルを指定可能です。

 コピー元として停止中のDockerコンテナを指定できますので、バックアップ機能として利用することができます。

以前の記事で、停止中のDockerコンテナ内のファイルをコピーすることはできない、旨の内容を記載しておりましたが、実際は可能でした。訂正してお詫びいたします。

 2.の他のコンテナにマウントする方法は、Dockerコンテナを起動する場合に使用するdocker runコマンド使います。

 docker runコマンドのオプションに「--volumes-from」がありまして、引数として指定した他のDockerコンテナが使用しているデータボリュームを自分にマウントすることができます。複数のデータボリュームを使用している場合でも、全てマウントされます。

 もちろん、停止しているDockerコンテナを指定することも可能です。

 1.の方法ですと、バックアップ対象のDockerコンテナにマウントされているデータボリュームを1つずつdocker cpコマンドでコピーする必要がありますが、2.の方法ですとtarコマンドに複数のコピー元ディレクトリを指定できますので便利そうです。

 次の章では、2.の方法でバックアップを行う方法を紹介いたします。

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

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

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

  1. バックアップ対象のDockerコンテナ(以下コンテナA)を停止する
  2. tarコマンドを実行するための「--volumes-from」オプションを指定して起動するバックアップ用コンテナ(以下コンテナBと記す)を起動する。起動する際のオプションに「--volumes-from <コンテナA>」を付与する。
  3. コンテナBにマウントされているデータボリュームの内容をtarファイルに出力する
  4. 出力したtarファイルをコンテナBから取り出す。
  5. コンテナAを起動する
  6. コンテナBから取り出したアーカイブしたファイルをバックアップする

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

 コンテナBにマウントされているデータボリュームのマウントポイントが判らないと、どこをアーカイブして良いか判断できません。

 Dockerコンテナにマウントされているディレクトリ情報はDocker inspectコマンドで取得できますので、シェルスクリプトの作り込みが必要になります。

 上の青枠部分の内容を参考にシェルスクリプトを組んでいただければと思います。

 シェルスクリプトの作り込みが困難な場合は、次章でご紹介しますツールのご利用をオススメします。

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

 オススメしますのは、「boombatower/docker-backup」というツールになります。

 Docker公式レジストリであるDockerHUB内で「boombatower/docker-backup」を検索すると出てきます。

 使い方は、対象のDockerコンテナを「--volumes-from」オプションで指定して、「docker run」で起動するだけです。

 ちなみに、このバックアップ用コンテナの中身を確認したところ、バックアップ処理を行っていますのは非常にシンプルなシェルスクリプトでした。実行内容が明確に分かるので安心して使うことができます。でも、ご使用になる場合は「自己責任」でお願いします。

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

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

 また、バックアップしたファイルが格納されているtarファイルは、バックアップ用コンテナから取り出さなくても、ツールを実行したカレントディレクトリ内に出力されるようになっていました。

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

 バックアップ対象コンテナの名前はdataserver1とします。

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ファイルが存在するディレクトリを指定してスクリプトを実行するだけでバックアップが完了するようになりました。

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

 最後までお読みいただき本当にありがとうございました!

コメント