Docker Volume 使用总结
Docker的数据持久化主要有两种方式:bind mount
和 volume
,Docker的数据持久化要么存在于host的某个指定目录中(使用bind mount
),要么使用docker自己管理的volume
(/var/lib/docker/volumes
下)。
一. 使用bind mount方式
下面是挂载示例
docker run -itd -v $(pwd)/host-dava:/container-data centos:7.7.1908 /bin/bash
说明:
- host机器的目录路径必须为绝对路径,不然docker会将其当做
volume
而不是bind mount
处理. - 如果host机器上的目录不存在,docker会自动创建该目录.
- 如果container中的目录不存在,docker会自动创建该目录.
- 如果container中的目录已经有内容,那么docker会使用host上的目录将其覆盖掉.
二. 使用volume方式
docker的volume直接将数据写到host机器上,只是volume是被docker管理的,docker下所有的volume都在host机器上的指定目录下/var/lib/docker/volumes
。
2.1 创建volume
# 创建volume
docker volume create my-volume
# 查看所有volume
docker volume ls
DRIVER VOLUME NAME
local my-volume
# 查看指定volume详情
docker volume inspect my-volume
[
{
"CreatedAt": "2020-06-14T18:56:23+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/my-volume/_data",
"Name": "my-volume",
"Options": null,
"Scope": "local"
}
]
2.2 使用volume
# 运行容器时指定volume,如果my-volume不存在,docker会自动创建my-volume,然后再挂载。
docker run -itd -v my-volume:/container-data centos:7.7.1908 /bin/bash
说明:
- 多个容器可以使用同一个volume,同时使用时可能会有写冲突的问题。
- 如果volume是空的而container中的目录有内容,那么docker会将container目录中的内容拷贝到volume中。
- 如果volume中已经有内容,则会将container中的目录覆盖。
2.3 匿名volume
# 在创建volume时不指定名称,则会创建一个匿名volume
docker volume create
912caacbbaabdbec96389ebf58382309eb09c32f4198725c06fc5da61270968d
# 运行容器时不指定volume名称也会创建一个匿名volume
docker run -itd -v /container-data centos:7.7.1908 /bin/bash
2.4 Dockerfile 中的 volume
在Dockerfile中,可以使用VOLUME指令来申明contaienr中的某个目录需要映射为volume
#Dockerfile
VOLUME /foo
这表示,在docker运行时,docker会创建一个匿名的volume,并将此volume绑定到container的/foo目录中,如果container的/foo目录下已经有内容,则会将内容拷贝的volume中。也即,Dockerfile中的VOLUME /foo
与docker run -v /foo centos:7.7.1908
的效果一样。
Dockerfile
中的VOLUME
使每次运行一个新的container
时,都会为其自动创建一个匿名的volume
,如果需要在不同container
之间共享数据,那么我们依然需要通过docker run -it -v my-volume:/foo
的方式将/foo
中数据存放于指定的my-volume
中。因此,VOLUME /foo
在某些时候会产生歧义,如果不了解的话将导致问题。
三. docker-compose.yml中的使用
在docker-compose
中同样两种使用方式
# 创建volume的方式
version: '2.2'
volumes:
data01:
driver: local
data02:
driver: local
# 使用volume的方式
version: '2.2'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.7.1
volumes:
- data01:/usr/share/elasticsearch/data
# 使用bind的方式
version: '2.2'
services:
es01:
image: docker.elastic.co/elasticsearch/elasticsearch:7.7.1
volumes:
- /data/data1/es01:/usr/share/elasticsearch/data