5.dokcer的数据卷
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但是不属于联合文件系统,因此能够绕过Union File System提供的一些用于持续存储或共享文件的特性
卷的设计目的就是数据持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
1.数据卷可在容器之间共享或重用数据
2.卷中的更改可以直接生效
3.数据卷中的更改不会包含在镜像的更新中
4.数据卷的声明周期一致持续到没有容器使用它为止
功能:
1.容器间的持久化
2.容器间的继承和数据共享
直接通过命令实现共享
1.如何实现宿主机和容器间的文件共享:docker run -it -v /宿主机文件夹的绝对路径:容器文件的绝对路径 镜像名称
[root@wmd03 ~]# docker run -it -v /hostDataValume:/containerDataValume centos
这个语句的作用是启动centos镜像,并宿主机根目录下创建:hostDataValume文件夹,在centos容器根目录下创建containerDataValume 文件夹,这两个文件夹实现了文件共享,
即宿主机在hostDataValume创建文件或更改文件,centos容器中的containerDataValume 也会做对应的更改
centos容器中也是同理
容器中的根目录:
[root@3038c21a010f /]# ls
bin containerDataValume(发现其创建了文件夹) dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
宿主机根目录:
[root@wmd03 /]# ls
bin boot dev etc home hostDataValume(也创建了该文件夹) lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
这两个文件夹实现了文件共享
2.创建一个只读的文件夹
[root@wmd03 ~]# docker run -it -v /hostDataValume:/containerDataValume:ro centos
这样的结果是docker容器中的containerDataValume文件夹中的文件只读,不能创建也不能更改,只有宿主机可以
示例:
[root@wmd03 ~]# docker run -it -v /hostDataValume:/containerDataValume:ro centos
[root@6af3e954d88f /]# ls
bin containerDataValume dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@6af3e954d88f /]# cd containerDataValume/
[root@6af3e954d88f containerDataValume]# touch text.text
touch: cannot touch 'text.text': Read-only file system---->不需要创建
3.这里有意思的是:这里容器停止了,在停止期间,宿主机在共享文件夹做的更改,容器再此启动后会同步过来...
如何使用dockerFile创建数据卷(宿主机的共享文件夹)
1.编写一个Dockerfile
[root@wmd03]mkdir mydocker
[root@wmd03]vim Dockerfile
# volume test
FROM centos
VOLUME ["/dataVolumeContainer01","/dataVolumeContainer02"]--->这里是创建的docker容器的数据卷,并没有宿主机的对应位置
CMD echo "成功的创建了容器的数据卷!"
CMD /bin/bash
2.使用build生成镜像:后面的点必须有
[root@wmd03 myDockerFile]# docker build -f /myDockerFile/dockerFile -t wmd/centos .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 0d120b6ccaa8
Step 2/4 : VOLUME ["/dataVolumeContainer01","/dataVolumeContainer02"]
---> Running in 1fe005128a1d
Removing intermediate container 1fe005128a1d
---> c013893a5550
Step 3/4 : CMD echo "成功的创建了容器的数据卷!"
---> Running in d589954d3f5b
Removing intermediate container d589954d3f5b
---> 1fab8c265711
Step 4/4 : CMD /bin/bash
---> Running in 883b7580f8dd
Removing intermediate container 883b7580f8dd
---> cecc006ec033
Successfully built cecc006ec033
Successfully tagged wmd/centos:latest
3.查询镜像:
[root@wmd03 myDockerFile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
wmd/centos(有) latest cecc006ec033 21 seconds ago 215MB
centos latest 0d120b6ccaa8 2 months ago 215MB
4.运行镜像:
[root@wmd03 myDockerFile]# docker run -it wmd/centos
[root@03285be9b93c /]# ls
bin dataVolumeContainer01(创建成功) dataVolumeContainer02(创建成功) dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
5.问题:查找容器数据卷对应的宿主机文件夹位置:
[root@wmd03 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5c00dad91191 wmd/centos "/bin/sh -c /bin/bash" 29 seconds ago Up 28 seconds hardcore_engelbart
[root@wmd03 ~]# docker inspect 5c00dad91191
。。。
"Volumes": {
"/dataVolumeContainer01": {},
"/dataVolumeContainer02": {}
},
。。。
发现对应关系为空:但是宿主机的对应文件夹在/var/lib/docker/volumes文件夹下,并且可以形成共享关系,但是这里查询不出,问题没有得到解决
数据卷之间的继承和共享
数据卷之间可以存在继承关系,实现共同的文件共享
示例如下:
1.创建第一个数据卷:
[root@wmd03 ~]# docker run -it --name dc01 wmd/centos 指定名称创建第一个容器,并发现创建了(dataVolumeContainer01 dataVolumeContainer02)
[root@0e8d9d653926 /]# ls
bin dataVolumeContainer01 dataVolumeContainer02 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
2.在dataVolumeContainer02创建文件
[root@0e8d9d653926 /]# cd dataVolumeContainer02/
[root@0e8d9d653926 dataVolumeContainer02]# touch dc01.txt
[root@0e8d9d653926 dataVolumeContainer02]# ls
dc01.txt
3.创建第二个容器,数据卷继承容器1
[root@wmd03 ~]# docker run -it --name dc02 --volumes-from dc01 wmd/centos
[root@683cd6dff487 /]# ls (发现也创建了dataVolumeContainer01和dataVolumeContainer02,并且在dataVolumeContainer02中有2步骤创建的文件)
bin dataVolumeContainer01 dataVolumeContainer02 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@683cd6dff487 /]# cd dataVolumeContainer02/
[root@683cd6dff487 dataVolumeContainer02]# ls
dc01.txt
4.创建第三个容器,数据卷继承容器2
[root@wmd03 ~]# docker run -it --name dc03 --volumes-from dc02 wmd/centos
[root@92a0731aacb4 /]# ls (发现也创建了dataVolumeContainer01和dataVolumeContainer02,并且在dataVolumeContainer02中有2步骤创建的文件)
bin dataVolumeContainer01 dataVolumeContainer02 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
[root@92a0731aacb4 /]# cd dataVolumeContainer02/
[root@92a0731aacb4 dataVolumeContainer02]# ls
dc01.txt
结论:有继承关系的数据卷实现了文件共享
问题:
1.删除1容器,即23容器的父类,23容器的数据卷是否还存在
答案:存在,并且如果在2容器中做的更改,3容器数据卷也会做对应改变,反之,在3容器中数据卷做的更改,2容器数据卷也会更改,这是个双向通道!
2.在子数据卷做的更改,父数据卷是否会改变
答案:会的,这是个双向通道,存在数据卷继承关系的容器,不论哪个容器数据卷做了更改,其他容器的数据卷都会做对应更改
Dokefile解析
是什么
Dockfile事用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本
步骤:
1.手动编写一个dockefile文件,当然要符合dockefile的规范
2.有了这个文件后,直接docker buil的命令执行,获取一个自定义的镜像
3.run
以我们熟悉的centos系统的Dockfile文件作为例子:https://github.com/CentOS/sig-cloud-instance-images/blob/12a4f1c0d78e257ce3d33fe89092eee07e6574da/docker/Dockerfile
内容如下:
FROM scratch (scratch是所有镜像的父类)
ADD centos-8-x86_64.tar.xz /
LABEL org.label-schema.schema-version="1.0" org.label-schema.name="CentOS Base Image" org.label-schema.vendor="CentOS" org.label-schema.license="GPLv2" org.label-schema.build-date="20200809"
CMD ["/bin/bash"]
docker运行DockerFile的大致流程:
1.dokcer从基础镜像运行一个容器(基础镜像就是From后面的)
2.执行一个指令并对容器进行更改
3.执行类似docker commit的操作,提交更改,并形成一个新的镜像(这里很重要:意思是dockfile的每个语句,对容器做出更改,都会提交生成新的镜像)
4.docker再基于方才提交的镜像生成一个新的容器
5.执行dockerfile的下一条指令,直到所有指令都执行完毕!
结论:
基于上述的流程,dockerfile会生成一个一层一层的镜像!
1.Doclfile的保留子指令
1.FROM 基础镜像,当前新镜像是基于哪个镜像的
2.MAINTAINER 镜像维护者的姓名和邮箱地址
3.RUN 容器构建时需要运行的命令
4.EXPOSE 当前容器对外暴露的端口
5.WORKDIR 指定再创建容器后,终端莫瑞诺登录的进来的工作目录,一个落脚点
6.ENV 用来再构建镜像过程中设置环境变量
7.ADD 将宿主机目录下的文件拷贝近镜像,且ADD命令会自动处理URL和解压tar压缩包
8.COPY 类似于ADD,拷贝文件和目录到镜像,但是不会解压
将从构建上下文目录中<源路径>的文件/目录 复制到新的一层的镜像内的<目标路径>位置
9.VOLUME 容器数据卷,用于数据保存和持久化工作
10.CMD
指定一个容器启动要运行的命令
Dockfile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换
11.ENTRYPOINT
指定一个容器启动时要运行的命令
ENTRYPOINT 的目的和CMD一样,都是在指定容器启动程序及参数,但是这个是追加
12.ONBUILD 当构建一个被继承的Dockfile是运行命令,父镜像在被子继承后,父镜像的onbuild被触发
使用实例:
FROM cenos -->继承centos
MAINTAINER wmd --->作者
ENV MYPATH /usr/local --->定义一个MYPATH的变量
WORKDIR $MYPATH --->定义落脚点:因为每次-it运行centos镜像时,出现的交互页面路径都是根路径:/,设置这个后,再进入就是/usr/local
RUN yum -y install vim --->执行命令:安装vim,因为docker中的centos容器不能使用vim命令,现下载
RUN yum -y install net-tools --->执行命令:安装网络工具,因为docker中的centos容器不能使用ifconfig,现在下载
EXPOSE 80 -->对外暴露的端口为80