docker run -vとDockerfileのVOLUMEは違うのか?
はじめに
最近dockerについてプログラマのためのDocker教科書(以下教科書と呼ぶ)で勉強し始めた。
プログラマのためのDocker教科書 インフラの基礎知識&コードによる環境構築の自動化
- 作者: 阿佐志保,山田祥寛
- 出版社/メーカー: 翔泳社
- 発売日: 2015/11/20
- メディア: 大型本
- この商品を含むブログ (3件) を見る
今回は、dockerを使ってデータの永続化という話でつまづいたときの整理をしたいと思う。
データの永続化とは、たとえばmysqlコンテナとデータコンテナを分けるということである。
たとえ前者を削除しても、データコンテナは別なのでデータを失うことはない。
別のバージョンのmysqlをデータコンテナにリンクさせることでポータビリティを保てるというメリットがあるわけだ。
教科書でデータ用のコンテナを作成するときに、次のDockerfileからイメージをビルドして作成している。
Dockerfile
# Dockerイメージの取得 FROM centos:latest ...(中略)... # ボリュームの作成 VOLUME /var/log/httpd
しかしここでいくつか気になる疑問がでてきたのだ。
- ファイル内のVOLUMEが指すものは、どこに存在するものなのか?(ホストのどこか?)
- Dokcerfileでイメージをビルドしないとデータ永続用コンテナは作成できないのか?
- docker runのvオプションとはVOLUMEは別物なのか?
この疑問に関して調べた結果を残そうと思う。 先に結論を述べると、vオプションでもVOLUMEも同じである。
docker run v
オプションについて
教科書には、vオプションについて次のように書かれてある。
docker run -v [ホストのディレクトリ]:[コンテナのディレクトリ]
ホストとコンテナでディレクトリを共有化する方法。
なるほど、この場合データの実態はホストに存在している。
では、次のように書くと何を意味するのか?
docker run -v /myvol -e MYSQL_ROOT_PASSWORD=mysql --name dbserver mysql
下図の通り確かにmyvolが作成されたコンテナに存在している。
が、それはどこに繋がれてる? ホストなのか?
実は、/myvolは、docker volumeに接続されている。
docker volume ls
と入力すると、dockerで作成されたボリュームができる。
ただし-v /myvol
とした場合、volume名がハッシュ化されてどの用途のボリュームなのかがわからなくなる。上図でも一つはmysqlコンテナ自体が使用しているボリュームで、もう一つは/myvolにマウントしているボリュームになるが、ハッシュ化されたVOLUME NAMEではわからない。
名前解決できない状況を回避するためには、ボリューム名を明示的に指定して作成し、それをマウントさせる。
docker volume create v1
docker run -v v1:/myvol -name dbserver mysql
v1という名前のボリュームの作成
作成したボリュームをマウントする
docker run -d --name dbserver -v v1:/myvol -e MYSQL_ROOT_PASSWORD=root mysql
docker volume ls
で確認
以上よりdocker run
のvオプションについてまとめると、
docker run -v [ホストのディレクトリ]:[コンテナのディレクトリ] mysql
ホストと共有化
docker run -v [dokcer volume]:[コンテナのディレクトリ] mysql
名前付きボリュームを指定ディレクトリにマウント
docker run -v [コンテナのディレクトリ] mysql
ハッシュ値のボリュームを指定したディレクトリにマウント
となり、最後の2つについては、起動コンテナと別のボリュームがマウントされ、名前付きかどうかが異なる
補足: rmオプションについて
docker rm
でコンテナを削除しても、vオプションで作られたボリュームは同時に削除されない。
コンテナが不要になったと同時に削除するには、rmオプションをつけて、docker run --rm -v v1:/myvol mysql
と入力する。
※それでもマウントしたv1ボリュームは削除されないことは注意
.DockerFile
のVOLUMEについて
教科書には、VOLUMEについてこう書かれている。
VOLUME ["/マウントポイント"]
指定したマウントポイントをコンテナ内に作成し、ホストやその他コンテナからボリュームの外部マウントを行います
よくわかりませんね。。。
なので、実際にDockerfileをつくってやってみましょう。
.DockerFile
FROM mysql VOLUME /myvol ENV MYSQL_ROOT_PASSWORD mysql
docker build -t dbesrver .
でイメージ作成して、
docker run -d -name db dbserver
でコンテナ起動
マウント状況を確認すると、
上図の通り、Dockerfileを利用した場合も新たにボリュームを作成して、VOLUMEで指定したディレクトリにマウントするという意味である。ボリュームに名前をつけていないので、起動したコンテナのボリュームの名前をハッシュ値となる。
(したがって、ボリュームが不要ならば--rm
オプションを付けた起動したほうがよい。)
結果
以上まとめて、はじめの疑問に回答すると
ファイル内のVOLUMEが指すものは、どこに存在するものなのか?(ホストのどこか?)
ホストに存在するが特定のディレクトリと共有してるわけではなく、
docker volumeとして作成された新たにボリュームを指しているDokcerfileでイメージをビルドしないとデータ永続用コンテナは作成できないのか?
docker run -v
からも作成可能docker runのvオプションとはVOLUMEは別物なのか?
同じである。 名前付きかどうかという違いがあるぐらいだ。
というわけでした。
参考サイト
詳しく書かれてあったのでわかりやすかったです。
https://qiita.com/namutaka/items/f6a574f75f0997a1bb1d https://qiita.com/mtgto/items/aabc212a1d3f99878828 https://qiita.com/gounx2/items/23b0dc8b8b95cc629f32