Docker数据持久化


Docker数据持久化

为什么要做数据持久化:

因为Docker容器本身就是一个进程,可能会因为某些原因,或某些错误导致进程被杀死,这样数据就会丢失。

Docker容器是有生命周期的,生命周期结束,进程也会被杀死,数据就会丢失,因此需要做数据持久化,保证数据不会丢失

Storage Driver

数据存储

Centos7版本的Docker,Storage Driver为:Overlay2; backing filesystem:xfs

Data Volume

Bind mount

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

特点:

  • Data Volume是目录或文件,不能是没有格式化的磁盘(块设备)
  • 容器可以读写volume中的数据
  • volume数据可以永久保存,即使用它的容器已经被销毁

小实验:

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

[root@docker01 ~]# mkdir  html
[root@docker01 ~]# cd  html/
[root@docker01 html]# echo "This is a testfile in dockerHost."  >  index.html
[root@docker01 html]# cat index.html 
This is a testfile in dockerHost.
[root@docker01 ~]# docker run  -itd  --name  testweb  -v  /root/html/:/usr/share/nginx/html  nginx:latest
[root@docker01 ~]# docker inspect testweb
"Gateway": "172.17.0.1",
[root@docker01 ~]# curl 172.17.0.2
This is a testfile in dockerHost.

点击并拖拽以移动

PS:DockerHost上需要挂在的源文件或目录,必须是已经存在的,否则,当做一个目录挂在到容器中

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

并且还可以挂在单独文件到容器内部,一般它的使用场景是:如果不想对整个目录进行覆盖,而只希望添加某个文件,就可以使用挂载单个文件

Docker Manager Volume

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

点击并拖拽以移动

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

容器与容器的数据共享:

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

点击并拖拽以移动

容器的跨主机数据共享

docker01dcoker02docker03
httpdhttpdnfs

要求:

docker01和docker02的主目录是一样的

//docker03的操作:

[root@docker03 ~]#yum  -y  install  nfs-utils
[root@docker03 ~]# mkdir  /datashare
[root@docker03 ~]# vim  /etc/exports
[root@docker03 ~]# cat /etc/exports
/datashare  *(rw,sync,no_root_squash)
[root@docker03 ~]# systemctl  start  rpcbind
[root@docker03 ~]# systemctl  enable  rpcbind
[root@docker03 ~]# systemctl  start  nfs-server
[root@docker03 ~]# systemctl  enable  nfs-server
[root@docker03 ~]# vim  /datashare/index.html
[root@docker03 ~]# cat /datashare/index.html 
<div id="datetime">
    <script>
        setInterval("document.getElementById('datetime').innerHTML=new Date().toLocaleString();", 1000);
    </script>
</div>
bdqn-webshare

点击并拖拽以移动

//验证

[root@docker01 ~]# showmount  -e  192.168.1.60
Export list for 192.168.1.60:
/datashare *
[root@docker02 ~]# showmount  -e  192.168.1.60
Export list for 192.168.1.60:
/datashare *

点击并拖拽以移动

//docker01的操作

[root@docker01 ~]# mkdir  /htdocs
[root@docker01 ~]# mount  -t  nfs  192.168.1.60:/datashare  /htdocs/
//-t:指定类型(type)
[root@docker01 ~]# cat /htdocs/index.html 
<div id="datetime">
    <script>
        setInterval("document.getElementById('datetime').innerHTML=new Date().toLocaleString();", 1000);
    </script>
</div>
bdqn-webshare

点击并拖拽以移动

//docker02的操作

[root@docker02 ~]# mkdir   /htdocs
[root@docker02 ~]# mount  -t  nfs  192.168.1.60:/datashare  /htdocs/
[root@docker02 ~]# cat  /htdocs/index.html 
<div id="datetime">
    <script>
        setInterval("document.getElementById('datetime').innerHTML=new Date().toLocaleString();", 1000);
    </script>
</div>
bdqn-webshare

点击并拖拽以移动

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

//docker01

[root@docker01 ~]# docker run  -itd  --name  bdqn-web1 -P  -v  /htdocs/:/usr/local/apache2/htdocs  httpd:latest
PS:查看端口映射0.0.0.0:32778->80/tcp   bdqn-web1

点击并拖拽以移动

//docker02

[root@docker02 ~]# docker run  -itd  --name  bdqn-web2 -P  -v  /htdocs/:/usr/local/apache2/htdocs  httpd:latest
PS:查看端口映射0.0.0.0:32768->80/tcp   bdqn-web2

点击并拖拽以移动

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

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

[root@docker01 ~]# cd  /htdocs/
[root@docker01 htdocs]# vim  Dockerfile
[root@docker01 htdocs]# cat Dockerfile 
FROM busybox
ADD  index.html  /usr/local/apache2/htdocs/index.html
VOLUME  /usr/local/apache2/htdocs
[root@docker01 htdocs]# docker build  -t  back_data  .
[root@docker01 htdocs]# docker create --name back_container1 back_data:latest 
[root@docker01 htdocs]# docker run -itd --name web3 -P --volumes-from back_container1 httpd:latest 
[root@docker01 htdocs]# pwd
/htdocs
[root@docker01 htdocs]# docker save  > back_data.tar back_data:latest 

点击并拖拽以移动

//docker02上操作:

[root@docker02 ~]# cd /htdocs/
[root@docker02 htdocs]# ls
back_data.tar  Dockerfile  index.html
[root@docker02 htdocs]# docker load < back_data.tar 
[root@docker02 htdocs]# docker create --name back_container2 back_data:latest
[root@docker02 htdocs]# docker run -itd --name web4 -P --volumes-from back_container2 httpd:latest

点击并拖拽以移动

测试:

[root@docker01 htdocs]# rm -rf index.html 

点击并拖拽以移动

通过浏览器访问,一开始运行的web1和web2容器,无法访问了。web3和web4还是可以访问的。

但是数据无法同步了


文章作者:Echo
版权声明:本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Echo !
  目录