陶刚的博客
与你分享我的点滴

Docker的持久化存储以及数据共享(2020实操演示)

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

一丶叙述

1.Container 和 Image的区别

简单点来说Container是在Image基础上进行创建的,Image(只读)不能写数据而Container可以写数据,虽然Container能够写数据,但是数据只限于这个Container(当容器删除后,那么之前在容器中写入的数据或文件就全部没有了)。
容器层(container layer)是可以读写的,镜像层(image layer)只能读不能写。
在这里插入图片描述
镜像(Image)就是一堆只读层(read-only layer)的统一视角,也许这个定义有些难以理解,下面的这张图能够帮助读者理解镜像的定义。
在这里插入图片描述
容器(container)的定义和镜像(image)几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
在这里插入图片描述
以上资料参考于《Visualizing Docker Containers and Images(翻译:杨润青)》原创文章

2.Data Volume(数据卷)

当你不小心将一个存有重要数据或文件的容器误删后,容器默认是将数据写入到container layer的,那么就会导致数据丢失,为了防止此类事件发生,就可以引入持久化的机制Data Volume将数据保存到本地或者是某个地方进行存储,这样容器和数据就隔离开了,即使不小心或误删容器,也不会对外挂的存储数据造成影响,那么这样就形成了数据的持久化了
在这里插入图片描述

3.Docker持久化数据方案

docker主要有两种数据存储形式,一种是基于storage driver(也叫做Graph driver), 另一种则是基于volume driver

stroage driver主要是存储那些无状态的数据,而volume driver是写入密集型的场景时使用 。

3.1 Storage Deiver

容器运行的文件系统是镜像层和容器层组成的,一层一层叠加,只有最上面的那层是可写的,其他层都是只读的。 Docker通过Union FS技术支持文件的读写和新建,Docker 采用插件式的方式支持多种Union FS实现,官方文档中一般使用stroage driver术语,目前已经有多种实现的插件, 比如: aufs、overlay、overlay2、devicemanger等等。

3.2 Volume Driver

基于本地文件系统的Volume,可以在执行Docker Create或Docker Run时,通过-v参数将主机的目录作为容器的数据卷,这部分功能便是基于本地文件系统的volume管理。

基于Plugin的Volume,支持第三方的存储方案,比如NAS,AWS等。

4. Volume的类型

第一种:受管理的data volume,由docker后台自动创建。
第二种:绑定挂载的volume,具体挂载位置可以由用户指派。

二丶数据持久化的实现

1.Data Volume

1. 在Dockerfile中,通过VOLUME参数指定容器某一个目录的数据挂载到linux主机的一个目录里,并且会创建一个volume对象。实现方式主要有以下两种:

  • Dockerfile指定VOLUME
    VOLUME [“/var/lib/mysql”]
  • 运行指定-v参数
    docker run -v mysql:/var/lib/mysql

2. 通过github查看mysql image的Dockerfile文件中Volume参数的使用,如下所示当启动运行mysql后,会通过volume参数将mysql生成的数据存储到linux本机/var/lib/mysql目录下,该目录下的数据不会随着你删除容器而被删除的,这样则实现了数据的持久化存储
在这里插入图片描述
3. 因为以上查看docker官方提供的mysql:5.7 image的Dockerfile文件中已经使用了volume参数,所以直接拉取下来进行使用即可
在这里插入图片描述
4. 创建运行name为mysql1的容器并指定mysql允许使用空密码

docker run -d --name mysql1 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7

在这里插入图片描述
5. 查看这个volume数据

docker volume ls
docker volume inspect <VOLUME NAME>

在这里插入图片描述
6. 再创建一个mysql2的容器,并查看其volume

docker run -d --name mysql2 -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7

在这里插入图片描述
7. 现在删除mysql1和mysql2容器,再次查看本地volume没有应其容器被删除而删除

docker rm -f mysql1 mysql2
docker volume ls

在这里插入图片描述
8. 以上可以发现创建运行的容器生成的volume的name不够友好,所以在创建容器时,通过-v参数来指定volume name及其在容器下的路径

docker run -d --name mysql1 -v mysql:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7

在这里插入图片描述
9. 现在进入到mysql1 /bin/bash中,登录mysql 并创建一个database

docker exec -it mysql1 /bin/bash

在这里插入图片描述
10. 退出/bin/bash,删除mysql1容器,重新创建mysql2的容器并使用mysql:/var/lib/mysql这个volume

docker run -d --name mysql2 -v mysql:/var/lib/mysql -e MYSQL_ALLOW_EMPTY_PASSWORD=true mysql:5.7

在这里插入图片描述
11. 进入到mysql2 /bin/bash里,登录mysql数据库,查看所有的database,发现在mysql1容器中使用mysql创建的docker数据库是存在的,这就说明了通过data volume能够成功实现数据持久化
在这里插入图片描述

2.Bind Mounting

2.1 data volume与bind mount的区别

1. data volume是需要在Dockerfile中去定义VOLUME字段,而bind mount则不需要,bind mount只需要在创建运行容器的时候通过-v参数指定本地的目录与容器的目录一一对应即可
docker run -v /home/aaa:/root/aaa

2. 并且可以对本地目录和容器目录做一个同步,当对本地目录的文件进行修改后,对应的容器目录下的文件也会同步修改的,因为它们属于同一目录下的同一个文件(映射关系)

2.2 bind mount具体实现过程

1. 创建Dockerfile及其配置中需要的文件
在这里插入图片描述
2. 通过以上Dockerfile构建image

docker build -t cdtaogang/docker-nginx .

在这里插入图片描述
3. 创建运行容器,并通过curl拉取nginx主页的数据,因为在Dockerfile中将我们创建的index.html文件拷贝到了nginx的html目录下(也就是替换掉nginx的主页),所以这里是显示出我们创建的index.html文件的数据

docker run -d -p 80:80 --name web cdtaogang/docker-nginx

在这里插入图片描述
4. 在浏览器中访问docker-node1主机的IP则可以看到渲染到浏览器上的index.html数据
在这里插入图片描述
5. 接下来删除web容器重新创建,通过-v命令参数将本机docker-nginx目录映射到容器里面的/usr/share/nginx/html目录

docker run -d -p 80:80 -v $(pwd):/usr/share/nginx/html --name web cdtaogang/docker-nginx

在这里插入图片描述
6. 进入容器/bin/bash中,查看/usr/share/nginx/html目录下文件,与本机docker-nginx目录下的文件一样,touch创建一个文件

docker exec -it web /bin/bash
touch text.txt

在这里插入图片描述
7. 现在退出容器,也就是回到linux本机docker-nginx目录,查看目录下文件,就会发现自动多了一个text.txt,这就验证了两个目录是同步的
在这里插入图片描述
8. 最后修改本机docker-nginx目录下的text.txt文件的内容为cdtaogang,进入web容器中,查看目录下的text.txt文件内容为cdtaogang,说明不管是添加文件还是对文件进行修改都是两个目录下的文件都是同步的
在这里插入图片描述

3.Docker + Bind Mount 实战

3.1 实战介绍

1. 通过容器运行一个flask-web程序,如果你是这个网站的开发人员,当你对这个网站进行修改后并且想要看到修改后的内容,你就可以通过重新build docker image再创建运行容器,但是这样太麻烦了,那么比较方便的操作就是通过bind mount来同步源文件,这样你就可以实时看到网站修改后的效果了

2. 首先是准备一个基于flask框架的web程序,创建一个Dockerfile文件,将linux当前目录下的web程序源代码拷贝到容器根目录下skeleton目录,执行pip安装命令安装requirements.txt文件中的包,最后指定scripts目录下的shell命令
在这里插入图片描述

3.2 具体实现

1. 构建image

docker build -t cdtaogang/flask-skeleton .

在这里插入图片描述
2. 创建运行容器,提示如下,解决方法则是升级linux内核,因为博主前面已经升级了,只是在开机时默认使用的是3.0的内核,所以直接删除容器和镜像,重启linux主机选择最新的内核5.6.5内核启动,重新创建image和容器即可(关于centos7内核升级可参考博主的《Docker Network(二)
》这篇文章)

docker run -d -p 80:5000 --name flask-web cdtaogang/flask-skeleton

在这里插入图片描述
3. 现在创建容器成功
在这里插入图片描述
4. 容器已经成功运行,现在在博主本机浏览器上去访问linux主机ip即可访问搭建的flask-web app程序了,因为再创建容器时将容器5000端口映射到linux主机80端口上,所以直接访问linux主机ip即可
在这里插入图片描述
5. 删除flask-web容器,通过-v参数将linux本机flask-skeleton目录映射到容器根目录下的skeleton目录里

docker run -d -p 80:5000 -v $(pwd):/skeleton --name flask-web cdtaogang/flask-skeleton

在这里插入图片描述
6. 现在在linux本机skeleton/client/templates/main目录下修改home.html文件中的内容(懂web开发的都明白这是web主页前端模板文件)
在这里插入图片描述
7. 此时直接在本机浏览器强制刷新页面,则会显示以上修改的home.html页面数据了,这样通过docker bind mount方式实现同步数据就很方便了开发人员进行开发调试了
在这里插入图片描述

赞(1) 打赏
版权声明:本文为CSDN博主「cdtaogang」的原创文章,遵循CC 4.0 BY-NC-SA版权协议,转载请附上原文出处链接及本声明:记录学习生活 » Docker的持久化存储以及数据共享(2020实操演示)

评论 抢沙发

评论前必须登录!

 

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏