Docker实现数据持久化
由于Docker技术的火爆,以至于现在大大小小的公司都在使用Docker。对Docker熟悉的朋友都明白DOcker容器运行是有生命周期的,如果docker容器发生故障,那么就意味着容器中的数据也将丢失。那么对于企业来说的话,数据是重要的!如何做到对docker容器中的数据持久化就是运维人员需要考虑的问题了!本篇博文将了解如何对容器中的数据进行持久化!
在了解Docker数据持久化之前,需要对Docker的存储类型有一个简单的了解,执行以下命令即可看出:
[root@docker ~]# docker info //查看Docker的详细信息Containers: 2 //一共有几个容器 Running: 2 //正在运行的有几个容器 Paused: 0 //挂起、暂停的有几个容器 Stopped: 0 //停止的有几个容器Images: 2 //有几个镜像Server Version: 18.09.0 //docker的版本信息Storage Driver: overlay2 //存储驱动类型为overlay2 Backing Filesystem: xfs //支持的文件系统:xfs Supports d_type: true Native Overlay Diff: trueLogging Driver: json-fileCgroup Driver: cgroupfsPlugins: Volume: local //本地存储 Network: bridge host macvlan null overlay //支持的网络类型 Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslogSwarm: inactiveRuntimes: runcDefault Runtime: runcInit Binary: docker-initcontainerd version: c4446665cb9c30056f4998ed953e6d4ff22c7c39runc version: 4fc53a81fb7c994640722ac585fa9ca548971871init version: fec3683Security Options: seccomp Profile: defaultKernel Version: 3.10.0-862.el7.x86_64 //内核信息Operating System: CentOS Linux 7 (Core) //操作系统OSType: linux //操作系统类型Architecture: x86_64 CPUs: 2 //CPU个数Total Memory: 1.779GiB //内存容量Name: dockerID: 3SU5:P433:UIFM:YK6O:FBGP:MJSN:MTSO:PKPA:3NMN:6VW4:XUOV:XL5HDocker Root Dir: /var/lib/dockerDebug Mode (client): falseDebug Mode (server): falseRegistry: https://index.docker.io/v1/Labels:Experimental: falseInsecure Registries: 127.0.0.0/8Registry Mirrors: //采用的加速器信息 http://f1361db2.m.daocloud.io/Live Restore Enabled: falseProduct License: Community Engine
Data Volume(数据卷管理操作)
数据库管理操作分为两种bind mount与docker managervolume两种方式。
1)Bind mount(绑定挂载)
持久化存储:本质上是DockerHost文件系统中的目录或文件,能够直接被Mount到容器的文件系统中。在运行容器时,可以通过-v 实现。
Bind mount的特点:
- Data Volume是目录或文件,不能是没有格式化的磁盘(块设备);
- 容器可以读写volume中的数据;
- 随源文件变化而变化;
- volume数据可以永久保存,即使使用它的容器已经被销毁;
示例:
[root@docker ~]# mkdir /html[root@docker ~]# echo "hello world" >> /html/index.html //创建测试页面[root@docker ~]# docker run -itd --name test -p 80:80 -v /html:/usr/share/nginx/html nginx:latest//运行容器并使用"-v"选项指定挂载目录,前面为docker host的目录,":"后面为容器中的目录[root@docker ~]# [root@docker ~]# curl 127.0.0.1 //可以看到挂载已经生效hello world[root@docker ~]# echo "lzj" > /html/index.html [root@docker ~]# curl 127.0.0.1 //这种方式可以看出当源文件发生变化时,目标文件也会随之发生变化lzj[root@docker ~]# docker inspect test //查看容器的详细信息 "Mounts": [ //找到Mount字段 { "Type": "bind", //其类型为bind "Source": "/html", //源目录 "Destination": "/usr/share/nginx/html", //目标目录 "Mode": "", "RW": true, "Propagation": "rprivate" } ],
注意:
- DockerHost上需要被挂着的源文件或目录,必须是已经存在,否则,当做的一个目录挂着到容器中;
- 默认挂载到容器内的文件,容器是有读写权限。可以在运行容器"-v"选项后边加":ro" 选项来限制容器的写入权限;
- 可以挂载单独的文件到容器内部,使用场景:如果不想对整个目录进行覆盖,而只希望添加某个文件,就可以使用挂载单个文件;
2)Docker Manager Volume
示例:
[root@docker ~]# docker run -itd --name test1 -v /usr/share/nginx/html nginx:latest//这种方式"-v"选项后,只需添加容器中的目录即可[root@docker ~]# docker inspect test1 "Mounts": [ { "Type": "volume", //其类型为volume "Name": "47545a64ef51aa1ea1065848b6cb5cc5f19e2da8b2c91966b256a910fca58c4d", "Source": "/var/lib/docker/volumes/47545a64ef51aa1ea1065848b6cb5cc5f19e2da8b2c91966b256a910fca58c4d/_data", //源目录(docker自动生成的) "Destination": "/usr/share/nginx/html", //目标目录 "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],[root@docker ~]# ls /var/lib/docker/volumes/47545a64ef51aa1ea1065848b6cb5cc5f19e2da8b2c91966b256a910fca58c4d/_data50x.html index.html//可以看出宿主机上的目录就是容器中挂载的目录
这种方式特点:
- 会随着源文件的变化而变化,跟Bind mount效果是一样的!
- 删除容器的操作,默认不会对dockerhost主机上的原文件进行删除,如果想要在删除容器是将原文件删除,可以在删除容器时添加"-v"选项,(一般情况下不建议使用,因为文件有可能被其他容器就使用);
3)Volume container(容器与容器的数据共享)
Volume container:给其他容器提供volume存储卷的容器。并且它可以提供bind mount,也可以提供docker manager volume。
[root@docker ~]# docker create --name vc_data -v /html:/usr/share/nginx/html busybox:latest//创建一个容器(无须运行)[root@docker ~]# docker run -itd --name test3 -P --volumes-from vc_data nginx:latest//使用"--volumes-from"来挂载vc_data容器中的数据间到新的容器test3[root@docker ~]# docker ps //查看其映射的端口CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES021653708bb2 nginx:latest "nginx -g 'daemon of…" 7 seconds ago Up 5 seconds 0.0.0.0:32768->80/tcp test3[root@docker ~]# curl 127.0.0.1:32768 //测试效果lzj
注意:以上方式在源目录删除后,容器中的数据也会发生丢失现象!
可以采用编写dockerfile文件的方式,将目录或文件写到镜像中,然后根据镜像生成容器,才可保证原数据丢失,容器中的数据不会发生变化!
由于这种方式随机性、灵活性太差,这里就不多做介绍了这样就可以通过数据卷容器实现容器之间的数据共享。
通过以上机制,即使容器在运行过程中出现故障,用户也不用担心数据发生丢失。如果发生意外,只需快速重新创建容器即可!
注意:生产环境中最注重的就是存储的可靠性,以及存储的可动态扩展性,一定要在做数据卷时考虑到这一点,在这方面比较出色的还要数GFS文件系统了,我上面只是做了简单的配置,若在生产环境中,一定要好好考虑,就比如上面做的镜像卷容器,就可以在宿主机本地挂载GFS文件系统,然后创建镜像卷容器时,将挂载GFS的目录映射到容器中的镜像卷,这样才是一个合格的镜像卷容器。
----------本文到此为止,感谢阅读------------