【Docker 学习六】docker容器数据卷

容器数据卷

什么是容器数据卷

Docker将运用与运行的环境打包形成容器运行, Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来, 那么当容器删除后,数据自然也就没有了。 为了能保存数据在Docker中我们使用卷。

卷就是目录或文件,存在于一个或多个容器中,由Docker挂载到容器,但卷不属于联合文件系统(Union FileSystem),因此能够绕过联合文件系统提供一些用于持续存储或共享数据的特性:。

卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷

docker的理念回顾

将应用和环境打包成一个镜像

如果数据都在容器中,那么我们容器删除,数据一定会丢失了 需求:数据可以持久化

Mysql:如果容器删除了,删库跑路 需求:MySQL数据可以存储在本地

容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!

这就是卷的技术,目录的挂载,将我们容器内的目录,挂载到Linux上面

卷的作用:
总结:容器的持久化同步操作,容器之间可以数据共享

卷的重要性

Docker容器本质上是暂时的,这意味着它们可以轻松地停止、删除或替换。
尽管这对应用程序开发和部署非常有利,但处理持久性数据时会带来挑战。
这就是卷的作用。
它们提供了一种将数据存储和管理与容器的生命周期分开的方法。

卷的类型

Docker中有三种类型的卷:
主机卷:它们存储在主机机器的文件系统中,通常位于/var/lib/docker/volumes目录中。这些可以很容易地访问,但可能会带来可移植性或文件系统兼容性问题。
匿名卷:这些是在运行容器时没有指定卷时自动生成的。它们的ID由Docker生成,也存储在主机机器的文件系统中。
命名卷:与匿名卷类似,命名卷也存储在主机机器的文件系统中。但是,您可以提供自定义名称,这样在其他容器中引用或备份时更容易。

使用容器数据卷

方法一:Docker容器启动的时候,如果要挂载宿主机的一个目录,可以用-v参数指定。

–volume(-v)概念

命令用法
参数--volume(或简写为-v)只能创建bind mount。示例:

1
2
3
4
docker run --name $CONTAINER_NAME -it \
-v $PWD/$CONTAINER_NAME/app:/app:rw \
-v $PWD/$CONTAINER_NAME/data:/data:ro \
centos /bin/bash

注释:

  • 命令格式:[[HOST-DIR:]CONTAINER-DIR[:OPTIONS]]]
  • 如果指定HOST-DIR则必须是绝对路径,如果路径不存在则会自动创建
  • 实例中的rw为读写,ro为只读

首先在主机中进入/home之后

1
cd /home

创建ceshi目录

1
2
mkdir ceshi
# ceshi

挂载命令volume(-v)

1
2
3
4
# -v 表示--volume 数据卷
# docker run -it -v 主机目录:容器内部目录
docker run -it -v /home/ceshi:/home centos /bin/bash
[root@0092ce05f98e /]#

进入容器内部后看看/home

1
2
[root@0092ce05f98e /]#cd /home
# 容器/home下没有任何文件/文件夹

通过docker inspect 容器ID 看看 Mounts挂载一个卷

退出容器之后使用命令

1
2
docker inspect 0092ce05f98e

在结果取一个Mounts的对象

1
2
3
4
5
6
7
8
9
10
"Mounts": [   # 挂载卷
{
"Type": "bind",
"Source": "/home/ceshi", # 主机内部的目录路径
"Destination": "/home", # docker容器内部的目录路径
"Mode": "", #
"RW": true, # 是否是读写模式
"Propagation": "rprivate"
}
]

测试1:是否同步文件(类似vue的双向绑定)

首先先看看容器内部目录有没有文件

1
docker attach 0092  # 已有运行的容器,可以用attach或者exec进去

进入容器之后切换home

1
[root@0092ce05f98e:/]# cd /home

命令ls查看内容

1
2
[root@0092ce05f98e:/home]# ls
#

经过确实容器内部目录里面没有文件,我们在宿主机目录下创建文件

创建文件的同步

  1. 宿主机下创建文件
    1
    touch /home/ceshi/123.txt
  2. 进入指定容器,看看内部有没有同步文件
    1
    2
    3
    4
    5
    docker attach 0092  # 已有运行的容器,可以用attach或者exec进去
    # 如果报错信息,如下
    # You cannot attach to a stopped container, start it first
    # 那么重新启动
    docker start 0092
    再进入容器
    1
    2
    docker attach 0092
    # [root@0092ce05f98e home]#
    命令ls查看内容
    1
    2
    [root@0092ce05f98e home]# ls
    # 123.txt

    说明,我们宿主机和容器同步文件成功了

测试2:停止容器,在宿主机上修改文件之后,启动容器,查看容器内部数据是否自动同步

首先把容器停止了之后进入宿主机上修改文件

1
2
docker stop 0092
# 0092

咱们在宿主机上123.txt里面添加一些内容

1
vi /home/ceshi/123.txt

保存修改文件之后,再启动容器,进入容器内部目录看看文件是不是同步了

1
2
docker start 0092
# 0092

进去容器

1
2
docker exec -it 0092 /bin/bash
# [root@0092ce05f98e /]#

在容器里面123.txt文件看看内容有没有变化

1
2
[root@0092ce05f98e /]# cat /home/123.txt
# 测试123

说明,我们宿主机和容器同步文件成功了

好处:我们以后修改只需要在本地修改即可,容器内会自动同步

–mount概念

参数:

  • --mount默认情况下用来挂载volume
  • 但也可以用来创建bind mounttmpfs
  • 如果不指定type选项,则默认为挂载volume
  • volume是一种更为灵活的数据管理方式,volume可以通过docker volume命令集被管理

示例:

1
2
3
4
5
docker run --name $CONTAINER_NAME -it \
--mount type=bind,source=$PWD/$CONTAINER_NAME/app,destination=/app \
--mount source=${CONTAINER_NAME}-data,destination=/data,readonly \
centos:latest /bin/bash

注释:

  • 挂载volume命令格式:[type=volume,]source=my-volume,destination=/path/in/container[,...]
  • 创建bind mount命令格式:type=bind,source=/path/on/host,destination=/path/in/container[,...]
  • 如果创建bind mount并指定source必须是绝对路径,且路径必须已经存在
  • 示例中readonly表示只读

采用类似于<key>=<value>的结构指定,这个是官方推荐的方式,此种方式不用严格保证配置属性的有序性,其属性之间以,分隔

-v--mount有一些不同

  • -v指定挂载目录时,如果目录不存在于主机中,他会自行创建一个目录,而–mount不会,但是–mount会有相关错误信息的抛出来
  • -v–mount是不允许同时使用的,如果要切换,必须先在运行完之后,删除相关容器才可以