Dockerのデータボリュームをバックアップ・リストアする
Dockerで環境を構築し運用するにあたり、データを永続化して保持したい場合が出てきます(Dockerで構築した場合、コンテナを破棄するとそのままではデータも消えてしまいます)。
対策として「バインドマウント」という仕組みを使ってホスト側のファイルやディレクトリをコンテナ側にマウントする方法とともに「データボリューム」(または「ボリューム」)という仕組みがあります。
一方でDockerで実運用を始めると障害対策などの理由で永続化したデータをバックアップする必要も出てきます。
「バインドマウント」の場合であれば、ホスト側のファイルやディレクトリをバックアップすれば良いのですが、データボリュームの場合は単純にデータボリュームを構成するファイルをバックアップすれば良いというわけにはいきません。
データボリュームの実態ファイルはLinuxの場合「/var/lib/docker/volumes/」以下にあります。macOSの場合はDocker EngineのVM(~/Library/Containers/Docker/Data/vms/0/)で動いているのでFinder等で直接参照できません。
データボリュームの場所は「docker volume inspect データボリューム名」で確認できます。
今回は、データボリュームに保存したファイル類をバックアップ・リストアする方法をご紹介します。
バックアップ
バックアップするDocker環境
バックアップするDockerコンテナはDocker Composeで動かすものとし、docker-compose.ymlは下記のようなものとします。
# vi backup_test/docker-compose.yml
version: "3.7"
x-db: &DB_SERVER
"backupdb"
x-web: &WEB_SERVER
"backupweb"
services:
mysql:
build: ./mysql
container_name: *DB_SERVER
hostname: *DB_SERVER
volumes:
- "db_data:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: 'passwd'
TZ: 'Asia/Tokyo'
php-apache:
build: ./php
container_name: *WEB_SERVER
hostname: *WEB_SERVER
volumes:
- "./data/html:/var/www/html"
environment:
TZ: 'Asia/Tokyo'
ports:
- "80:80"
depends_on:
- mysql
volumes:
db_data:
※mysql,およびphp-apacheのDockerfileの設定は省略します。
バックアップ実行
今回の例では、データボリュームはMySQLのデータベースファイル(/var/lib/mysql/)の格納用に利用しており、データベースファイル全てをバックアップするものとします。
次のコマンドでデータボリュームをバックアップします。
# cd /var/home/core/backups/ <---- バックアップファイルを置くディレクトリに移動
# docker run --rm --volumes-from backupdb -v $(pwd):/backup busybox tar czf /backup/dbbackup.tar.gz /var/lib/mysql
- 「--volumes-from コンテナ名」で指定したコンテナ経由でデータボリュームにアクセスします。
- ファイルのバックアップには「busybox」という軽量Unixを利用します。バックアップコマンド(tar czf)実行後、コンテナは削除(--rm)されます。
※注意点:
この方法ではコンテナ「backupdb」を停止することができません。
コンテナ「backupdb」を停止できる環境であれば次のコマンドでバックアップすることもできます。
# docker volume ls <------- データボリュームの確認
DRIVER VOLUME NAME
local backup_test_db_data
# docker run --rm -v backup_test_db_data:/var/lib/mysql -v $(pwd):/backup busybox tar czf /backup/dbbackup.tar.gz /var/lib/mysql
リストア
リストアするDocker環境
リストアするDockerコンテナはDocker Composeで動かすものとし、docker-compose.ymlは下記のようなものとします。
# vi restore_test/docker-compose.yml
version: "3.7"
x-db: &DB_SERVER
"restoredb"
x-web: &WEB_SERVER
"restoreweb"
services:
mysql:
build: ./mysql
container_name: *DB_SERVER
hostname: *DB_SERVER
volumes:
- "db_data:/var/lib/mysql"
environment:
MYSQL_ROOT_PASSWORD: 'passwd'
TZ: 'Asia/Tokyo'
php-apache:
build: ./php
container_name: *WEB_SERVER
hostname: *WEB_SERVER
volumes:
- "./data/html:/var/www/html"
environment:
TZ: 'Asia/Tokyo'
ports:
- "80:80"
depends_on:
- mysql
volumes:
db_data:
※mysql,およびphp-apacheのDockerfileの設定は省略します。
リストア実行
リストアするマシン(ホスト側:Dockerコンテナ側ではない)の適当なディレクトリにバックアップファイル(dbbackup.tar.gz)を準備します。
※Dockerコンテナがアクセスできる権限を持つ場所にバックアップファイルを置くことに注意。
リストアするコンテナのデータボリューム名を確認します。
# docker volume ls
DRIVER VOLUME NAME
local restore_test_db_data
コンテナの/var/lib/mysql/ディレクトリ内を確認します。
# docker run --rm -v restore_test_db_data:/var/lib/mysql -v $(pwd):/backup busybox ls /var/lib/mysql
-rw-r----- 1 999 999 196608 Feb 11 03:47 #ib_16384_0.dblwr
-rw-r----- 1 999 999 8585216 Feb 11 03:45 #ib_16384_1.dblwr
drwxr-x--- 2 999 999 4096 Feb 11 03:45 #innodb_redo
drwxr-x--- 2 999 999 4096 Feb 11 03:51 #innodb_temp
-rw-r----- 1 999 999 56 Feb 11 03:45 auto.cnf
-rw-r----- 1 999 999 3032843 Feb 11 03:45 binlog.000001
-rw-r----- 1 999 999 180 Feb 11 03:51 binlog.000002
-rw-r----- 1 999 999 32 Feb 11 03:45 binlog.index
-rw------- 1 999 999 1680 Feb 11 03:45 ca-key.pem
-rw-r--r-- 1 999 999 1112 Feb 11 03:45 ca.pem
-rw-r--r-- 1 999 999 1112 Feb 11 03:45 client-cert.pem
-rw------- 1 999 999 1680 Feb 11 03:45 client-key.pem
-rw-r----- 1 999 999 4140 Feb 11 03:51 ib_buffer_pool
-rw-r----- 1 999 999 12582912 Feb 11 03:51 ibdata1
drwxr-x--- 2 999 999 4096 Feb 11 03:45 mysql
-rw-r----- 1 999 999 31457280 Feb 11 03:45 mysql.ibd
lrwxrwxrwx 1 999 999 27 Feb 11 03:45 mysql.sock -> /var/run/mysqld/mysqld.sock
drwxr-x--- 2 999 999 4096 Feb 11 03:45 performance_schema
-rw------- 1 999 999 1680 Feb 11 03:45 private_key.pem
-rw-r--r-- 1 999 999 452 Feb 11 03:45 public_key.pem
-rw-r--r-- 1 999 999 1112 Feb 11 03:45 server-cert.pem
-rw------- 1 999 999 1676 Feb 11 03:45 server-key.pem
drwxr-x--- 2 999 999 4096 Feb 11 03:45 sys
-rw-r----- 1 999 999 16777216 Feb 11 03:47 undo_001
-rw-r----- 1 999 999 16777216 Feb 11 03:47 undo_002
/var/lib/mysql/ディレクトリ内の全てのファイル/ディレクトリを一旦削除します。
# docker run --rm -v restore_test_db_data:/var/lib/mysql busybox /bin/sh -c "rm -rf /var/lib/mysql/*"
削除確認:ファイルは何も残っていないことを確認します。
# docker run --rm -v restore_test_db_data:/var/lib/mysql -v $(pwd):/backup busybox ls -la /var/lib/mysql
total 8
drwxrwxrwt 2 999 999 4096 Feb 11 03:56 .
drwxr-xr-x 3 root root 4096 Feb 11 03:57 ..
バックアップファイルを/var/lib/mysql/以下に展開します。
# docker run --rm -v restore_test_db_data:/var/lib/mysql -v $(pwd):/backup busybox tar zxf /backup/dbbackup.tar.gz
リストアの確認
コンテナに入ります。
# docker container exec -it restoredb bash
bash-4.4#
コンテナのMySQLにログインしデータベースが存在していることを確認します。
bash-4.4# mysql -u root -p
Enter password: <-------- パスワードを入力(※バックアップしたデータベースのrootパスワードです)
Welcome to the MySQL monitor. Commands end with ; or \g.
:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
:
| mysql |
| performance_schema |
| sys |
+--------------------+
10 rows in set (0.01 sec)
実際にデータベースにアクセスし、問題なければリストア完了です。