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卷检查