Docker 数据存储及持久化应用

cunchu

Author:rab



前言

Docker 为容器提供了两种存放数据的资源:

  • storage driver:管理镜像层和容器层;
  • data volume:管理容器应用数据。

一、Storage Driver

1.1 Storage Driver 介绍

不同操作系统 Docker 默认的存储驱动可能不同,如 Ubuntu 15.04 使用的存储驱动是 aufs,底层文件系统时 extfs。而我下图中是 CentOS 7.9。其 Docker 存储驱动就是 overlay2。

image-20220809122145202

查看存储驱动

image-20220809121816382

之前博客中提到 Docker 的 Copy-on-Write 特性,之所以可以实现这样的特性,主要是因为我们 Docker Storage Driver 存储驱动,它实现了多层数据堆叠,并为用户提供一个单一的合并之后的统一视图。有兴趣的可以去看看我前面的博客《Docker 的 Copy-on-Write 特性》

1.2 Storage Driver 类型

Docker 支持多种 Storage Driver,主要有这几种类型:

  • VFS

  • ZFS

  • Btrfs

  • AUFS

  • OverlayFS

  • Device Mapper

对于 DOcker 使用哪种类型的存储引擎,官方给出的答案是:默认使用你当前 Linux 发行版的 Storage Driver,因为默认的 Storage Driver 是最稳定存储引擎,在发行版上经过了严格的测试。

使用 Storage Driver 数据存储有什么优势呢?对于那些无状态(即无需数据持久化到本地)的容器,Storage Driver 的优势将是毫无疑问的,因为它能从镜像直接创建、删除(且删除时生成的数据也一并随容器删除)。

而对于需要做数据持久化的容器,Storage Driver 显然就不如 Data Volume,也就是对于这类有状态的容器,我们要用到 Docker 的 Data Volume 来做容器数据持久化存储。

二、Data Volume

2.1 Data Volume 介绍

Data Volume 实际上是我们宿主机上的目录或文件,我们通过挂载的方式将 Host 的目录或文件挂载到容器内部文件系统,有时也可以说是把容器文件系统映射到宿主机上。

这样一来容器产生的数据就可以往 Volume 写入数据了,并持久化到 Host 本地了,即使该容器被删除了,再次运行一个新的容器,状态也是与之前保持一致的。

2.2 Data Volume 类型

2.2.1 bind mount

该类型是将 Host 上已存在的目录或文件 mount 到容器。

1、具体案例

看下面案例:其语法结构为 -v <Host_path>:<container_path(不存在则创建)>

docker run -it \
--name=elasticsearch \
--privileged=true \
--restart=always \
--net=host \
-v /etc/localtime:/etc/localtime \
-v /data/elasticsearch/data:/usr/share/elasticsearch/data \
-v /data/elasticsearch/logs:/usr/share/elasticsearch/logs \
-v /data/elasticsearch/plugins:/usr/share/elasticsearch/plugins \
-v /data/elasticsearch/config/elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml \
-e ES_JAVA_OPTS="-Xms512m -Xmx512m" \
-e "discovery.type=single-node" \
-d elasticsearch:6.8.20

注意:如果 container_path 存在数据,则会被隐藏,取而代之的是 Host mount 的目录或文件,这与 Linux 中 mount 效果一样。

2、带有权限的 bind mount

类似 Linux 的 mount,在挂载时可指定挂载目录权限,默认时读写权限

docker run -it \
...
-v /data/elasticsearch/plugins:/usr/share/elasticsearch/plugins:ro \
...

# ro:只读
# rw:读写

小结:从上面的案例上看,bind mount 可实现对目录或文件的 mount 操作,可根据你的实际情况操作。

2.2.2 docker managed volume

与 bind mount 不同的是,docker managed volume 不需要指定 mount 源,只需指明挂载点(mount point)即可。

1、案例

docker run -d --name=tmp -p 8280:80 -v /usr/local/apache2/htdocs httpd

我只指定了容器内部挂载点,并没有指定 Host 源目录/文件,那这个数据持久化到 Host 的哪个位置呢?

image-20220809150246050

继续查看容器的详细信息:

docker inspect tmp

# 看 Mount 部分

image-20220809150430133

2、如何持久化呢?

此时上图红框中的部分就是数据持久化目录了,就可以像 bind mount 对持久化目录/文件进行相关更新了。具体如下:

  • 当前内容

    image-20220809151421398

  • 内容更新

    [root@docker_swarm_work1 _data]# pwd
    /var/lib/docker/volumes/fb39b435deb9bd50531b7da00ff1313f94bed8e489afb0ff69f27b77cd8a9253/_data
    [root@docker_swarm_work1 _data]# cat index.html 
    <html><body><h1>It works!</h1></body></html>
    [root@docker_swarm_work1 _data]# echo '<html><body><h1>Update It works!</h1></body></html>' > index.html
    

    image-20220809151823689

  • 删除容器并新起一个容器(验证数据持久化)

    docker stop tmp && docker rm tmp
    docker run -d --name=tmp -p 8288:80 -v /usr/local/apache2/htdocs httpd
    
    # 再起一个新容器的话,docker 又会重新创建一个随机的持久话目录
    # 但是我们之前的数据依然是在红框的上一个目录里面的
    

    image-20220809152528267

2.3 查看 Data Volume

docker volume ls

image-20220809154016353

但是需注意,docker volume ls 只能查看 docker managed volume 类型的 Data Volumebind mountData Volume 需要通过 docker inspect <container_name> 来查看。

如果我想在删除容器时,连 volume 也一并删除,如何操作?

docker stop tmp
docker rm -v tmp

# 其中-v就表示volume
# 如果你确定不再需要这些持久化数据了就可执行 -v 操作
# docker rm -v <container_name> 对 bind mount 类型的volume无效(也是无法删除,想删除需手动)
# 如果你运行容器时指定了--rm,那在停止容器时volume也会被自动删除(当然也是只对docker managed volume才有效)

image-20220809154426361

三、小结

bind mountdocker managed volume 就类似于动态指定端口和静态指定端口,动态指定端口:-p 80 此时会将容器的 80 端口在 Host 上映射一个随机端口,静态指定端口:-p 8080:80

区别:

  • bind mount 指定的数据卷是静态的,而 docker managed volume 指定的数据卷是随机动态的;

  • bind mount 挂载时 Host 源 path 会覆盖掉容器目标 path(但并不代表被永久替换),而 docker managed volume 则是将容器原有的目录或文件随机持久化在 /var/lib/docker/volumes 目录下;

  • bind mount 可指定挂载目录的读写权限,而 docker managed volume 不能;

  • bind mount 的 mount 源可以是目录或文件,而 docker managed volume 只能是目录。

对于无状态(无需做数据持久化)的容器我们可以选择 Storage Driver 默认存储引擎即可,如果对于有状态(需做数据持久化)的容器我们需要引入 Data Volume 实现数据持久化。

<点击跳转至开头>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

云计算-Security

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值