Closed mlycore closed 5 years ago
镜像是 包含一系列必要的文件的根文件系统。
容器运行起来之后,需要使用的配置文件,比如软件仓库源文件/etc/apt/source.list 。容器运行时创建的文件也可以通过 docker export 命令保存起来。通过镜像,我们可以完整的保存容器的运行环境。
dockerfile是一系列命令的集合,包含ADD ,COPY, RUN,CMD等。每执行一条命令,就会生成一个新的镜像层。每一条指令都会在上一条指令生成的镜像上运行。
run命令会在当前镜像层上运行 [command]指定的命令,并将执行结果commit到新的镜像层。因此类似 下面的指令是不会产生我们想要的结果的。
RUN cd /tmp
RUN ls .
CMD命令:CMD [command] cmd命令指定容器运行的初始命令为command。
COPY命令:COPY [src] [dst] copy命令将主机的文件复制到容器的文件系统中。
我们必须要基于一个初始的镜像层来构建镜像。使用指令FROM
下面我们来写一个Dockerfile。在这个dockerfile中我们指定初始的镜像是ubuntu:18.04,然后将同级目录中的cpfile复制到 /tmp目录中,并且运行 ls 命令,然后指定容器运行的第一条指令为/bin/sh。
FROM ubuntu:18.04
COPY ./cpfile /tmp
RUN ls /tmp
CMD /bin/sh
使用docker build 命令来构建一个镜像。参数 -t 指定镜像的tag,-f 指定dockerfile的路径。在构建镜像时,我们还需要指定镜像的上下文。那么什么是镜像的上下文呢?
还记得我们在使用COPY命令时的情景吗,上下文就是我们要拷贝的文件的父目录。在使用docker build 命令时,会将上下文中的所有文件发送给docker daemon。
使用如下命令,构建镜像:
docker build -t Lily -f ./Dockerfile . (指定上下文为当前目录)
使用docker history命令可以看到每个镜像层,如下图所示:
可以看到cpfile成功的复制到了/tmp目录:
docker镜像是容器快速部署的关键,通过将容器打包成镜像,我们可以将之前的应用的运行环境完整的复制下来,直接运行即可。
分层镜像 每个镜像都是由若干只读的镜像层,和运行之后的,可读写的容器层叠加而成。那么镜像为什么要分层呢?我想一个好处就是,不同的镜像可以共享一些镜像层,从而节省空间。
COW 写时复制策略, 如果仅仅读取底层镜像层的某一个文件时,镜像层的文件并不会被拷贝到容器层。只有当我们要写入文件时,才会将该文件拷贝到容器层,然后修改容器层的文件。
whiteout 文件
那么如果我们要删除镜像层的某个文件怎么办呢?先强调一点,虽然镜像是分层的,但是对于容器来说,每一层的文件都是可见的,每一层不是完全隔离的关系。
删除镜像层的文件时,我们并不可能真正的删除该文件,而是在容器层生成一个同名的whiteout文件,该文件实际上是一个字符设备文件。当上层发现一个whiteout文件时,就不会再往下层去查找该文件。
@DennisWong 第一个回答的赞!思路清晰赞!第4点要再想想哦
Docker镜像是一个只读的 Docker容器模板,含有启动 Docker容器所需的文件系统结构及其内容,因此是启动一个 Docker容器的基础。镜像不包含任何动态数据,其内容在构建之后也不会被改变。 Docker镜像是Docker容器运行的基础,没有Docker镜像,就不可能有Docker容器。Docker容器实际上就是一个或者多个进程,而容器的父进程就是Docker守护进程。Docker守护进程手握Docker镜像的json文件,为容器配置相应的环境,并真正运行Docker镜像所指定的进程,完成Docker容器的真正创建。
mkdir mydocker
cd mydocker
docker pull hub.c.163.com/library/tomcat:latest
下载jpress开源项目,下载地址为 ,下载后将jpress移动到mydocker目录下,并重命名为jpress.war
FROM hub.c.163.com/library/tomcat
MAINTAINER yang225217
COPY jpress.war /usr/local/tomcat/webapps
docker build -t jpress .
docker run -d -p 8888:8080 jpress
来启动Tomcat“容器镜像将会成为未来软件的主流发布方式”。Docker公司创新性地提出了使用多个增量rootfs联合挂载一个完整rootfs的方案,也就是容器镜像中的“层”的概念,通过镜像分层的设计,以Docker镜像为核心,来自不同公司、不同团队的技术人员被紧密联系在了一起。而且,由于容器镜像的操作是增量式的,这样每次镜像拉取、推送的内容,比原来多个完整的操作系统的大小要小得多。而共享层的存在,可以使得这些镜像需要的总空间也比每个镜像的总和要小。一旦这个镜像被发布,那么你在全世界的任何一个地方下载这个镜像,得到的内容都完全一致,可以完全复现这个镜像制作者当初的完整环境。可以说,镜像的发明打通了“开发——测试——部署”流程的每一个环节。
@naomiyang 提到了Docker镜像打通“开发-测试-部署”流水线这个很重要,👍,这个地方有个理论依据是“不可变基础设施”,你可以查查这个然后分享一下 😄
@mlycore 好的,我下来再了解一下。
起初大家都认为Docker不过是新瓶装旧酒,Namespace和CGroups并不是新鲜的东西,所以并未给予太多关注,然而Docker却以迅雷不及掩耳之势席卷了整个云计算市场,引起了一股全球范围的容器化浪潮。究其原因正是Docker的秘密武器——镜像。所以这次的问题是: