DockerのVolumeについて

EC2(AmazonLinux2)環境にてDockerと戯れているのですが、
気がついたらホストOS上にマウントポイントが増殖していました。。。
そこでVolumeの理解を深める為に色々と試しました。

# DockerにおけるVOLUMEについて
Dockerリファレンスのdockerfile-VOLUMEの説明より抜粋
>VOLUME 命令は指定した名前でマウントポイントを作成し、他のホストやコンテナから外部マウント可能なボリュームにします。
`docker run` コマンドは、ベース・イメージから指定した場所に、データを保存する場所として新規作成したボリュームを初期化します。
  
これを読んで「コンテナ内にVOLUMEで指定したディレクトリが作成されるんだな」と理解はしましたが、**"他のホストやコンテナから外部マウント可能なボリュームにします"**という部分は、
コンテナ起動時(run)に`-v`でホストOS上のディレクトリとの紐付けを可能にするディレクトリを定義するという認識でした。(-vを指定しないと結局のところ永続化はされずデータは破棄される認識)

で、色々とVolumeの動作検証をしました。

# 検証環境  
- EC2 (Amazon Linux2)  

# 動作検証
- VOLUME指定の無いイメージ(CentOS)からコンテナ起動してみる(-v, --mount指定なし)

```
#Volumeは存在しない(コンテナ起動前)
[~]docker volume ls
DRIVER              VOLUME NAME

#CentOSイメージからコンテナ起動
[~]docker run --name test_container -dt centos

#Volumeは存在しない(コンテナ起動後)
docker volume ls
DRIVER              VOLUME NAME
```

- VOLUME指定のあるイメージからコンテナ起動してみる(-v, --mount指定なし)  
下記dockerfileを使用してCentOSイメージをベースにVolume指定されたイメージを作成して起動してみる

``` 
#dockerfile(CentOSイメージをベースにVolume=/test_volumeを定義)
ARG baseimagetag=latest
FROM centos:${baseimagetag} AS baseimage
VOLUME /test_volume

#dockerイメージ作成
[~]docker build -t centos_mod .

#Volumeは存在しない(コンテナ起動前)
[~]docker volume ls
DRIVER              VOLUME NAME

#CentOS(改変)イメージからコンテナ起動
[~]docker run --name test_container -dt centos_mod

#Volumeが作成される(コンテナ起動後)
docker volume ls
DRIVER              VOLUME NAME
local               ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b

#VolumeのホストOS上のマウントポイントを確認
#自動的に/var/lib/docker/volumes/配下にマウントポイントが作成されていることがわかる
[~]docker inspect ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b
[
    {
        "CreatedAt": "2020-07-10T08:30:00+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b/_data",
        "Name": "ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b",
        "Options": null,
        "Scope": "local"
    }
]

#コンテナ停止、削除
[~]docker stop test_container
[~]docker rm test_container

#Volumeが確認(コンテナ削除後)
#ホストOS上のマウントポイントは存在している
docker volume ls
DRIVER              VOLUME NAME
local               ec1feead17bb87e24d3e2e6db716daf58d12747cbdd0b510fd30f507d7f8308b
```

- VOLUME指定のあるイメージからコンテナ起動してみる(-v にてVolume名を指定)

```
#CentOS(改変)イメージからコンテナ起動(ホストOSのマウントポイントを名称(host_mount)で指定
[~]docker run --name test_container -v host_mount:/test_volume -dt centos_mod
baf6954e9dbce1dd9ad3ae5c8286e63c01fd39689d79053725ae1800b70ea752

#Volumeが作成される(コンテナ起動後)
[~]docker volume ls
DRIVER              VOLUME NAME
local               host_mount

#VolumeのホストOS上のマウントポイントを確認
#自動的に/var/lib/docker/volumes/配下に-vで指定した名前/_dataでマウントポイントが作成されていることがわかる
docker inspect host_mount
[
    {
        "CreatedAt": "2020-07-10T22:22:49+09:00",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/host_mount/_data",
        "Name": "host_mount",
        "Options": null,
        "Scope": "local"
    }
]
```

- VOLUME指定のあるイメージからコンテナ起動してみる(-v にてホストOS上のディレクトリを指定)

```
#CentOS(改変)イメージからコンテナ起動(ホストOSのマウントポイントをディレクトリ(/test_mount)で指定
[~]docker run --name test_container -v /test_mount:/test_volume -dt centos_mod
e5e70d6235dbfe54950e2053f61236c1450d43c0b3aacfa38341e37cfacecaaa

#Volumeの確認(コンテナ起動後)
#下記コマンドではマウントポイントは表示されない
[~]docker volume ls
DRIVER              VOLUME NAME

#コンテナ情報からマウントポイントを確認
[~]docker inspect test_container
##一部抜粋
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/test_mount",
                "Destination": "/test_volume",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
```

# 動作検証をして理解したこと
- VOLUMEが定義されたDockerイメージを使用してコンテナ起動すると、
VOLUMEで指定されたディレクトリが永続化領域としてコンテナ内に作成される
- Dockerコンテナ起動時(run)にVOLUMEで指定されたディレクトリに対応するホストOS上のマウントポイント(ディレクトリ)を指定しない場合、ホストOS上のDockerのVolume領域(上記検証では/var/lib/docker/volumes)にマウントポイントが自動で作成される
- 起動時にVOLUMEで指定されたディレクトリに対応するホストOS上のマウントポイント(名称)を指定した場合、無指定時と同様、ホストOS上のDockerのVolume領域にマウントポイントが指定した名称/_dataで作成される
- `docker volume ls`で表示されるマウントポイントはホストOS上のDockerのVolume領域(/var/lib/docker/volumes)に作成されたディレクトリを表示している  
※Volume領域以外のディレクトリをマウントポイントに指定した場合は表示されない
- ホストOS上に作成されたマウントポイントはコンテナを停止、破棄しても削除されない(永続化領域なんだから当たり前)  
※VOLUME指定されたイメージ(MySQLなど)からのコンテナ起動を繰り返していると認識していないディレクトリが山のように発生している可能性も。。)


# (おまけ)Volume指定されているイメージかを確認する方法
`docker inspect <イメージ名>`でイメージの情報を表示し、**"Volumes":** の部分にディレクトリが指定されてるかを確認する

例)MySQLコンテナの場合
永続化領域としてコンテナ内に/var/lib/mysqlが定義されている

```
"Volumes": {
        "/var/lib/mysql": {}
},
```