容器中的volume卷
1. 创建资源
开始实验之前,您需要先创建实验相关资源。
- 在实验室页面,单击创建资源。
- (可选)在实验室页面左侧导航栏中,单击云产品资源列表,可查看本次实验资源相关信息(例如IP地址、子用户信息等)。
说明:资源创建过程需要3~5分钟(视资源不同开通时间有所差异,ACK等资源开通时间较长)。完成实验资源的创建后,您可以在云产品资源列表查看已创建的资源信息,例如:子用户名称、子用户密码、AK ID、AK Secret、资源中的项目名称等。
实验环境一旦开始创建则进入计时阶段,建议学员先基本了解实验具体的步骤、目的,真正开始做实验时再进行创建。
资源创建成功,可在左侧的资源卡片中查看相关资源信息以及RAM子账号信息
2. Volume挂载简介
在上面的实验中我们为大家介绍了如何在容器中挂载文件和文件夹,这种采用绝对路径,直接挂载宿主机中的文件或者文件夹的方法又叫bind mount。这种方式比较适合将宿主机中的文件共享到容器中的场景。
除此之外docker还提供了另一种volume的方式进行挂载。这种方式通常会先在宿主机中通过docker volume命令创建一个具有名称的volume,然后再将这个volume挂载到容器中。
相比较于bind mount方式,这种方式在使用的时候完全使用docker命令,并不需要向bing mount方式那样依赖于宿主机的绝对目录,主要用于将容器中的数据持久化保存到宿主机中。
- 创建volume
在使用volume之间,通常需要先通过docker volume create命令创建volume。该命令的格式为docker volume create [volume名],和bind mount方式不同的是,volume创建之后默认并没有内容。这里我们创建名为file-vol的volume。
docker volume create file-vol
- 挂载volume
在volume创建好之后,我们就可以通过docker run 的-v参数进行挂载。在使用-v参数挂载volume时,用volume名称代替宿主机路径即可。这里我们创建并启动一个busyboxy容器,并将file-vol挂载到/file目录。
在容器创建之后,我们向volume挂载的文件夹中写入一个文件/file/text。验证挂载成功。
docker run -itd --name vol1 -v file-vol:/file busybox docker exec vol1 sh -c "echo '向volume中写入文件' > /file/text" docker exec vol1 ls /file docker exec vol1 cat /file/text
- 查看volume信息
当我们在容器的挂载点中保存数据之后,数据文件会被写入到volume中,这时我们可以通过docker volume inspect或者docker inspect来查看volume的信息。
docker volume inspect file-vol
3. Volume的持久化
在上一个小节中我们介绍了volume的基本用法。在容器中我们使用volume的主要作用,是为容器中的文件提供一种持久化的保存方法。
在前面讲解容器基本用法的时候,我们了解到每一个容器都是一个轻量级的虚拟机,在容器中创建的文件和宿主机以及其他容器并没有关系。如果容器被删除了,那么容器上的文件也就都丢失了。但是在某些情况下,我们在容器中存放了有价值的文件,比如数据库,邮件服务器,文件备份等。这个时候我们就希望能有一种即使容器被销毁了文件还可以存在的技术。这就是volume持久化的由来。
- 删除容器
接下来我们来验证volume的持久化能力。我们停止并删除刚才创建的容器vol1。在删除之后我们查看名为file-vol的volume。我们会发现容器的删除并不会影响volume的存在。
docker stop vol1 docker rm -f vol1 docker volume inspect file-vol
- 重用volume
然后我们再创建一个新的容器vol2,并将file-vol挂载到另一个目录/file-other上。由于之前的容器把数据存储在了volume中,因此新容器中的/file-other目录中保存vol1容器中的数据。
docker run -itd --name vol2 -v file-vol:/file-other busybox docker exec vol2 ls /file-other docker exec vol2 cat /file-other/text
- volume的多重绑定
如同容器可以使用多个端口绑定,容器在启动时也可以使用多个-v参数绑定多个volume,同时一个volume也可以同时绑定到多个容器中。在容器绑定volume之后,我们还可以通过docker inspect命令通过容器筛选Mounts字段查看volume的信息。
docker volume create ext-vol docker run -itd --name vol3 -v ext-vol:/ext -v file-vol:/file busybox docker inspect -f "{{json .Mounts}}" vol3 | jq
4. Volume的常用命令
在前面的小节中我们学习了volume的持久化,本小节我们再来学习一下volume相关的一些1命令
- 查看整体磁盘占用
在docker中,占用磁盘的对象包括容器镜像,容器,volume等,我们还可以通过docker system df -v命令可以查看所有对象的的磁盘占用。
如果docker的镜像,容器,或者volume对象较多,则可以使用-f参数添加过滤器来筛选具体某一个volume的信息。下面的命令可以筛选出名为file-vol的volume的过滤器的信息。
docker system df -v docker system df -v --format=\ '{{range .Volumes}}{{if eq .Name "file-vol"}}\ {{.Name}} - {{.Size}}\n{{end}}{{end}}'
- 自动创建volume
当我们使用docker run 创建容器并使用-v挂载volume的时候,如果需要加载的volume还没有被创建,则docker run会自动创建volume。
docker run -itd --name vol4 -v auto-vol:/auto busybox docker inspect auto-vol
- volume的自动删除
docker也提供了删除所有当前没有被挂载的volume的指令docker volume prune,需要注意的是使用此指令时需要小心,防止数据被误删除!下面的代码可以删除全部的容器,并清空所有的volume。下面的例子我们演示了删除所有的容器,并且删除所有的volume
docker rm -f $(docker ps -aq) docker volume prune -a docker volume ls
5. 在MySQL中使用Volume
上面的小节中,我们学习了volume的相关知识,本小节中我们来演示一个通过volume管理MySQL容器的例子。
- volume的自动创建
事实上当我们在使用docker run -v 创建数据挂载时,如果没有预先创建volume,docker会自动创建对应的volume,如果用户连volume名称都没有指定,docker会自动为volume分配名称。
接下来我们直接创建名为mysql1的mysql容器,在容器创建成功后接入mysql控制台。
docker run -itd --name mysql1 -v db-vol:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=[MYSQL密码] mysql docker exec -it mysql1 mysql -uroot -p [MYSQL密码]
- 操作数据库
在一个MySQL服务中,可以包含多个数据库,每一个数据库中又可以包含多个数据表。每一个数据表中又可以包含多个数据行。
接下来我们再控制台中通过CREATE DATABASE创建一个新数据库ali_db,创建数据库之后需要通过USE命令选中要操作的数据库,然后通过CREATE TABLE命令在ali_db中添加一个数据表ali_tab,接下来使用INSERT INTO在数据表中添加一条记录。最后使用SELECT命令查询数据表中的记录。
CREATE DATABASE ali_db; USE ali_db; CREATE TABLE ali_tab (`name` VARCHAR(100)); INSERT INTO ali_tab VALUES('aliyun'); SELECT * FROM ali_tab; exit
- 重用MySQL数据库
接下来我们删除mysql1容器,删除之后在创建另一个名为mysql2的mysql容器。mysql2容器创建成功后进入mysql控制台,在控制台中通过USE命令选择数据库,然后用SELECT命令查看数据记录。会发现数据库中记录仍存存在。
docker rm -f mysql1 docker run -itd --name mysql2 -v db-vol:/var/lib/mysql \ -e MYSQL_ROOT_PASSWORD=abc123456 mysql docker exec -it mysql2 mysql -uroot -p [MYSQL密码]
USE ali_db; SELECT * FROM ali_tab; exit
实验地址:https://developer.aliyun.com/adc/scenario/d1f14afe76224e4caa40df04c359b994