Dockerコンテナを移行してみる【成功編】

#背景
ある環境で建てたDockerコンテナを別のホストに移行し、データ等が適切に引き継がれるかテストしたいと考えました。

失敗編はこちら→[Dockerコンテナを移行してみる【失敗編】](https://qiita.com/Osbrewery/items/91908e40af6661adebaf)

#前提環境
移行元・移行先ともに
OS：CentOS Linux release 7.4.1708 (Core)
Docker：Docker version 17.12.1-ce, build 7390fc6
コンテナ：wordpressとmysql

#流れ
Dockerイメージにはデータボリュームが含まれず、イメージのみ移行してもデータは伴わない。
従ってデータボリュームを別途バックアップし、移行する必要がある。

※そもそもイメージをバックアップすることはDockerの仕様上ナンセンスな考え方です。
本来であればDockerfileなどでイメージを指定してあげて、Docker Hubなどにイメージを取りに行く構成にしておき、そのDockerfileとボリュームを移行するのがスマートなやり方です。

★イメージのバックアップ
・コンテナをイメージに変換
・イメージをtarに変換

★データボリュームのバックアップ
・データボリュームをtarに変換

★イメージのリストア
・イメージのtarファイルを移行先で展開

★データボリュームのリストア
・データボリュームのtarファイルを移行先で展開
・データボリュームを指定する形でコンテナを構築


#ゴール
予め移行元の環境でWordpressをカスタマイズしておき、移行先でコンテナを展開した際に同じカスタマイズされたページが出ればOK
![image.png](https://qiita-image-store.s3.amazonaws.com/0/167392/9afb51c1-1559-8064-1552-4708188ed4e1.png)

#手順
###イメージのバックアップ&リストア
イメージの展開までは失敗編と同じですので、そちらに記載します。

###データボリュームのバックアップ
移行元のコンテナがどのボリュームを使用しているか確認します。
`docker inspect <CONTAINER ID>`を実行し、Mounts欄に記載があります。

```shell:確認
[root@docker01 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
e43ffef0e6c0        wordpress           "docker-entrypoint.s…"   10 days ago         Up 10 days          0.0.0.0:8080->80/tcp   tvc-wordpress
04f6a48f8168        mysql               "docker-entrypoint.s…"   10 days ago         Up 10 days          3306/tcp               wordpress-mysql
[root@docker01 ~]# 
[root@docker01 ~]# 
[root@docker01 ~]# docker inspect e43ffef0e6c0
(省略)
        "Mounts": [
            {
                "Type": "volume",
                "Name": "deccf2f2935ae370a10eb76322bc05001436f2b0ade81a599d1c0e95816a8102",
                "Source": "/var/lib/docker/volumes/deccf2f2935ae370a10eb76322bc05001436f2b0ade81a599d1c0e95816a8102/_data",
                "Destination": "/var/www/html",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }

[root@docker01 ~]# docker inspect 04f6a48f8168
(省略)
        "Mounts": [
            {
                "Type": "volume",
                "Name": "b13f46758c4269717295cdf90fffc584c1620303b76ac489d31f8fff11e3ce98",
                "Source": "/var/lib/docker/volumes/b13f46758c4269717295cdf90fffc584c1620303b76ac489d31f8fff11e3ce98/_data",
                "Destination": "/var/lib/mysql",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],


```

この
"Source"はホストのパス
"Destination"はコンテナ上のパス
を指しています。

従って、Sourceをバックアップ&リストアし、そのパスをDestinationにマウントする形でコンテナを構築してあげればOKということです。

なのでtarで丸めてscpで転送します。


###データボリュームのリストア
転送先にログインし、`tar -xvf`でデータボリュームを展開します。

```shell:イメージの確認
[root@docker02 volumes]# docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
<none>              <none>              1783ef16ab30        2 days ago          371MB
mysql_trans         latest              7ea06243cc0f        10 days ago         371MB
wordpress_trans     latest              8c6f718cfe06        10 days ago         408MB
```

続いて展開したボリュームを指定してコンテナを構築します。


```
docker run -v <ホストのパス(Source)>:<コンテナのパス(Destination)> --name <コンテナ名>　-e <mysqlで構成する内容> -d <イメージ>
```


```shell

[root@docker02 volumes]# docker run -v /var/lib/docker/volumes/b13f46758c4269717295cdf90fffc584c1620303b76ac489d31f8fff11e3ce98/_data:/var/lib/mysql --name wordpress-mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_USER=root -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=wordpressdb -d mysql_trans
36e2610ec602e4fd6860b426435e76bf9cf42fa236e150639ce72d7136c62d90
[root@docker02 volumes]#
[root@docker02 volumes]# docker run -v /var/lib/docker/volumes/deccf2f2935ae370a10eb76322bc05001436f2b0ade81a599d1c0e95816a8102/_data/:/var/www/html --name tvc-wordpress -p 8080:80 --link wordpress-mysql:mysql -d wordpress_trans
e4b466ce62230b196cf6327edd47600df1a965404ab7d63edf5e51585f1d1546
[root@docker02 volumes]# 
[root@docker02 volumes]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                  NAMES
e4b466ce6223        wordpress_trans     "docker-entrypoint.s…"   4 seconds ago       Up 2 seconds        0.0.0.0:8080->80/tcp   tvc-wordpress
36e2610ec602        mysql_trans         "docker-entrypoint.s…"   7 minutes ago       Up 7 minutes        3306/tcp               wordpress-mysql

```

ここで詰まったのが以下エラー。
-vオプションを一番最後につけてしまうとコマンドとして認識されてしまい、適切に起動しません。

```
[root@docker02 volumes]# docker run --name wordpress-mysql -e MYSQL_ROOT_PASSWORD=password -e MYSQL_USER=root -e MYSQL_PASSWORD=password -e MYSQL_DATABASE=wordpressdb -d mysql_trans -v /var/lib/docker/volumes/b13f46758c4269717295cdf90fffc584c1620303b76ac489d31f8fff11e3ce98/_data:/var/lib/mysql
75b58db699fa0a299587f7f49b932eb8ee7244ca045ead99e5f86a3540072460
[root@docker02 volumes]# 
[root@docker02 volumes]# 
[root@docker02 volumes]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
75b58db699fa        mysql_trans         "docker-entrypoint.s…"   9 seconds ago       Exited (1) 8 seconds ago                       wordpress-mysql
[root@docker02 volumes]# 
[root@docker02 volumes]# 
[root@docker02 volumes]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@docker02 volumes]# 
[root@docker02 volumes]# 
[root@docker02 volumes]# docker start 75b
75b
[root@docker02 volumes]# 
[root@docker02 volumes]# 
[root@docker02 volumes]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
[root@docker02 volumes]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
75b58db699fa        mysql_trans         "docker-entrypoint.s…"   2 minutes ago       Exited (1) 7 seconds ago                       wordpress-mysql
[root@docker02 volumes]# 

[root@docker02 volumes]# docker logs 75b

ERROR: mysqld failed while attempting to check config
command was: "mysqld -v /var/lib/docker/volumes/b13f46758c4269717295cdf90fffc584c1620303b76ac489d31f8fff11e3ce98/_data:/var/lib/mysql --verbose --help"

2018-04-16T08:56:05.485415Z 0 [ERROR] Too many arguments (first extra is '/var/lib/docker/volumes/b13f46758c4269717295cdf90fffc584c1620303b76ac489d31f8fff11e3ce98/_data:/var/lib/mysql').
2018-04-16T08:56:05.490059Z 0 [ERROR] Aborting

```
変なエラーを出し、すぐExitしてしまいます。


まあ何はともあれコンテナが起動したので
`http://<IP Address>:8080`
にアクセスしてみましょう。

#結果
移行元でカスタマイズしたページと同じものが復元されました！
見た目は同じですが、アクセスしているIPが別です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/167392/cfbbf957-002d-1671-1dc5-51a978690a39.png)

めでたくこれで移行が完了しました！


#参考
[Dockerのシステム移行手順（バックアップおよび復元方法）](https://qiita.com/mikoski01/items/7d71ef7d167a6b78219a)

[Dockerのバックアップの考え方とその方法について](http://www.memotansu.jp/2016/09/docker/489/)