为了账号安全,请及时绑定邮箱和手机立即绑定

Docker数据持久化-撑起来容器服务的半边天

标签:
Java

Web应用服务的核心是业务逻辑处理,不管是采用了微服务的贫血模型(Get/Set),还是实现数据增删改查的DAO层,操作的关键都是后台的应用数据。同时如果想运行带持久化功能的缓存模块如Redis、数据库集群服务MySQL、微服务配置中心Consul等容器,都需要对后台数据卷进行读写功能。换言之,数据持久化撑起来容器服务的半边天。
图片描述

之前在Docker镜像文中,大家已经看到了容器文件系统的分层加载模型。Docker在启动的时候采用了默认的storage driver,包含AUFS、Device Mapper、VFS、OverlayFS、Btrfs等。不同操作系统会选择不同的默认存储驱动。以CentOS 7为例:

[root@training1 ~]# docker info
Client:
 Debug Mode: false

Server:
 Containers: 5
  Running: 1
  Paused: 0
  Stopped: 4
 Images: 5
 Server Version: 19.03.1
 Storage Driver: overlay2
  Backing Filesystem: extfs
  Supports d_type: true
  Native Overlay Diff: false
  ...
  Docker Root Dir: /var/lib/docker
  ...

可以看到,默认的存储驱动是overlay2,采用的文件系统是extfs,系统卷的默认目录是主机的/var/lib/docker目录
在启动启动内的所有数据增删改查操作只会对当前容器有效。容器销毁后,在主机和镜像内不会有其相关的数据残留。Writable的部分只限制于当前容器内:
图片描述
图片来自dockerinfo.net,图⽚片版权归属原作者
这个技术适合作为容器系统的系统卷使用。

是不是摆放数据的持久化卷也是通过类似方式准备起来的呢? 答案是
数据卷有两类常见的使用方法:Bind Mount和Volume(tmpfs mount很少使用)。
图片描述
图片来自docker.com,图⽚片版权归属原作者

  1. Bind Mounts:我把这种模式称为狩猎模式。当你手提猎枪站在森林里狩猎的时候,最大的感觉就是畅快,可谓指哪打哪。在Bind Mount模式也一样,你想把主机中什么文件或者目录mount到容器的什么位置都可以。
    图片描述
    还是以之前的redis为例,我们对这个缓存模块进行增强,提供数据持久化功能:
[root@training1 ~]# pwd
/root
[root@training1 ~]# ls
apache  Dockerfile  emacs  get-docker.sh


[root@training1 ~]# docker run -v $PWD/data:/data -d redis:3.2 redis-server
aa964b1b61fd2a8c503bb3cd63ee87235f85bead022b504f48f20eff575e5b05
[root@training1 ~]# ls
apache  data  Dockerfile  emacs  get-docker.sh

[root@training1 ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS              PORTS               NAMES
aa964b1b61fd        redis:3.2             "docker-entrypoint.s…"   About a minute ago   Up About a minute   6379/tcp            tender_franklin
[root@training1 ~]# docker exec -it aa964b1b61fd /bin/bash

root@aa964b1b61fd:/data# touch update
root@aa964b1b61fd:/data# exit
exit

[root@training1 ~]# ls data/
update

从上面的演示可以看出,Bind Mount模式的关键命令在于-v <host_path>:<ontainer_path>这几个字符。通过指定当前目录下的data子目录为加载的源头,容器内的/data为mount点,进行目录的加载。之后在容器内的数据操作会保留到主机的相关文件和目录中,持久化存储下来。

  1. Volumes: 我把这种模式称为靶场模式。当一个新兵开始训练的时候,通常狩猎场都不是最好的选择;相对的,靶场的封闭的场馆和方便的弹药更换环境,才更受欢迎。在Volumes模式中,用户可以创建卷名,并把它加载到指定的容器,但是在主机平台,这些卷确被统一存放在为Docker指定的靶场环境/var/lib/docker/volume中。
    图片描述
    两种主流volume创建方式:
    • 隐式创建卷:docker run .... -v /data
    • 显式创建卷 docker volume create --name **
      我们先来隐式地创建Redis缓存所需的持久化卷吧:
[root@training1 volumes]# docker run -v /data2 -d redis:3.2 redis-server
8fb55dcc8a5e6b0294044a99190c89e829f152782f7eb10b45f2331223f27509
[root@training1 volumes]# docker inspect 8fb55dcc8a5e6b0294044a99190c89e829f152782f7eb10b45f2331223f27509
...
        "Mounts": [
            {
                "Type": "volume",
                "Name": "f0815cce95ff0ec913f8c0a72fd04a0da72be0cccf685d9b1ecd57c14965c35a",
                "Source": "/var/lib/docker/volumes/f0815cce95ff0ec913f8c0a72fd04a0da72be0cccf685d9b1ecd57c14965c35a/_data",
                "Destination": "/data",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],
...
[root@training1 volumes]# ls /var/lib/docker/volumes/f0815cce95ff0ec913f8c0a72fd04a0da72be0cccf685d9b1ecd57c14965c35a
_data

大家可以看到,Volumes模式和Bind Mounts模式最大的区别就是-v后面没有:符号,这也就意味着我们只制定了容器内的目标mount点,而所需要从host上加载的卷,由系统在/var/lib/docker/volumes目录下随机指定,并mount到容器的/data2目录。

现在我们再来显式地创建Volume,并加载到容器内:

[root@training1 ~]# docker volume create data3
data3
[root@training1 ~]# docker inspect data3
[
    {
        "CreatedAt": "2019-08-21T00:16:47+08:00",
        "Driver": "local",
        "Labels": {},
        "Mountpoint": "/var/lib/docker/volumes/data3/_data",
        "Name": "data3",
        "Options": {},
        "Scope": "local"
    }
]
[root@training1 ~]# ls -d /var/lib/docker/volumes/data3
/var/lib/docker/volumes/data3

[root@training1 ~]# docker run -v data3:/data3 -d redis:3.2 redis-server
833da638bfdc220e7f9d9e49821ac247d6abdc6b3868a9be51803097d8de649f
[root@training1 ~]# docker exec -it 833da638bfdc220e7f9d9e49821ac247d6abdc6b3868a9be51803097d8de649f /bin/bash
root@833da638bfdc:/data# ls -ld /data3
drwxr-xr-x 2 root root 4096 Aug 20 16:16 /data3

显式地创建volume会使得其在主机上的卷名比较容易记忆,但整个加载效果其实和隐式创建类似。Volume会确保保存在/var/lib/docker/volumes目录下。

区别点 Bind Mounts Volumes
安全性 野外乱射,容易走火伤人,容易影响主机系统非容器目录 靶场射击,安全可控,只影响docker环境/var/lib/docker/volumes
灵活性 方便指定特定文件或目录 只能对应特定目录下的子目录,不支持文件
权限控制 可设置只读权限 读写权限
跨主机共享磁盘 需要各个主机上目录结构相似,移植不方便 无特定主机目录要求,移植性强
适用人群 高手特定场景下狩猎使用 小白靶场练手起步

在本篇文章中,我们学习了Docker数据持久化的技术 - Bind Mounts 和 Volumes,并对使用场景做了分析比较。

国内外一线大厂技术大咖与慕课网组成专家团队12个月磨一剑

千万级电商项目从0到1到100全过程

涵盖Java程序员不同成长阶段的问题及最佳解决方案

点击查看更多内容
4人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消