在容器中管理数据主要有两种方式:

  • 数据卷( Volumes )
  • 挂载主机目录 ( Bind Mounts )

关于使用:-v or --mount,新手推荐选择 --mount 参数,经验丰富的自由发挥。

容器数据卷#

数据卷(Volumes)是一个可供一个或多个容器使用的特殊目录它可以绕过 UFS,可以提供很多有用的特性:

  • 数据卷可以在容器之间共享和重用
  • 对数据卷的修改会立马生效
  • 对数据卷的更新不会影响镜像
  • 数据卷默认会一直存在,即使容器被删除

数据卷的使用,类似 Linux 下对目录或文件进行 mount,镜像中被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)

创建数据卷#

[root@wangpengliang ~]# docker volume create myredis
myredis

查看所有数据卷#

[root@wangpengliang ~]# docker volume ls
DRIVER    VOLUME NAME
local     myredis

查看指定数据卷#

[root@wangpengliang ~]# docker volume inspect myredis
[
    {
        "CreatedAt": "2021-05-26T13:35:05+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/myredis/_data",
        "Name": "myredis",
        "Options": {},
        "Scope": "local"
    }
]

启动容器#

使用 docker run 命令时,使用 --mount 标记来将数据卷挂载到容器里。在一次docker run中可以挂载多个数据卷。

docker run -d --name redis -v myredis:/data redis redis-server --appendonly yes  
# or
docker run -d --name redis --mount source=myredis,target=/data  redis redis-server --appendonly yes

查看数据卷具体信息#

$ docker inspect redis

数据卷信息在 Mounts Key 下面

删除数据卷

$ docker volume rm myredis

数据卷是用来持久化数据的,它的生命周期独立于容器,Docker 不会在容器被删除后自动删除数据卷,并且也不存在垃圾回收这样的机制来处理没有任何容器引用的数据卷。如果需要在删除容器的同时移除数据卷。可以在删除容器的时候使用 docker rm -v 命令。

无主的数据卷可能会占据很多空间,要清理使用以下命令:

$ docker volume prune

挂载主机目录#

挂载主机目录指挂载一个主机目录作为数据卷(Bind Mounts)。

使用 --mount  标记可以指定挂载一个本地主机的目录到容器中:

docker run -d --name redis -v /data/docker/redis/data:/data redis redis-server --appendonly yes  
# or
docker run -d --name redis --mount type=bind,source=/data/docker/redis/data,target=/data redis redis-server --appendonly yes

上面命令加载宿主机的/data/docker/redis/data 目录到容器的 /data目录。

注意:本地目录路径必须是绝对路径,使用 -v 参数时如果本地目录不存在 Docker 会自动创建一个目录,使用--mount参数时如果本地目录不存在,Docker 会报错

Docker 挂载主机目录的默认权限是读写,也可以通过增加 readonly 指定为只读:

docker run -d --name redis -v /data/docker/redis/data:/data:ro redis redis-server --appendonly yes  
# or
docker run -d --name redis6 --mount type=bind,source=/data/docker/redis/data,target=/data,ro redis redis-server --appendonly yes

加了readonly之后,就挂载为只读了。如果在容器内 /bin 目录新建文件,会显示如下错误

加了 readonly 之后,就挂载为只读了。如果在容器内 /bin 目录新建文件,会显示如下错误:

Read-only file system

简拼

  • ro :ReadOnly
  • rw :ReadAndWrite

挂载方式判定#

  • -v 容器内路径  匿名挂载
  • -v 卷名:容器内路径 具名挂载
  • -v /宿主机路径:容器内路径   指定路径挂载

指定路径挂载#

docker run -it -v [本地路径]:[容器内路径]
docker run -d --name redis  -v /data/docker/redis/data:/data redis redis-server /etc/redis/redis.conf --appendonly yes   

# 查看容器详细信息
docker inspect redis

匿名挂载#

docker run -d --name redis -v /data  redis redis-server --appendonly yes   

# 查看容器详细信息
docker inspect redis

具名挂载#

docker run -d --name redis -v redis:/data redis redis-server --appendonly yes

推荐使用具名挂载因为方便后期查找或其他操作

数据卷容器 #

定义一个容器(挂载了数据卷的),其他容器通过挂载这个容器(父容器)实现数据共享,挂载数据卷的容器,称为数据卷容器( --volumes-from)。通过数据卷容器可以实现容器间的数据共享。

docker run -it/ -d  -p 主机端口:容器端口 --name=容器名称 --volumes-from 数据卷容器ID/数据卷容器名称 生成数据卷容器的镜像ID/镜像名称[:版本号]

注:这里数据共享的方式:是拷贝不是共享,这就意味着哪怕父数据卷容器被停止,子容器数据还是存在的