Docker系列学习文章 - 存储基本配置(八)

| 导语 通过前面的文章学会后,我们运行一个容器,打包制作一个镜像没啥问题了。但是要真正在生产上运用docker,我们还差两招很重要的。一个是数据卷的配置,还有一个是docker网络配置。这两个学会之后,基本上能开车慢慢上路了。

前面我们学习容器的时候,运行的是一些没有持久化数据存储的容器。也就是说,我们运行的容器就是能提供service服务,但是不涉及到存东西到硬盘里。我们知道,有些服务是必须要有持久化功能的,比如数据库。你用docker起了一个mysql的容器并且提供服务,那么数据总得有个地方存储。所以,我们得学习如何给容器挂载添加一块“硬盘”,让容器的产生的数据有落地的地方。

那么如何给容器添加一块存放数据的“硬盘” 呢?那就是要用到容器的数据卷服务了。接下来我们从四个方面:什么是数据卷、添加挂载数据卷、数据卷共享同步、备份还原数据卷这四方面给大家讲解下。学习了这四点之后,大家就明白怎么给容器挂硬盘做数据持久化了。

一、什么是数据卷

1. 为什么要用数据卷

数据卷的意义上面我们已经提到过了,就是为了让容器有持久化数据的功能,如果没有数据卷,容器服务产生的数据没法存储。

2. 数据卷有啥特点

数据卷总结起来有以下一些特点,大家一定要知道,这样在日后的使用中能根据其特性灵活运用。

  • 数据卷可以在dockerfile里指明指定(这个之前我们讲dockerfile里说过,VOLUME指令)。
  • 数据卷随着容器的启动而初始化,如果镜像里面volume挂载点有数据,那么会通过COPY ON WRITE(写时复制)的技术写到数据卷里。
  • 数据卷里的内容可以直接修改,无论是容器内操作还是容器外操作,会立马生效。
  • 数据卷可以在容器之间共享和重用。也就是说,多个不同的容器可以同时使用一个数据卷(类似NFS共享)。
  • 数据卷和容器、镜像能相互独立存在。
  • 挂载数据卷的容器如果被删除,数据卷还会存在,不会因为容器没了,数据卷随之也删除。

二、添加挂载数据卷

上面我们介绍了数据卷的作用和特性,那么接下来我们要学习下到底如何使用数据卷。也就是说我要怎么操作才能把一块“硬盘”挂载给容器,让它能存东西。

给容器挂载数据卷很简单,有三种方式。第一种是用docker volume 命令创建挂载;第二种就是通过docker run 命令 -v 的参数指定数据卷挂载路径;第三种就是我们之前讲过的,在做镜像的时候在dockerfile里用VOLUME指令设置好数据卷路径。

1. 第一种docker volume 方式

docker volume命令可以创建、删除、罗列、查看数据卷。

创建一个volume:# docker volume create   运行完这个命令后会在/var/lib/docker/volumes创建一个随机命名的volume,如图:

当然,你也可以给volume指定一个名字,只要加个--name即可,比如我们创建一个test的volume:

注意,创建好的volume其实就是一个文件夹,没有什么指定volume大小的说法。

创建好了volume,那么我们怎么给容器挂载?这里我们用 -v 参数即可做挂载操作了。比如我们把刚才创建的test 这个volume挂载到一个ubuntu容器里,运行:

# docker run -d -v test:/data ubuntu /bin/bash

这样创建好的test volume就跟容器的/data目录挂载映射上了。

如果你想删除volume,直接执行docker volume rm + volume名字或者ID即可:

注意,这个volume要没有容器使用占用才会被删除成功。

如果你想罗列所有创建好的volume,直接执行docker volume ls 即可:

如果你想查看创建好的某个volume信息,直接执行docker volume inspect + volume名字或者ID即可:

2. 第二种docker run -v 方式

-v 参数其实可以跳过docker volume命令直接使用。命令格式如下:

docker run -v 宿主机里绝对路径:容器里绝对路径 -it 镜像名 /bin/bash

例子:

docker run -d -v /docker_volume/volume_01:/data -it hub.tecent.com/library/centos /bin/bash

-v :就是指定映射关系的参数

/docker_volume/volume_01 :就是宿主机里你给容器存储数据设置的绝对路径,如果宿主机里不存在这个路径,那么运行那命令后会自动创建一个。

/data :就是容器里你要存数据的路径

通过这命令达到的效果就是容器的数据在容器里是存在/data下的,但是实际上数据是放在/docker_volume/volume_01里。真正存数据的是宿主机的/docker_volume/volume_01目录,而且用的IO性能也是宿主机硬盘的IO。

你运行了这样的命令后,在容器里/data目录下创建一个文件test.txt,写点数据。那么退出容器后,进到/docker_volume/volume_01里,你也可以看到你刚才在容器里创建的test.txt文件,它们是实时同步的。

3. dockerfile VOLUME指定方式

假如容器里事先就用VOLUME指定好了挂载的数据卷路径,那么用这个镜像生成的容器就自动会挂载数据卷。容器里的路径就是VOLUME设置的那个,然后宿主机里会自动默认在主机上会有一个特定的区域(/var/lib/docker/volumes  路径下),该区域用来存放 volume。volume 在生成的时候如果不指定名称,便会随机生成。所以,这个目录下的名字都是随机的ID,类似于 “/var/lib/docker/volumes/4ae9914bc4bd127e669b89ee6b703a0c9cc91f18c8dfe5034dbb838de2ca8062/_data” 这样的。

这里要注意下,假如用同一个镜像生成了两个容器,那么/var/lib/docker/volumes/ 路径下是会随机生成两个不同的路径分别对应这两个容器的,也就是说不同的容器会对应不同的路径。

三、数据卷共享、同步

通过上面第二点的方法我们知道了如何挂载一个本地路径给容器使用。但是有种情况需要考虑和实现,那就是多个容器之间假如要共用一个路径以达到数据共享怎么弄?

要做到数据卷的共享使用,我们可以用 --volumes-from 参数做到,命令格式如下:

docker run --volumes-from 容器名

例子:

# docker run -d -it --name docker2 --volumes-from docker1 ubuntu /bin/bash

docker2:是新的要创建的容器名。

--volumes-from:就是要用到的参数,注意,后面必须跟的是容器名。

docker1:这里docker1是假设的已经之前创建好的容器,里面做好了volume的挂载。

如果有个docker3容器也想使用docker1里的volume,那么只要运行同样的命令即可:

# docker run -d -it --name docker3 --volumes-from docker1 ubuntu /bin/bash

这样docker2和docker3都使用了docker1的volume了。

由此我们可以知道,volume数据卷共享其实是通过容器来做的,而不是我在宿主机里创建个目录,把它同时mount给多个容器。必须通过一个容器来做这样的桥梁以共享数据卷,这个容器我们一般叫“数据卷容器”。

因此,我们做共享,提前得规划生成这样的数据卷容器。这个容器通过前面的方法先挂载好数据卷,然后其他容器用--volumes-from来一起使用它的数据卷,分三步走:

# docker run --name docker1 -v /data ubuntu echo "share data volume container"

# docker run -d -it --name docker2 --volumes-from docker1 ubuntu /bin/bash

# docker run -d -it --name docker3 --volumes-from docker1 ubuntu /bin/bash

注意,这个docker1我们先给它映射好了数据卷/data,那么接下来的docker2和docker3就直接使用的是docker1里的/data目录了。

四、备份还原数据卷

前面我们讲了创建、挂载、删除、查看volume数据卷的方法,那么还有个很重要的操作需要学习下。那就是数据卷的备份和还原。我们知道数据是IT生产环境里非常重要的一部分,几乎所有的服务都是围绕着数据做操作,数据是核心!所以容器数据的备份和还原非常重要。

1. 备份volume

备份数据卷我们也同样用 --volumes-from 参数,然后结合数据卷容器就能达到备份数据卷的目的。我们推荐用这样的方式去备份volume,因为要备份的volume在这个数据卷容器里,所以我们针对这个数据卷容器即可操作。

我们引用下第三点里创建好的docker1,然后大家可以参考下面的命令,以后备份套用下即可:

# docker run -it --volumes-from docker1 -v /var/lib/docker/volumes/test:/backup --namedocker_backup --rm ubuntu tar cvf /backup/backup.tar /data

命令说明:

(1)首先我们--volumes-from了docker1的数据卷,然后整个命令的效果是要创建一个临时容器docker_backup;

(2)这个docker_backup容器同时挂载了两个volume,一个是来自docker1的共享volume(注意这个共享的volume就是我们要备份的/data目录),另外一个是挂载映射了宿主机的 /var/lib/docker/volumes/test,然后容器内部是/backup目录;

(3)这个docker_backup容器创建成功后,会将docker1的共享volume(也就是咱们需要备份的/data目录)打成tar包备份到宿主机的 /backup/backup.tar 下;

(4)注意我们命令里带了--rm参数,所以最后这个docker_backup容器是会被删除的,备份好了数据就删除了。

整个命令执行的效果如图:

我们在 /var/lib/docker/volumes/test 下直接能看到备份好的backup.tar 。

有些同学可能会疑问,为啥这么麻烦还得起个容器然后去备份下?其实,这个操作是最专业、最正确的操作;还有,容器其实就是一个进程,起这个容器其实就是执行一个进程执行了备份而已,也没什么麻烦,也不会占用什么太多资源。

2. 恢复volume

有了备份操作,肯定会有恢复操作。恢复操作我们也得用--volumes-from,然后创建一个临时容器就能操作恢复我们刚才备份好的backup.tar了。

大家可以参考下面的命令,以后做恢复操作套用下即可:

# docker run -it --name docker_recover -v /data ubuntu /bin/bash

# docker run --rm --volumes-from docker_recover -v /var/lib/docker/volumes/test:/backup ubuntu tar xvf /backup/backup.tar -C /data

命令说明:

(1)我们创建了一个数据卷容器docker_recover,然后设置了内部容器卷目录为/data。到时候我们的目的就是要把之前第一步备份好的backup.tar的数据恢复到docker_recover容器里;

(2)我们临时创建一个容器,通过--volumes-from 我们这个临时的容器挂载了 docker_recover 里的/data目录

(3)然后我们给这个临时容器映射了宿主机的/var/lib/docker/volumes/test 目录到了容器内部 /backup,注意/var/lib/docker/volumes/test目录下有咱们之前备份的backup.tar,所以这里一定要映射这个目录,这样这个临时容器里的 /backup 目录里才有backup.tar;

(4)最后,我们在容器里直接解压/backup 下的backup.tar ,并且把数据解压指定到容器里的/data目录下,注意,这个/data目录也是docker_recover容器里的volume。我们把文件解压到了/data里,那么docker_recover自然而然也有了要恢复的数据了。

总结:本文通过四点去讲解了下容器数据卷,数据卷在一些需要持久化容器服务里经常用到。这里要着重了解清楚数据卷的共享和备份恢复操作。最后的备份恢复有点绕,大家最好实验操作下。

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏PHP在线

Docker 入门教程

2013年发布至今, Docker 一直广受瞩目,被认为可能会改变软件行业。 但是,许多人并不清楚 Docker 到底是什么,要解决什么问题,好处又在哪里?本文...

3714
来自专栏云计算教程系列

如何在Ubuntu 14.04上使用Docker和Docker Compose配置持续集成测试环境

持续集成(CI)指的是开发人员尽可能频繁地集成代码,并且在自动化构建将每个提交合并到共享存储库之前和之后都要进行测试的实践。

530
来自专栏holer

外网访问内网Docker容器

局域网里的主机上安装了Docker容器,只能在内网访问,怎样从外网也能访问内网的Docker容器?

2481
来自专栏云计算教程系列

如何在Debian 9上安装Anaconda Python发行版

Anaconda是一个开源包管理器,环境管理器,以及Python和R编程语言的发行版。它专为数据科学和机器学习工作流程而设计,通常用于大规模数据处理,科学计算和...

5694
来自专栏编程坑太多

『中级篇』Docker 水平扩展和负载均衡(40)

PS:Docker的scale 可以扩展,也可以所有,他们自动来控制的。web=10 可以改成5 其中的6,7,8,9,10就被删除了。

4853
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Docker Bench对Docker主机进行安全性审核

使用Docker来容纳您的应用程序和服务可以为您提供开始即用的一些安全优势,但默认的Docker安装仍然有一些空间可用于一些与安全相关的配置改进。在互联网安全中...

1633
来自专栏云计算教程系列

如何在Ubuntu 16.04上使用Docker和Docker Compose配置持续集成测试环境

持续集成(CI)是指开发人员尽可能经常集成代码并在每个提交在通过自动构建合并到共享存储库之前和之后进行测试的实践。

940
来自专栏性能与架构

Docker容器案例:应用 Mysql

前阶段体验 Mysql 的新版本 5.7.13,由于机器里已经有 Mysql了,再安装另一个版本会有一些麻烦,为了简单,便使用 Docker 容器来安装 可能有...

3303
来自专栏JMCui

Docker 系列六(Docker Swarm 项目).

    随着互联网快速发展,以及微服务架构的流行,服务器的压力越来越大。上一篇介绍的 Docker Compose 项目,可以将多个容器捏合在一起,实现容器间的...

874
来自专栏崔庆才的专栏

Docker 入门教程

1653

扫码关注云+社区

领取腾讯云代金券