上周学习了docker的dockerfile,这周会往下学习一下docker的持久化;提到持久化,首先会涉及到一个UnionFS的概念;
1、什么是UnionFS?
docker创建镜像的时候,会将各种依赖包括操作系统OS、工具包、依赖库等都放在文件系统(FS)中,这样容器进程调用各项依赖都在这个文件系统目录里,从而实现环境一致性;
但是镜像是只读的,为了实现镜像的复用性,docker引入了层(layer)的概念;当镜像被docker run后,会在这个镜像的顶部添加一个新的可写层,这便是容器层;这个容器层和上一层的镜像层组成了container的运行时态;
在容器层对FS的修改不会影响到上一层的FS;这一层一层的FS便组合成为了UnionFS,以下是专业的定义:
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下;
比较遗憾的是,UnionFS并未做到数据持久化,在容器丢失或被删除后,容器层所做的修改也全部丢失,同时也存在着迁移和备份困难、读写效率低的问题;
为了保存容器层的修改,docker提供了数据卷持久化;
2、什么是数据卷?
数据卷是宿主机中的一个特殊的文件或目录,与容器中的另一个文件/目录直接关联;数据卷是完全独立于容器的生命周期、它可以绕过UnionFS,为一个或多个容器提供访问;
数据卷的特点为:
1)数据卷在容器启动时初始化,如果容器使用的镜像在挂载点包含了数据,这些数据会被拷贝到新初始化的数据卷中;
2)数据卷可以在容器之间共享和重用;
3)可以对数据卷里的内容直接进行修改;
4)数据卷的变化不会影像镜像的更新;
5)卷会一直存在,即使挂载数据卷的容器已经被删除;
3、数据持久化
目前docker是提供了3种持久化数据的方式:
卷(volume)、绑定挂载(bind mount)、临时挂载(tmpfs mount);
方式 | 说明 | 备注 |
卷(volume) | 存于宿主机文件系统中的某个目录如/var/lib/docker/volumes/ | 非docker进程无权修改其中数据 |
绑定挂载(bind mount) | 存于宿主机文件系统中的任意位置 | 非docker进程可以修改其中数据 |
临时挂载(tmpfs mount) | 存于宿主机内存中 | 容器停止,tmpfs mount会被移除 |
3.1 卷(volume)
多个容器可以通过读写或只读访问一个volume;当容器停止时,volume仍然存在,只有当显式删除时,volume才会被删除掉;以下学习一下volume的用法;
1)为容器添加卷 (volume)
docker run --name tomcat2 -v /docker/data_volume:/data:ro -it centos /bin/bash
/docker/data_volume为宿主机目录,/data为容器目录,ro为只读权限
创建容器以后呢,进入容器可以看到目录下已经有dir123的目录,且添加目录显示只读;
2)创建一个卷 (volume)
docker volume create data_volume
以下是创建了一个data_volume的卷;
3)查看所有卷 (volume)
docker volume list
4)查看卷(volume)的详细信息
docker volume inspect data_volume
可以看到他的创建日期、驱动、挂载点等信息;
5)删除卷 (volume)
docker volume rm -f data_volume
6)使用dockerfile构建卷 (volume)
FROM centos MAINTAINER chililopp LABEL version ="1.0" WORKDIR /etc RUN rm -f yum.repos.d/* RUN curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo RUN yum -y install wget RUN yum -y install zip WORKDIR /usr ADD jdk-8u212-linux-x64.tar.gz local COPY etl_tomcat.zip local RUN cp ~/.bash_profile ~/.bash_profile.bak RUN source ~/.bash_profile WORKDIR local RUN unzip etl_tomcat.zip WORKDIR /usr/local/etl_tomcat/bin EXPOSE 8090 VOLUME ["/data1","data2"]
这是我之前构建的tomcat的镜像,我再其中加上VOLUME ["/data"],创建好容器以后,发现会自动创建卷,而且容器中自动创建了目录;
7)挂载卷 (volume)容器
命名的容器挂载卷,其他容器通过挂载这个容器实现数据共享;
docker run --name centos --volumes-from=tomcat -itd centos /bin/bash
进入容器中看看,同样是创建了data1和data2两个目录
tomcat的data1中创建目录,centos中的data1同样可以看到
8)备份卷 (volume)
docker run --volumes-from tomcat -v /root/backup:/backup --name tomcat-copy centos tar zcvf /backup/data-volume.tar.gz /data1
查看一下back下的目录,发现是有data-volume.tar.gz文件
9)还原卷 (volume)
docker run --volumes-from tomcat -v /root/backup:/backup --name tomcat-tar centos tar zxvf /backup/data-volume.tar.gz -C /data1
原来是将/data1下文件均删除:
还原以后存在;
3.2 绑定挂载(bind mount)
需要手动在宿主机上创建挂载的目录(或者利用现有的),数据直接存在了宿主机硬盘上,删除容器或者卸载docker,数据并不会消失。
以下学习一下bind mount的用法;
1)为容器添加挂载(bind mount)
其用法和使用volume添加卷类似:
docker run --name tomcat_bind --mount type=bind,src=/docker/data_volume,dst=/data -it centos /bin/bash
src为宿主机路径,dst为容器路径;
3.3 临时挂载(tmpfs mount)
tmpfs mount只在linux中支持;相对于volume和bind mount,tmpfs mount是临时的,只在主机内存中持久化。当容器停止,tmpfs mount会被移除。对于临时存放敏感文件很有用;且多个容器之间无法共享tmpfs mount;
1)为容器添加挂载(tmpfs mount)
docker run --name tomcat_tmpfs --tmpfs /data1 -it centos /bin/bash
我是chililopp,正在学习k8s,之后如果有新的总结或者体验也会发出来,如果有说的不对的地方,还请指点,十分感谢阅读!