千家信息网

Docker数据持久化和容器与容器的数据共享

发表于:2024-11-15 作者:千家信息网编辑
千家信息网最后更新 2024年11月15日,一、前言当我们使用Docker创建一个mysql的container, 数据是存储在container内的.如果有一天不小心执行了docker rm $(docker ps -aq)删除所有conta
千家信息网最后更新 2024年11月15日Docker数据持久化和容器与容器的数据共享

一、前言

当我们使用Docker创建一个mysql的container, 数据是存储在container内的.
如果有一天不小心执行了docker rm $(docker ps -aq)删除所有container. 那么mysql里的数据也会被删掉, 这是不安全的.
我们需要将数据持久化, 存储在container外部. 即使删除container也不会删除原有的数据.

二、容器的缺陷

容器中的数据可以存储在容器层。但是将数据存放在容器层存在以下问题:
1.数据不是持久化。意思是如果容器删除了,这些数据也就没了
2.主机上的其它进程不方便访问这些数据
3.对这些数据的I/O会经过存储驱动,然后到达主机,引入了一层间接层,因此性能会有所下降

三、data volume有两种挂载方式:

1)bind mount(用户管理):将宿主机上的某个目录或文件(不可以是没有格式化的磁盘文件),挂载到容器中,默认在容器内对此目录是有读写权限的,如果只需要向容器内添加文件,不希望覆盖目录,需要注意源文件必须存在,否则会被当做一个目录bind mount给容器。
2)docker manager volume(docker自动管理):不需要指定源文件,只需要指定mount point(挂载点)。把容器里面的目录映射到了本地。
这种方式相比bind mount 缺点是无法限制对容器里边目录或文件的权限。

使用第二种挂载方式,-v 挂载时,不指定源文件位置,则默认挂载的路径是:

[root@sqm-docker01 _data]# pwd/var/lib/docker/volumes/dd173640edd5b0205bb02f3c4139647be12528b38289b9f93f18123a6b1266a8/_data#当有目录挂载时,默认在/var/lib/docker/volumes/下会生成一串hash值,hash值下有一个_data的目录,容器内映射的文件就在此路径下。

四、Storage Driver

数据存储方式

Centos7版本的docker,Storage Driver(数据存储方式)为:overlay2 ,Backing Filesystem(文件系统类型): xfs

可使用 "docker inspect 容器名称" 来查看数据存储方式

五、Data Volume

(Bind mount)

持久化存储:本质上是DockerHost文件系统中的目录或文件,能够直接被Mount到容器的文件系统中。在运行容器时,可通过-v实现。

特点:
**1. Data Volume是目录或文件,不能是没有格式化的磁盘(块设备)。

  1. 容器可以读写volume中的数据。
  2. Volume数据可以永久保存,即使使用它的容器已经被销毁。**

小实验:

运行一个nginx服务,做数据持久化

(1)Data Volume是目录或文件,不能是没有格式化的磁盘(块设备)。

[root@docker01 ~]# mkdir html//创建测试目录[root@docker01 ~]# cd html/[root@docker01 html]# echo "This is a testfile in dockerHost." > index.html//创建测试网页[root@docker01 ~]# docker run -itd --name testweb -v /root/html/:/usr/share/nginx/html nginx:latest//运行一个nginx容器,并挂载目录[root@docker01 ~]# docker inspect testweb

[root@docker01 ~]# curl 172.17.0.3

注意:dockerhost上需要被挂载的源文件或目录,必须是已经存在,否则,会被当作一个目录挂载到容器中。

(2)容器可以读写volume中的数据。

[root@docker01 ~]# docker exec  -it testweb  /bin/bashroot@ef12d312a94e:/# cd /usr/share/nginx/html/root@ef12d312a94e:/usr/share/nginx/html# echo "update" > index.html//容器中更新网页root@ef12d312a94e:/usr/share/nginx/html# exit[root@docker01 ~]# cat html/index.html//可以看到宿主目录的挂载目录也更新了

(3)Volume数据可以永久保存,即使,使用它的容器已经被销毁,也可以通过宿主机的挂在目录重新启动一个容器挂载这个目录进行访问。

[root@docker01 ~]# docker ps -a -q |xargs docker rm -f
//删除所有容器

[root@docker01 ~]# cat html/index.html//容器删除之后,宿主机的测试网页也在

[root@docker01 ~]# docker run  -itd --name t1  -P -v  /root/html/:/usr/share/nginx/html nginx:latest//基于测试网页创建一个容器[root@docker01 ~]# docker ps

[root@docker01 ~]# curl 127.0.0.1:32768//访问一下

[root@docker01 ~]# echo "update-new" > html/index.html//再次更新测试网页[root@docker01 ~]# curl 127.0.0.1:32768//在宿主机更新测试网页,刚刚创建的容器的测试网页也会更新

(5)默认挂载到容器内的文件,容器是有读写权限。可以在运行容器是-v 后边加":ro"限制容器的写入权限

[root@docker01 ~]# docker run  -itd --name t2 -P  -v  /root/html/:/usr/share/nginx/html:ro  nginx:latest//创建容器设置指读权限[root@docker01 ~]# docker exec -it t2 /bin/bash//进入容器root@4739c0f5d970:/# cd /usr/share/nginx/htmlroot@4739c0f5d970:/usr/share/nginx/html# echo 1234 > index.html//修改测试网页(失败,因为是只读的)

[root@docker01 ~]# echo 654321 > html/index.html //宿主机可以更改[root@docker01 ~]# curl 127.0.0.1:32768

(6)并且还可以挂载单独的文件到容器内部,一般他的使用场景是:如果不想对整个目录进行覆盖,而只希望添加某个文件,就可以使用挂载单个文件。
<1>测试1

 [root@docker01 ~]# docker run -itd --name v6 -P -v /root/html/index.html:/usr/share/nginx/html/index.html nginx:latest[root@docker01 ~]# docker ps

[root@docker01 ~]# curl 127.0.0.1:32770

<1>测试2

[root@docker01 ~]#  echo test > test.html[root@docker01 ~]# docker run -itd --name t8 -P -v /root/test.html:/usr/share/nginx/html/test.html nginx:latest

[root@docker01 ~]# curl 127.0.0.1:32772/test.html

六,Docker Manager Volume

会自动在宿主机生成目录,所以在挂载目录的时候只用写容器中的目录。
特性和上边的bind mount基本一样

[root@docker01 ~]# docker run -itd --name t1 -P  -v /usr/share/nginx/html nginx:latest[root@docker01 ~]# docker ps

[root@docker01 ~]# docker inspect t1

[root@docker01 _data]# cd /var/lib/docker/volumes/17c50a065a6b10ccd01ca1ce8091fdf6282dc9dcb77a0f6695906257ecc03a63/_data[root@docker01 _data]# echo "this is a testfile" > index.html[root@docker01 _data]# docker ps

[root@docker01 _data]# curl 127.0.0.1:32777

[root@docker01 _data]# docker volume ls

[root@docker01 _data]# docker rm t1 -f[root@docker01 _data]# cat index.html

1.删除容器的操作,默认不会对dockerhost上的源文件操作,如果想要在删除容器时把源文件也删除,可以在删除容器时添加-v选项(一般不推荐使用这种方式,因为文件有可能被其他容器使用)

[root@docker01 _data]# docker run -itd --name t2 -P  -v /usr/share/nginx/html nginx:latest[root@docker01 ~]# docker inspect t2

[root@docker01 ~]# cd /var/lib/docker/volumes/2781dbfdc673fc7d149dc4f6217ef277fe72e05ba2e20fcebb617afe97eccb30/_data[root@docker01 _data]# docker rm -v t2 -ft2[root@docker01 _data]# ls

七,容器与容器的数据共享

Volume container:给其他容器提供volume存储卷的容器。并且它可以提供bind mount,也可以提供docker manager volume。

创建一个vc_data容器

[root@docker01 ~]# docker create --name vc_data  -v ~/html:/usr/share/nginx/html  -v /other/useful/tools busybox[root@docker01 ~]# docker inspect vc_data

[root@docker01 ~]# docker run -itd --name t3 -P  --volumes-from vc_data nginx:latest[root@docker01 ~]# docker ps

[root@docker01 ~]# curl 127.0.0.1:32779

八,容器的跨主机数据共享

实验环境

docker01docker02
httpdnfs

要求:docker01和docker02的主目录,是一样的。

准备工作

[root@localhost ~]# hostnamectl set-hostname nfs[root@localhost ~]# hostnamectl set-hostname docker01[root@localhost ~]# hostnamectl set-hostname docker02

nfs操作

[root@localhost ~]# yum -y install nfs-utils//下载nfs服务[root@nfs ~]# mkdir /datashare//创建共享目录[root@nfs ~]# vim /etc/exports//设置权限如下/datashare *(rw,sync,no_root_squash)

开启各项服务

[root@nfs ~]# systemctl start rpcbind[root@nfs ~]# systemctl enable rpcbind[root@nfs ~]# systemctl start nfs-server[root@nfs ~]# systemctl enable nfs-server

docker01和docker02测试nfs

[root@docker01 htdocs]# showmount -e 192.168.1.20[root@docker02 htdocs]# showmount -e 192.168.1.20


docker01的操作

[root@docker02 ~]# mkdir /xxx[root@docker01 ~]# mount  -t nfs 192.168.1.10:/datashare /xxx//挂载nfs上的共享目录[root@docker01 ~]# mount | tail -1//查看是否挂载


nfs创建测试文件

[root@nfs ~]# cd datashare/[root@nfs datashare]# vim index.html
xgp666

docker01查看一下

docker02的操作与docker01上一样
这里先不考虑将代码写入镜像,先以这种方式,分别在docker01和docker02部署httpd服务

[root@docker01 ~]# docker run -itd --name bdqn-web1 -P -v /xxx/:/usr/local/apache2/htdocs httpd:latest [root@docker02 ~]# docker run -itd --name bdqn-web2 -P -v /xxx/:/usr/local/apache2/htdocs httpd:latest
[root@docker01 ~]# docker ps //查看端口0.0.0.0:32775->80/tcp   bdqn-web[root@docker02 ~]# docker ps//查看端口0.0.0.0:32769->80/tcp   bdqn-web2

此时,用浏览器访问,两个WEB服务的主界面是一样。但如果,NFS服务器上的源文件丢失,
则两个web服务都会异常。

想办法将元数据写入镜像内,在基于镜像创建一个vc_data容器,这里因为没有接触到docker-compose和docker-swarm等docker编排工具,所以需手动创建镜像!

nfs操作

[root@nfs datashare]# echo xgp666 > index.html //更改测试文件

docker02操作

[root@docker02 ~]# cd /xxx/[root@docker02 xxx]# vim Dockerfile//编写Dockerfile[root@docker02 xxx]# cat Dockerfile FROM busyboxADD index.html /usr/local/apache2/htdocs/index.htmlVOLUME /usr/local/apache2/htdocs

创建镜像并运行一个容器

[root@docker02 xxx]# docker build -t back_data .//基于Dockerfile创建镜像[root@docker02 xxx]# docker create --name back_container1  back_data:latest //基于刚刚创建的镜像创建容器

运行容器,并导出镜像

[root@docker02 xxx]# docker run -itd --name bdqn-web3 -P  --volumes-from  back_container1 httpd:latest //运行一台容器[root@docker02 xxx]# docker save > back_data.tar back_data:latest//导出镜像,因为是在共享目录所以docker01也可以看到

docker01

[root@docker01 xxx]# docker load -i back_data.tar //去共享目录,导入镜像[root@docker01 xxx]# docker  create --name back_container2  back_data:latest//基于刚刚创建的镜像运行容器[root@docker01 xxx]# docker run  -itd --name bdqn-web4 -P  --volumes-from  back_container2 httpd:latest//运行一台容器

浏览器访问

[root@docker01 ~]# docker ps //查看端口 0.0.0.0:32776->80/tcp   bdqn-web4[root@docker02 ~]# docker ps//查看端口0.0.0.0:32770->80/tcp   bdqn-web3

容器 目录 数据 文件 测试 镜像 存储 运行 方式 网页 宿主 源文件 服务 权限 宿主机 更新 端口 主机 格式 磁盘 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 图片存入数据库的必要性与效率 游戏软件开发专业大学 省知识产权技术服务中心数据库 易语言外部数据库和数据源的区别 北京gps数显钟服务器 计算机网络技术师报考 怎么新建数据连接数据库连接 上海点正互联网科技有限公司排名 数据库emp表comm 天津将至网络技术是干什么的 学习软件开发前途 传统服务器的优势 网络安全法用户信息什么制度 无线网络技术课本电子版 数据库不设置主键怎么办 word数据库怎么添加图片文档 服务器多页面登录不了怎么办 职高网络技术好不好 爱丁堡网络安全 深圳停车场系统软件开发 网络安全元应具备的条件 上海连易企互联网科技 易语言外部数据库和数据源的区别 怎么在数据库表中怎么加字段 中国可信的企业网络安全 android和数据库 数据库alter的用法及例句 尚德服务器 如何创建一个forge服务器 亿达网络技术
0