Docker的卷
因为对于docker的卷不太理解,所以写下了自己的备忘录。
目标
-
- Docker V18.09
-
- Linux 4.18.0-16(ホストがWindowsのケースは対象としません)
- dockerコマンド(Dockerfile/docker composeについては応用だと思うので触れません)
何が分からなかったか
$ docker volume ls
DRIVER VOLUME NAME
local ad4c0f7038a3a323f6669ac59065248fa30796027d63c831fb498888caf1f214
local c2d816bc17333b5665785ff55e725b1c4862e0517a5f1e6c9d6c0ec1e6536857
local da512d42f360b623034937d44e0b158ed075c6ad285b7f2a2a268f1235e5cf7b
为什么会有这种东西留下来呢?
调查 chá)
阅读Docker文档并在实际环境中进行确认。
调查音量属性的方法有5种。
$ docker volume inspect ad4c0f7038a3a323f6669ac59065248fa30796027d63c831fb498888caf1f214
[
{
"CreatedAt": "2019-03-09T06:36:48+09:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/ad4c0f7038a3a323f6669ac59065248fa30796027d63c831fb498888caf1f214/_data",
"Name": "ad4c0f7038a3a323f6669ac59065248fa30796027d63c831fb498888caf1f214",
"Options": null,
"Scope": "local"
}
]
只是看这个也不会增加多少信息。似乎做复杂的事情才有用。
音量是用来做什么的?2
在容器/镜像外部存储目录/文件的东西。
它是由Docker提供的机制,并可以从多个容器中挂载。
攀比?3
将容器或镜像外部的目录或文件让容器能够访问。可以使用docker run选项–mount进行指定。共享类型有以下三种。
-
- bind: ホストにあるディレクトリやファイルの直接マウント
-
- volume: dockerが管理しているボリュームのマウント
- tmpfs: tmpfs(メモリを使ったファイルシステム)のマウント
音量挂载2
docker runのオプション–mountか–volumeでマウントできる。
ここでは–volumeによるマウントのみを説明する(tmpfsを除くと機能的には同じなので)。
指定されたvolumeが未作成の場合は、自動的に作成される。
在容器外部进行目录或文件的挂载(相当于bind)。
用字符串 “[主机路径] : [容器路径] : [挂载选项]” 进行指定。
$ docker run --volume $PWD/hoge:/home/hoge -it --name=mybash bash
bash-5.0# ls -lAF /home/hoge
total 4
-rw-rw-r-- 1 1000 1001 6 Mar 8 22:56 fuga.txt
bash-5.0#
上の例では、ホスト上の./hogeディレクトリをコンテナ上の/home/hogeにマウントしている。
コンテナの中でlsを実行しているが、見えているファイルfuga.txtは、ホスト上のファイル。
bind相当だと、volumeは作成されない。
mountのtypeも実際にbindとなる。
dockerが管理しているディレクトリやファイルのマウント(volume相当)
用以下的字符串来指定:[名称(可省略)]:[容器路径]:[挂载选项]
$ docker run --volume /home/hoge -it --name=mybash bash
bash-5.0# ls -lAF /home/hoge
total 0
bash-5.0#
在上面的例子中,使用匿名方式创建了一个新的卷,并将其挂载到容器的/home/hoge目录下。
在容器内执行了ls命令,但由于刚刚创建,所以是空的。
相当于创建了一个volume,因此会创建一个volume。
确认音量
实际上,在这个时间点上从另一台设备上观察一下…
$ docker volume ls
DRIVER VOLUME NAME
local 9274a58e30ad65cac10d469e513a8900194816ff8ae0d0be78c3d4a42d70f0f3 ←コレ
local ad4c0f7038a3a323f6669ac59065248fa30796027d63c831fb498888caf1f214
local c2d816bc17333b5665785ff55e725b1c4862e0517a5f1e6c9d6c0ec1e6536857
local da512d42f360b623034937d44e0b158ed075c6ad285b7f2a2a268f1235e5cf7b
我可以看出它已经被制作出来了。我试着检查一下……
$ docker volume inspect 9274a58e30ad65cac10d469e513a8900194816ff8ae0d0be78c3d4a42d70f0f3
[
{
"CreatedAt": "2019-03-09T19:31:49+09:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/9274a58e30ad65cac10d469e513a8900194816ff8ae0d0be78c3d4a42d70f0f3/_data",
"Name": "9274a58e30ad65cac10d469e513a8900194816ff8ae0d0be78c3d4a42d70f0f3",
"Options": null,
"Scope": "local"
}
]
音量的实质
由于我对挂载点的内容感到好奇,所以我试着从容器中创建一个文件。
bash-5.0# touch /home/hoge/touch
如果在主机上检查“Mount”点,会发现…
$ sudo ls -lAF /var/lib/docker/volumes/9274a58e30ad65cac10d469e513a8900194816ff8ae0d0be78c3d4a42d70f0f3/_data
合計 0
-rw-r--r-- 1 root root 0 3月 9 19:48 touch
実体がここにあることが分かる(ドキュメントでは言及されていないので実装依存)。
また、マウント方法も気になるので確認してみる(コンテナの中から、mountコマンドで確認する)。
bash-5.0# mount | grep /home/hoge
/dev/sda1 on /home/hoge type ext4 (rw,relatime)
通常のデバイスをマウントする形になっているので、overlayでないことが分かる。
つまり、ボリュームはコンテナ/イメージの外にあり、版管理されないと分かる。
削除
由于卷可能被多个容器/镜像引用,所以在删除容器或镜像时,卷默认情况下不会被删除,必须进行显式删除。
コンテナの削除と同時に削除する
$ docker container rm -v mybash
mybash
-vオプションが関連するボリュームを同時に削除するという意味。
なお、imageには匿名の新規のボリューム以外はcommitしても残らないように見え、docker image rmにも-vオプションは存在しない。
直接指定音量进行删除。
這種情況適用於留有不明身分的匿名(自動生成的名字)收集量,就像這次一樣。
$ docker container inspect mybash | grep /var/lib/docker/volumes
"Source": "/var/lib/docker/volumes/2d7f06255d264378aaec4443bb09788246f300e5141df1164221a53d406a9d0a/_data",
$ docker container rm mybash
mybash
$ docker volume rm 2d7f06255d264378aaec4443bb09788246f300e5141df1164221a53d406a9d0a
2d7f06255d264378aaec4443bb09788246f300e5141df1164221a53d406a9d0a
如果没有容器存在,可以启动挂载的容器并检查其内容。可以查看/var/lib/docker/volumes/[名字]/_data,但这取决于具体的实现。
在容器运行时指定删除结束时刻
$ docker run --rm --volume /home/hoge -it --name=mybash bash
在容器执行完成时,容器内的卷也会被删除(仅限于匿名卷)。
清除所有
$ docker volume prune
现在要删除所有未使用的卷。
也就是说,如果当前没有正在运行的容器使用该卷,那么将完全删除未来可能需要的卷。
所以,你了解了什么?
-
- コンテナ終了時に不要なボリュームが削除するように構成を考える
-
- コンテナ終了後も必要なボリュームは、面倒でも予め名前を付けておく
- 名前も中身も分からないボリュームが残っていた場合はマウントして中身を確認する
事实上
实际上,剩下的卷只是垃圾。
可能是因为没有在docker-compose或其他方式中附加-v参数来手动启动的容器被删除了,所以才会有残留。
Docker数据管理
使用卷
使用绑定挂载
使用临时挂载
Docker卷检查