本文共 5263 字,大约阅读时间需要 17 分钟。
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统是UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M?? 对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载。
为什么docker镜像要采用这种分层的结构呢? 最大的一个好处就是 - 共享资源。 比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像, 同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。docker镜像都是只读的。
当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常称做“容器层”,“容器层”之下的都叫“镜像层”。docker commit是提交容器副本使之成为一个新的镜像。
命令:docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:标签名案例演示:
1、从Hub上下载tomcat镜像到本地并运行:docker pull tomcatdocker run -it -p 8888:8080 --name mytomcat tomcat
其中:-p:主机端口:docker端口;-i:交互;-t:终端。
启动成功后再本地访问8888端口就可以访问到那只cat了。 2、故意删除上一步镜像产生tomcat容器的文档使此容器成为我自己的tomcat容器 3、将删除doc文档的容器作为一个模板提交到仓库 这样我们就剩成了一个属于自己的镜像文件并提交到了仓库中。先来看看Docker的理念:
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,
那么当容器删除后,数据自然也就没有了。为了能保存docker中的数据我们使用卷,有点类似redis中的RDB(Redis database)和AOF(append only file)持久化。
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
1:数据卷可在容器之间共享或重用数据 2:卷中的更改可以直接生效 3:数据卷中的更改不会包含在镜像的更新中 4:数据卷的生命周期一直持续到没有容器使用它为止docker run -it -v /宿主机绝对路径目录:/容器内目录 centos /bin/bash
然后在其中一方的目录中进行修改,另一方都可以看到,即实现了数据共享和持久化。 注:在容器停止退出之后,主机修改数据是否同步? 答:在容器重新启动之后依旧会同步。 命令中可带权限,如docker run -it -v /宿主机绝对路径:/容器内目录:ro 镜像名 其中:ro代表read only(只读)步骤:
1、根目录下创建/mydocker并进入; 2、编写Dockerfile文件; 创建Dockerfile文件,并在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷。 说明: 出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现。由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。 3、build生成镜像; 其中-f代表file,指定Dockerfile的位置,若不使用-f选项,那么默认的文件是本目录的“Dockerfile”文件。 这样就生成了一个新的镜像zzyy/centos。 4、run容器 通过上述方法,容器中的卷目录地址已经知道,那么主机中对应的主机目录地址在哪里? 注: Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied 解决办法:在挂载目录后多加一个–privileged=true参数即可命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
以上一步新建的zzyy/centos为模板,创建并运行容器dc01、dc02、dc03,那么他们已经有容器卷/dataVolumeContainer1和/dataVolumeContainer2了。
容器中的传递共享:
1、先启动一个父容器dc01,并且在/dataVolumeContainer2内新增内容
2、dc02和dc03继承自dc01,并且dc02和dc03也在/dataVolumeContainer2新增内容。 3、回到dc01可以看到02和03各自添加的内容了,证明数据可以共享。问题1:删除dc01,并修改dc02之后dc03可否看到?
答:可以! 问题2:删除dc02后dc03可否访问? 结论: 容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止。Dockerfile是用来构建docker镜像的构建文件,是有一系列命令和参数构成的脚本。
构建的步骤:
1、编写Dockerfile文件; 2、docker build; 3、docker run。从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
2 Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
3 Docker容器,容器是直接提供服务的。
CMD和ENTRYPOINT镜像案例:
两者都是指定容器启东市要运行的命令。 1、Dockerfile中可以有多个CMD命令,但是只有最后一个生效,CMD会被docker run之后的参数替换掉,如:docker run -it -p 8888:8080 tomcat /bash/shell
2、而ENTRYPOINT会将docker run之后的参数追加到ENTRYPOINT后面。比如若在Dockerfile中是:ENTRYPOINT [ "ls", "-l" ]
,运行指令是:
docker run -it -p 8888:8080 tomcat -a
那么最后的ENTRYPOINT运行结果为ENTRYPOINT [ “ls”, “-l”,"-a" ]即进行追加。
ONBUILD指令案例:
Docker Hub中99%的镜像都是通过base镜像(scratch)中安装和配置需要的软件构建出来的。如:
1、创建目录mkdir -p /mydocker/dockerfile/tomcat9
2、在上述目录下 touch c.txt 3、将jdk和tomcat安装的压缩包靠近上一步的目录中
4、在上一步目录中新建Dockerfile文件,内容为:FROM centosMAINTAINER xyy<1274268227@qq.com>#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下COPY c.txt /usr/local/cincontainer.txt#把java与tomcat添加到容器中ADD jdk-8u171-linux-x64.tar.gz /usr/local/ADD apache-tomcat-9.0.8.tar.gz /usr/local/#安装vim编辑器RUN yum -y install vim#设置工作访问时候的WORKDIR路径,登录落脚点ENV MYPATH /usr/localWORKDIR $MYPATH#配置java与tomcat环境变量ENV JAVA_HOME /usr/local/jdk1.8.0_171ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jarENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin#容器运行时监听的端口EXPOSE 8080#启动时运行tomcat# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ]# CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"]CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
5、docker build构建镜像文件
6、docker run创建并运行容器 7、访问本地端口,查看能否访问到那只猫转载地址:http://xmqrn.baihongyu.com/