Dockerのデータボリュームをバックアップ・リストアする

公開日:2023年02月11日
最終更新日:2023年02月11日
レベル:★★★☆☆
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)

実際にデータベースにアクセスし、問題なければリストア完了です。

ー 以上 ー

 CMSを使ったホームページ制作
 VPS, AWS等クラウドシステム構築
等々のご依頼承っております

Contents