前言

我们在使用docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及到容器的数据管理操作。

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

  • 数据卷(Data Volumes)
  • 数据卷容器(Data Volumes Dontainers)

接下来,本节主要包括以下内容:

【1】如何在容器内创建数据卷;

【2】如何把本地的目录或文件挂载到容器内的数据卷中;

【3】如何使用数据卷容器在容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复


1、数据卷

数据券是一个可供一个或多个容器使用的特殊目录,它绕过UFS文件系统,是一个从外部挂载在容器内文件系统的目录。可以提供很多有用的特性:

  • 数据券可以在容器之间共享和重用;
  • 对数据券的修改会立马生效;
  • 对数据券的更新,不会影响镜像;
  • 数据券会一直存在,直到没有容器使用。
  • 容器停止运行且被删除时,数据券不受影响,会依然存在于docker宿主机中;

数据券的使用,类似于linux下对目录或文件进行mount操作。


1.1 在容器内创建一个数据券

使用docker run命令时,使用-v标记可以在容器内创建一个数据券。多次使用-v标记可以创建多个数据券。

下面使用training/webapp镜像创建一个web容器,并创建一个数据券挂载到容器的/webapp目录:

docker run -idt -P -v /webapp test/centos:v1.0.1 /bin/bash
#-P为外网到容器的一个映射的IP
#/webapp为创建的数据券
#test/centos:v1.0.1为镜像:标签

执行创建命令后:

[root@master03 /]# docker run -idt -P -v /webapp test/centos:v1.0.1 /bin/bash
0a1d5de1b7b83f00e1fc517216a5a3474b5ccbc14ef1250e719a25f899f89e87
#进入手滑状态运行的容器中
[root@master03 /]# docker attach 0a1d5de1b7b83f00e1fc517216a5a3474b5ccbc14ef1250e719a25f899f89e87
[root@0a1d5de1b7b8 /]# 

在/webapp上面创建你的容器/web1和/webapp目录是共享的,但是对数据券的更新,不会影响镜像。

[root@master03 /]# docker run -idt -P --name web1 -v /webapp test/centos:v1.0.1 /bin/bash
7c25ba62fef63f590cbe1c129ab785375ecb4a65309276e174fb6d4e22970652
[root@master03 /]# docker attach web1
[root@7c25ba62fef6 /]# 

参数说明:

-v:创建一个数据券并且挂载到容器里;

--name:指定容器的名称;

-d:守护状态下运行(daemon)

启动后,使用docker attach命令进入守护状态运行的容器中。


1.2 挂载宿主机目录作为数据券

除此之外,还可以挂载宿主机的一个目录来映射到容器里面作为数据券:

[root@master03 /]# docker run -idt -P --name web2 -v /var/lib/docker/volumes/:/opt/docker/volume/ test/centos:v1.0.1 /bin/bash
d25931d84aef26496cfaaf69232ecf2dc17a38b12311ac45968cd4bb46341c9a
[root@master03 /]# docker attach d25931d84aef26496cfaaf69232ecf2dc17a38b12311ac45968cd4bb46341c9a
[root@d25931d84aef /]# exit
exit
[root@master03 /]# docker attach web2
You cannot attach to a stopped container, start it first
[root@master03 /]# docker ps -a
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                          PORTS                    NAMES
d25931d84aef        test/centos:v1.0.1         "/bin/bash"              53 seconds ago      Up 1 second                                              web2
7c25ba62fef6        test/centos:v1.0.1         "/bin/bash"              20 minutes ago      Exited (0) About a minute ago                            web1
0a1d5de1b7b8        test/centos:v1.0.1         "/bin/bash"              24 minutes ago      Exited (0) 20 minutes ago                                clever_shaw
1e926a5e946f        test/centos:v1.0.1         "/bin/bash"              3 hours ago         Exited (130) 3 hours ago                                 nifty_edison
e9d4dd65dbe2        training/webapp            "python app.py"          4 hours ago         Up 4 hours                      5000/tcp                 web
becb7857f5d9        registry:latest            "/entrypoint.sh /etc…"   21 hours ago        Up 6 hours                      0.0.0.0:5000->5000/tcp   registry
5517d6d70a09        microsoft/dotnet-samples   "dotnet dotnetapp.dl…"   2 days ago          Exited (0) 2 days ago                                    romantic_goodall
39327f2deca5        centos                     "/bin/bash"              3 days ago          Exited (137) 21 hours ago                                gifted_elbakyan
[root@master03 /]#
[root@master03 /]# docker attach web2
[root@d25931d84aef /]# 

表示宿主机的目录/var/lib/docker/volumes映射到容器中的/opt/docker/volume目录。

查看一下容器中的/opt/docker/volume目录文件:

#容器的/opt/docker/volume目录
[root@d25931d84aef /]# cd /opt/docker/volume/
[root@d25931d84aef volume]# pwd
/opt/docker/volume
[root@d25931d84aef volume]# ls
0cb1337b9ff9dad2afebb51f7f893e0f6eebc17a15c03f9b2c6f3f8762fbcb80
0d651a78570fa397763ad4bd91959b01c0af55183069c43788d1b00da018efca
12ec97ead61bceb78ec83d52df71cbe2ea6d9ea54c90cfefe6b8f5fa97c32ba6
389bb6f255881a3cb1dc5243895016c9352603899a3b2e7b11cd234775be5f9e
6b101ddbcef53f5cb4d1b101795faf36aaaae4dc809e14743bb8e6cf396b6424
9401d363593a024f39aa1059b496639ee191ac79ba0e6f8e4fc83c0b1d557f62
a716022ffc07596ff4338f43857d09fcd5f57147eb1c5d6d0a38fcd095503d4d
data_1
df53c5509c3154b30294b3324eaf81f7edc7fc57e9461a40ded54a0702d75ad1
metadata.db
[root@d25931d84aef volume]# 

查看一下宿主机中的数据券,我们会发现宿主机的/var/lib/docker/volume目录创建的文件和容器/opt/docker/volume目录下的文件一样。

可以使用命令docker volume list 或者直接进入到宿主机的/var/lib/docker/volume目录下查看:

#宿主机的/var/lib/docker/volumes/目录
[root@master03 /]# cd /var/lib/docker/volumes/
[root@master03 volumes]# ls
0cb1337b9ff9dad2afebb51f7f893e0f6eebc17a15c03f9b2c6f3f8762fbcb80
0d651a78570fa397763ad4bd91959b01c0af55183069c43788d1b00da018efca
12ec97ead61bceb78ec83d52df71cbe2ea6d9ea54c90cfefe6b8f5fa97c32ba6
389bb6f255881a3cb1dc5243895016c9352603899a3b2e7b11cd234775be5f9e
6b101ddbcef53f5cb4d1b101795faf36aaaae4dc809e14743bb8e6cf396b6424
9401d363593a024f39aa1059b496639ee191ac79ba0e6f8e4fc83c0b1d557f62
a716022ffc07596ff4338f43857d09fcd5f57147eb1c5d6d0a38fcd095503d4d
data_1
df53c5509c3154b30294b3324eaf81f7edc7fc57e9461a40ded54a0702d75ad1
metadata.db
[root@master03 volumes]# 

通过上边的操作,我们可可以挂载宿主机的一个目录来映射到容器里面作为数据券,最终结果就是,宿主机目录下的数据券文件将和容器指定数据券文件目录内容一样。

这里,我们通过docker volume create命令来创建一个别名为data_1和data_2的数据券:

[root@master03 /]# docker volume create --name data_1
data_1
[root@master03 /]# docker volume inspect  data_1
[{"CreatedAt": "2019-08-09T00:40:18-04:00","Driver": "local","Labels": {},"Mountpoint": "/var/lib/docker/volumes/data_1/_data","Name": "data_1","Options": {},"Scope": "local"}
]
[root@master03 /]#
[root@master03 /]# docker volume create --name data_2
data_2
[root@master03 /]# docker volume inspect  data_2
[{"CreatedAt": "2019-08-09T04:54:09-04:00","Driver": "local","Labels": {},"Mountpoint": "/var/lib/docker/volumes/data_2/_data","Name": "data_2","Options": {},"Scope": "local"}
]
[root@master03 /]# 

注意:/var/lib/docker/volume目录为宿主机的数据券目录,而不是容器的数据券目录(/opt/docker/volume)

运行一个容器,挂载data_1数据券到该容器的/data_1目录作为数据券:

docker run -d --name web1 -v data_1:/data_1 nginx

[root@master03 /]# docker run -d --name web3 -v data_1:/opt/docker/volume/data_1 nginx
60d08f67bdac68a9c7a6f83a4b61241ea13848363775c57377b5a9012cd96b32
[root@master03 /]# docker ps -a
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                         PORTS                    NAMES
60d08f67bdac        nginx                      "nginx -g 'daemon of…"   8 seconds ago       Up 7 seconds                   80/tcp                   web3

1.3 删除数据券

  • docker volume rm <参数:数据卷的VOLUME NAME>

删除数据卷,请注意如果数据卷没有取别名,则名称是64位的全名,不支持模糊匹配,所以在创建数据卷时最好取别名。

  • docker rm -v <参数:容器名称>

随容器删除数据卷,只针对随容器创建时而创建的数据卷。


2、数据卷容器

如果用户需要在容器之间共享一些持续更新的数据,最简单的方式是使用数据券容器

数据券容器实际上就是一个普通的容器,专门为它提供数据券供其他容器挂载。使用方法如下。

【1】首先,利用docker run命令创建一个数据券容器dbdata,并在其中创建一个数据券挂载到/dbdata。

[root@master03 /]# docker run -it -v /dbdata --name dbdata ubuntu
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
7413c47ba209: Pull complete
0fe7e7cbb2e8: Pull complete
1d425c982345: Pull complete
344da5c95cec: Pull complete
Digest: sha256:d91842ef309155b85a9e5c59566719308fab816b40d376809c39cf1cf4de3c6a
Status: Downloaded newer image for ubuntu:latest

查看新建容器的/dbdata目录:

root@cf958df95262:/# ls
bin  boot  dbdata  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
root@cf958df95262:/# 

【2】然后,可以在其他容器中使用--volumes-from来挂载dbdata容器中的数据券。

例如,创建db1和db2两个容器,并从dbdata容器挂载数据券:

docker run -it --volumes-from dbdata --name db1 ubuntu
docker run -it --volumes-from dbdata --name db2 ubuntu

我们使用docker ps -a命令看一下创建出来的容器:

[root@master03 /]# docker ps -a
CONTAINER ID        IMAGE                      COMMAND                  CREATED             STATUS                            PORTS                    NAMES
94d2df4ef3e3        ubuntu                     "/bin/bash"              9 seconds ago       Exited (0) 5 seconds ago                                   db2
fbf1daabef9a        ubuntu                     "/bin/bash"              48 seconds ago      Exited (0) 37 seconds ago                                  db1
cf958df95262        ubuntu                     "/bin/bash"              3 minutes ago       Exited (130) About a minute ago                            dbdata
[root@master03 /]# 

 此时,容器db1和db2容器都挂载同一个数据券得到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。

例如:在dbdata容器中创建一个test文件:

[root@master03 /]# docker attach cf958df95262
root@cf958df95262:/# cd /dbdata/
root@cf958df95262:/dbdata# ls -l
total 0
root@cf958df95262:/dbdata# touch test
root@cf958df95262:/dbdata# ls
test
root@cf958df95262:/dbdata# 

在db1容器内查看它:

[root@master03 /]# docker attach db1
root@fbf1daabef9a:/# cd /dbdata/
root@fbf1daabef9a:/dbdata# ls -l
total 0
-rw-r--r-- 1 root root 0 Aug  9 12:06 test
root@fbf1daabef9a:/dbdata# 

在db2容器内查看test文件:

[root@master03 /]# docker attach db2
root@94d2df4ef3e3:/# cd /dbdata/
root@94d2df4ef3e3:/dbdata# ls
test
root@94d2df4ef3e3:/dbdata# 

注意:使用--volumes-from参数所挂载数据券的容器自身并不需要保持在运行状态。

如果删除了挂载的容器(包括dbdata、db1和db2),数据券并不会自动删除。

如果要删除一个数据券,必须在删除最后一个还挂载着它的容器时显式使用docker rm -v命令来指定同时删除关联容器。

使用数据券永琪可以让用户在容器之间自由地升级和移动数据券。


3、利用数据券容器迁移数据

可以利用数据券容器对其中的数据券进行备份、恢复、以实现数据的迁移。

【1】备份

使用下面的命令来备份dbdata数据券容器内的数据券。

docker run --volumes-from dbdata -v ${pwd}:/backup --name worker ubuntu
tar cvf /backup/backup.tar /dbdata

分析上述命令:

首先利用ubuntu镜像创建了一个容器worker。

使用--volumes-from dbdata参数来让worker容器挂载dbdata容器的数据券(即dbdata数据券);

使用-v${pwd}:/backup参数来挂载本地的当前目录到worker容器的/backup目录。

worker容器启动后,使用了tar cvf /backup/backup.tar /dbdata命令来讲/dbdata下内容备份为容器内的/backup/backup.tar,即宿主机当前目录下的backup.tar。

【2】恢复

如果要恢复数据到一个容器。

首先创建一个带有数据券的容器dbdata2:

docker run -v /dbdata --name dbdata2 ubuntu /bin/bash

然后,创建另一个新的容器,挂载dbdata2的容器,并使用untar解压备份文件到挂载的容器券中即可:

docker run --volumes-from dbdata2 -v ${pwd}:/backup /backup busybox tar xvf
/backup/backup.tar

在生产环境中,我们推荐在使用数据券和数据券容器之外,定期将主机的本地数据进行备份,或者使用支持容错的存储系统,包括RAID或分布式文件系统,如GPFS、HDFS


愿你就像早晨八九点钟的太阳,活力十足,永远年轻。

Docker从理论到实践(七)------Docker数据管理相关推荐

  1. Webrtc从理论到实践七: 官方demo源码走读(peerconnection_server)

    系列文章目录 Webrtc从理论到实践一:初识 Webrtc从理论到实践二: 架构 Webrtc从理论到实践三: 角色 Webrtc从理论到实践四: 通信 Webrtc从理论到实践五: 编译webrt ...

  2. docker入门----理论部分

    docker入门----理论部分 文章目录 docker入门----理论部分 前言 1.docker的简介 1.1docker的起源 1.2docker的架构 1.3特性 1.4局限 1.5原理 1. ...

  3. Docker基本理论概述

    < Docker基本理论概述 > 关于Docker 1.为什么要使用 Docker ? 项目从开发到上线,从操作系统,到运行环境,再到应用的详细配置.作为开发工程师与运维工程师之间的协作, ...

  4. DDD(Domain Driven Design) 领域驱动设计从理论到实践 四

    - 接上 SOA 架构 ​     面向服务架构(Service Oriented Architecture,SOA)对于不同的人来说意思不同.这里梳理一下SOA原则: 服务契约 : 通过契约文档,服 ...

  5. Docker理论与实践(二)

    文章作者:Tyan 博客:noahsnail.com 1. Docker命令 # 列出系统中的所有容器 docker ps -a# 结果 CONTAINER ID IMAGE COMMAND CREA ...

  6. dockerfile 修改文件权限_网易技术实践|Docker文件系统实战

    在本文中,我们来实战构建一个Docker镜像,然后实例化容器,在Docker的生命周期中详细分析一下Docker的文件存储情况和DockerFile优化策略. 在开始实战之前,我们先介绍一个概念,联合 ...

  7. 32利用文件系统保存数据_网易技术实践|Docker文件系统实战

    在本文中,我们来实战构建一个Docker镜像,然后实例化容器,在Docker的生命周期中详细分析一下Docker的文件存储情况和DockerFile优化策略. 在开始实战之前,我们先介绍一个概念,联合 ...

  8. mysql主从docker_(学习到实践)四、docker搭建mysql主从实践

    前言 目前已完成:php7及扩展.redis5的Dockerfile测试版编写,稍许完善后同步上传到github,(记下这里memcached还没有剥离安装). 今天数据库,编程的一个重要原则是不要重 ...

  9. 《Docker 技术入门与实践》-读书笔记二

    <Docker 技术入门与实践>-读书笔记一 <Docker 技术入门与实践>-读书笔记二 一.数据管理 用户在使用 Docker 的过程中,往往需要能查看容器内应用产生的数据 ...

  10. 【Docker技术入门与实践(第2版)】Docker入门_学习笔记

    第一章 1 Docker入门须知 1.1 Docker基本知识 Docker是基于Go语言实现的开源容器项目,诞生于2013年年初,最初发 起者是dotCloud公司.Docker自开源后受到广泛的关 ...

最新文章

  1. 你需要知道的高性能并发框架Disruptor原理
  2. ubuntu java开发环境搭建(jdk+tomcat+eclipse)
  3. 中国K12教育行业运营动向及未来发展战略分析报告2022年版
  4. LeetCode 147. Insertion Sort List 链表插入排序 C++/Java
  5. 币安布局去中心化交易所,原来是因为这三个原因!
  6. 英国法院裁定GCHQ黑客发动网络攻击并不侵犯人权
  7. 周志华教授专著《集成学习:基础与算法》上市,豆瓣满分森林书破解AI实践难题...
  8. 解决mac 系统软件被阻止载入点允许没反应的问题
  9. Launch Image Source
  10. 位运算的简单应用,计算无符号的数中二进制位中值为 1 的个数
  11. C#中跨工程跨项目注释的显示
  12. WinForm中的特殊窗体效果:渐变窗口和信息提示窗口
  13. python函数的规则_Python函数的作用域规则和闭包
  14. 《数据结构 严蔚敏C》期末高频考题整理(含详解)
  15. php 5.3 include 上层 function,php5.3开始出现的Function ereg() is deprecated Error问题解决办法...
  16. AMS1117-3.3的电路分析
  17. matlab画雷达目标航迹,基于MATLAB的雷达目标测量仿真分析
  18. 凡科服务器物理位置,建设网站教程
  19. stm32h7内存分配_【STM32H7教程】第26章 STM32H7的TCM,SRAM等五块内存的超方便使用方式...
  20. 如何删除ZIP压缩包的密码?

热门文章

  1. Java中try-catch-finally-return的执行顺序
  2. 【Hoxton.SR1版本】Spring Cloud Gateway之GlobalFilter全局过滤器
  3. jdk动态代理为什么只能为接口生成代理类?
  4. spring源码-@Autowired、@Resource注解底层原理
  5. 数据库事务的特性及其实现原理
  6. 设计模式-责任链设计
  7. 用CSS制作细线表格
  8. case结构条件语句
  9. Parse分析之 -- Enum.Parse
  10. Android文件资源(raw/data/asset)的存取