一、说明
本文的主要内容
- 什么是数据卷
- 如何生成数据卷
- 将数据卷挂在容器上
- 多容器如何共享数据卷
- 什么是绑定挂载
二、数据卷概念
2.1 数据长久保存的要求
在容器运行时,容器内有一个数据存储空间,但是当容器关闭后,这个存储空间内容将被丢失(图1)。因此,数据无法长期保存!那么,数据如何长期保存需要什么策略?
通过在容器建立虚拟文件路径,此路径指向的物理地址是宿主机的文件系统,此时,当容器突然关闭,而所在宿主机上的文件系统依然无恙。这样就起到数据永久性保护的目的。
2.2 容器数据卷特征
数据卷是一个可供一个或多个容器使用的特殊目录,它将主机操作系统目录直接映射进容器 (也就是数据卷可以把数据可以直接映射到容器中)
数据卷的特性:
1.数据卷 可以在容器之间共享和重用
2.对数据卷的修改会立马生效
3.对数据卷的更新,不会影响镜像
4.数据卷 默认会一直存在,即使容器被删除
2.3 实验1:初步体验容器数据卷
【1】 简单地执行下列指令
docker run -it --name ubuntu_data -v /home/datatmp:/datatmp ubuntu20.04 bash
注意:
1)上述指令的-v参数指的是:在宿主机下的目录/home/datatmp和容器的/datatmp目录是映射关系,也就是互相备份数据。
2)上述宿主机目录 /home/datatmp以及容器目录/datatmp不需要预先建立,如无,run指令会自动建立,非常方便。
【2】 在宿主机建立文件:
进入宿主机目录cd /home/datatmp ,然后建立一个文件host.txt:
cd /home/datatmp
tounch host.txt
进入容器:
docker exec -it ubuntu_data bash
cd datatmp
ls
发现有host.txt的存在.
反之,在容器的/datatmp上建立文件cont.txt,回到主机的/home/datatmp也能看到cont.txt的存在。
2.4 容器数据卷的种类
第一种,直接挂载
这种直接用-v实现的挂载上面已经实现。
docker run -v /home/mount/data:/var/lib/mysql/data
第二种 匿名(默认路径)挂载
这种挂载指明了容器内的路径,而是物理机的地址,是指docker-engine的管辖目录:/var/lib/docker/volumes/random-hash/_data下
第三种 命名(默认路径)挂载
这是最常见的容器卷管理。这种挂载是将卷命名后挂载,通过这种命名,可以允许多个容器挂载到一个挂载点上,实现数据共享。
2.5 数据卷容器的好处
卷是持久化 Docker 容器生成和使用的数据的首选机制。虽然绑定挂载取决于主机的目录结构和操作系统,但卷完全由 Docker 管理。与绑定挂载相比,卷有几个优点:
- 卷比绑定挂载更容易备份或迁移。
- 您可以使用 Docker CLI 命令或 Docker API 管理卷。
- 卷适用于 Linux 和 Windows 容器。
- 卷可以更安全地在多个容器之间共享。
- 卷驱动程序允许您将卷存储在远程主机或云提供商上,以加密卷的内容或添加其他功能。
- 新卷的内容可以由容器预先填充。
- Docker Desktop 上的卷比 Mac 和 Windows 主机上的绑定挂载具有更高的性能。
- 此外,与在容器的可写层中持久化数据相比,卷通常是更好的选择,因为卷不会增加使用它的容器的大小,并且卷的内容存在于给定容器的生命周期之外。
三、Docker搭建MySQL并挂载数据
3.1 多路径挂载mysql
1、首先安装好 Docker,怎么安装?参看:【Docker概念和实践 2】虚拟机 ubuntu18上安装docker 。
2、下载 MySQL5.7 镜像。
docker pull mysql:5.7
3、创建容器并挂载数据。
docker run -d --restart=always --name mysql \
-v /itwxe/dockerData/mysql/data:/var/lib/mysql \
-v /itwxe/dockerData/mysql/conf:/etc/mysql \
-v /itwxe/dockerData/mysql/log:/var/log/mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_general_ci
参数说明:
-v /itwxe/dockerData/mysql/data:/var/lib/mysql:将数据文件夹挂载到主机
-v /itwxe/dockerData/mysql/conf:/etc/mysql:将配置文件夹挂在到主机,可以在宿主机放一份自定义 my.cnf文件,那么容器就会按自定义配置启动
-v /itwxe/dockerData/mysql/log:/var/log/mysql:将日志文件夹挂载到主机
-p 3306:3306:将容器的3306端口映射到主机的3306端口
-e MYSQL_ROOT_PASSWORD=123456:初始化123456用户的密码
--character-set-server=utf8mb4:设置字符集
--collation-server=utf8mb4_general_ci:排序方式
4、进入 MySQL 容器内部。
docker exec -it mysql /bin/bash
5、登录 MySQL。
mysql -uroot -p123456
6、查看字符集是否生效。
show variables like 'character_set_%';
3.2 挂载是否生效
1、上传备份 sql 到宿主机,复制宿主机备份 sql 到容器。
sudo touch /itwxe/dockerData/sunny.sql
docker cp /itwxe/dockerData/sunny.sql mysql:/
2、进入 mysql 容器内部,导入sql。
docker exec -it mysql /bin/bash
mysql -uroot -p123456
create database sunny;
use sunny;
source /sunny.sql;
3、数据导入成功可以查询后,删除容器,并重新用命令创建容器,查看数据存在。
docker stop mysql && docker rm mysql
使用上面的命令重新创建容器,查看数据是否正常,可以看到数据正常挂载查询,此处演示的数据正常挂载保存宿主机。
四、通过-mount挂载的数据卷
4.1 多路径挂载mysql
1)删除容器,准备重新生成
同样是挂载mysql数据库,我们将上面所生成的容器全部删除。
docker rm -f mysql
2)生成三个容器卷名称
docker volume create mysql_data &
docker volume create mysql_conf &
docker volume create mysql_log
3) 生成容器
docker run -d --restart=always --name mysql \
--mount type=volume,source=mysql_data,destination=/var/lib/mysql \
--mount type=volume,source=mysql_conf,destination=/etc/mysql \
--mount type=volume,source=mysql_log,destination=/var/log/mysql \
-p 3306:3306 \
-e TZ=Asia/Shanghai \
-e MYSQL_ROOT_PASSWORD=123456 \
mysql:5.7 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_general_ci
docker inspect mysql
以上说明,在定义容器卷后,同样可以挂载。
4.2 选择 -v 或 --mount 标志
-v就是卷的意思,类似的标记有--mount,两者有少许区别。
1)最主要区别:
- -mount可以支持创建集群服务的数据卷,而-v不行。
- 通常,--mount 更明确和冗长。最大的区别是 -v 语法将所有选项组合在一个字段中,而 --mount 语法将它们分开。这是每个标志的语法比较。
- 如果需要指定卷驱动程序选项,则必须使用 --mount。
2)-v( --volume)的要点
由三个字段组成,以冒号字符 (:) 分隔。字段的顺序必须正确,每个字段的含义不是很明显。
- 在命名卷的情况下,第一个字段是卷的名称,并且在给定的主机上是唯一的。对于匿名卷,省略第一个字段。
- 第二个字段是文件或目录在容器中的挂载路径。
- 第三个字段是可选的,并且是以逗号分隔的选项列表,例如 ro。这些选项将在下面讨论。
3)--mount
要点
由多个键值对组成,以逗号分隔,每个键值对由一个 <key>=<value> 元组组成。 --mount 语法比 -v 或 --volume 更冗长,但键的顺序并不重要,标志的值更容易理解。
- 挂载类型,可以是 bind、volume 或 tmpfs。本主题讨论卷,因此类型始终是卷。
- mount的来源。对于命名卷,这是卷的名称。对于匿名卷,省略此字段。可以指定为 source 或 src。
- destination 将文件或目录挂载在容器中的路径作为其值。可以指定为目的地、dst 或目标。
- readonly 选项(如果存在)会使绑定挂载以只读方式挂载到容器中。可以指定为只读或 ro。
- 可以多次指定的 volume-opt 选项采用由选项名称及其值组成的键值对。
docker service create \
--mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs,volume-opt=device=<nfs-server>:<nfs-path>,"volume-opt=o=addr=<nfs-address>,vers=4,soft,timeo=180,bg,tcp,rw"'
--name myservice \
<IMAGE>
五、数据卷管理操作
与绑定挂载不同,您可以在任何容器范围之外创建和管理卷。(这里“绑定挂载”就是run中用-v的语句)。
1.新建数据卷容器
docker volume create my-vol
2 查看卷(当前引擎下)
docker volume ls
3 查看容器内部
docker volume inspect my-vol
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/my-vol/_data",
"Name": "my-vol",
"Options": {},
"Scope": "local"
}
]
4 删除卷
docker volume rm my-vol
六、后记
数据规模越大、数据多样性更大,越要使用容器数据卷。尤其在compose、machine 和 swarm三大应用场合下,数据卷应用将更加频繁。