Docker容器存储层数据持久化实现

团队介绍

我们是光大科技有限公司智能云计算部云计算团队集团云项目组,致力于光大集团IaaS平台建设与维护工作,面向集团本部及子公司提供弹性、可扩展的IaaS平台服务。

我团队在云计算、虚拟化、存储领域拥有多名经验丰富的技术专家,将不定期与大家分享原创技术文章和相关实践经验,期待与大家共同探讨和进步。

了解概念

讨论Docker存储层数据的持久化需要首先了解容器的概念。

Package Software into Standardized Units for Development, Shipment and Deployment[1]. 

将软件打包成用于开发、移植和发布的标准化单元。

这是Docker官方对容器概念的阐释。容器是软件的标准单元,他将代码和所有依赖打包,以便可以快速可靠地跨主机迁移。

Docker容器镜像是轻量级、独立的、可执行的软件包,包含应用程序运行所需的一切:代码、运行时环境、系统工具、系统库和设置[2]。

容器镜像在运行时就会成为容器,对于Docker容器来说,当镜像运行在Docker引擎上时就是一个Docker容器。镜像是静态文件,容器是镜像的运行实例,可以借助Java或C++种类和实例的概念来理解。

Docker是时下应用较广泛的容器技术,其实例就是部署在Linux内核之上,作为一个进程存在。容器具有轻量级、可扩展、可堆叠且支持即时部署和滚动升级的特点,在企业中的应用场景迅速增加。但是也正因容器只是宿主机上的一个进程,那么进程一旦销毁,其产生的需要保存的数据如何持久化到本地,是我们必须要重视的问题。每个容器运行时都有用来读写的存储层,我们称之为容器存储层。

本文将通过实验演示Docker存储层数据持久化的实现。

实验环境说明:在Workstations中运行Centos虚拟机,并在虚拟机中安装Docker CE版。

Volume实现Docker数据持久化

使用Volume的方式可将向容器存储层写入的任何数据同步到宿主机的数据卷,数据卷的生命周期独立于容器,容器删除和重新运行之后,数据不会丢失。

此处会自动在宿主机上创建一个数据卷,需要注意这种数据卷实际上是一个目录而非格式化的磁盘分区

1、用httpd镜像运行一个容器。

[root@localhost dockerfile]# docker run –name xufei -d -p 8080:80 -v /usr/local/apache2/htdocs httpd

2、可以通过volume命令查看新建数据卷的信息,但如果想看容器存储层和宿主机数据卷路径的对应关系则需要使用inspect命令。

[root@localhost dockerfile]# docker inspect 01

Docker容器存储层数据持久化实现

3、分别查看容器存储层和宿主机数据卷对应目录的数据。

[root@localhost _data]# cat index.html

[root@localhost _data]# curl 127.0.0.1:8080

Docker容器存储层数据持久化实现

4、进入容器修改index.html文件的内容,并查看宿主机新建卷对应路径下index.html中内容已经同步更新。

[root@localhost _data]# docker exec -it 01 bash

root@01df6b136e83:/usr/local/apache2/htdocs# echo \”i\’m update the index.html\” > index.html

[root@localhost _data]# cat index.html

Docker容器存储层数据持久化实现

同理,在宿主机中做内容修改也会同步到容器中的文件。

5、强制删除容器,查看宿主机新建卷中的index.html依然存在。

[root@localhost _data]# docker rm -f 01

[root@localhost _data]# cat index.html

Docker容器存储层数据持久化实现

以上实验说明Volume的方式可以实现宿主机和容器存储层之间的数据同步和容器数据的持久化保存。

Bind Mount将宿主机目录共享给Docker

Bind Mount方式可以自定义宿主机目录和容器存储层的对应关系。通过挂载相同的iNode的机制实现宿主机和容器间的数据共享。

1、在宿主机上创建一个目录,并使用httpd镜像运行一个容器实例。

[root@localhost _data]# docker run –name lixufei -d -p 8081:80 -v /root/mapping/:/usr/local/apache2/htdocs httpd

Docker容器存储层数据持久化实现

2、在宿主机上更新index.html文件数据,发现容器中的数据也一起更新。由此实现宿主机和容器间的数据共享。

[root@localhost _data]# echo \”i\’m update the index.html again\” > /root/mapping/index.html

[root@localhost _data]# curl 127.0.0.1:8081

Docker容器存储层数据持久化实现

Volume Container实现多容器共享目录

在实际业务场景下,需要经常实现容器间的数据共享,通过Volume Container方式可以实现多个容器共享持久化存储

1、使用httpd镜像运行一个容器实例,并挂载自定义的宿主机数据卷。

[root@localhost _data]# docker create –name gd -v human:/usr/local/apache2/htdocs httpd

Docker容器存储层数据持久化实现

2、运行两个httpd容器,都引用步骤1)中创建的容器gd所对应宿主机的数据卷。

[root@localhost _data]# docker run –name kj -d -p 8082:80 –volumes-from gd httpd

[root@localhost _data]# docker run –name jt -d -p 8083:80 –volumes-from gd httpd

Docker容器存储层数据持久化实现

3、进入容器kj中,更新index.html的数据,并查看容器jt中数据已经同步更新。

root@443e5f7ccada:/usr/local/apache2# echo \”Sharing with jt\” > /usr/local/apache2/htdocs/index.html

[root@localhost _data]# curl 127.0.0.1:8083

方式总结

从Docker存储层原理来分析以上三个实验,可以总结为两种实现方式

·Docker Managed Volume

这种方式会通过docker cp的机制将Docker存储层数据复制到宿主机新建卷,正是由于这种机制,所以实例的可移植性强。而且可自定义新建卷或由Docker自动创建,但无论是自定义卷或自动生成的卷,默认都位于宿主机的指定目下/var/lib/docker/volumes。该方式不支持权限控制,即在宿主机或进入容器都可以对持久化文件进行写操作。

·Bind Mount

该方式底层是通过改变Docker存储层的iNode,使之与宿主机自定义目录的iNode一致,来实现宿主机目录的共享,但并不会改变Docker内原有的文件,且会将Docker中的目录隐藏,当执行umount操作后,原来的文件就会还原。但由于更改iNode的方式与宿主机的目录绑定,所以可移植性弱。该方式支持权限控制,可使对持久化文件的修改操作只能通过宿主机来完成,通过容器只能进行读操作。

在企业实际应用中,对于数据库软件、Web应用、ERP系统等无状态的内容可以放到容器存储层,作为镜像的一部分,而相应的数据库数据、Web应用日志、ERP系统数据是需要持久化保存的,不应受Docker生命周期的影响,至于选用Docker Managed Volume方式还是Bind Mount方式就需要结合具体业务场景、数据安全要求和容器迁移需要综合考虑。

[1] https://www.docker.com/resources/what-container

[2] https://www.docker.org.cn/

作者:李许飞 

往期回顾

1

初识大二层网络

2

Web前端SDK埋点工具的设计实现

3

一起学Dapr云原生开发

4

初识对象存储MinIO

扫码关注!

EBCloud

原创文章,作者:EBCloud,如若转载,请注明出处:https://www.sudun.com/ask/33426.html

(0)
EBCloud's avatarEBCloud
上一篇 2024年4月2日 下午3:29
下一篇 2024年4月2日 下午3:29

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注