Docker镜像的缓存特性和Dockerfile

13 篇文章 1 订阅
13 篇文章 0 订阅

一、Docker镜像的缓存特性

1、构建镜像

Docker 会缓存已有镜像的镜像层,构建新镜像时,如果某镜像层已经存在,就直接使用,无需重新创建。

例如:

在前面的 Dockerfile 中添加一点新内容,往镜像中复制一个文件imageFuGai:

vi Dockerfile

# This my first CentOS Dockerfile

# Version 1.0

# Base images

FROM centos

 

#MAINTAINER

MAINTAINER zola

 

#ENV

#ADD

 

#RUN

RUN yum install -y wget

 

COPY  imageFuGai

 

#WORKDIR

#EXPOSE

#CMD

 

[root@docker-centos ~]# pwd

/root

[root@docker-centos ~]# ll

total 8

-rw-------. 1 root root 1616 Apr 29 17:42 anaconda-ks.cfg

-rw-r--r--. 1 root root  189 May 10 20:09 Dockerfile

-rw-r--r--. 1 root root    0 May 10 20:02 imageFuGai

[root@docker-centos ~]# docker build -t centos-with-wget-02  .

Sending build context to Docker daemon  17.41kB

Step 1/4 : FROM centos

 ---> 470671670cac

Step 2/4 : MAINTAINER zola

 ---> Using cache

 ---> fe6ec852b0c9

Step 3/4 : RUN yum install -y wget

 ---> Using cache

 ---> 1cca79f8389d

Step 4/4 : COPY  imageFuGai  /

 ---> e0ebf5dc3b3c

Successfully built e0ebf5dc3b3c

Successfully tagged centos-with-wget-02:latest

[root@docker-centos ~]#

解释:

Step 2和Step 3:之前已经运行过相同的 RUN 指令,这次直接使用缓存中的镜像层 fe6ec852b0c9和1cca79f8389d。

Step 4:执行 COPY 指令。

其过程是启动临时容器,复制 imageFuGai,提交新的镜像层 e0ebf5dc3b3c,删除临时容器。

在构建镜像时不使用缓存,可以在 docker build 命令中加上 --no-cache 参数

docker build -t --no-cache  centos-with-wget-02  .

Dockerfile 中每一个指令都会创建一个镜像层,上层是依赖于下层的。无论什么时候,只要某一层发生变化,其上面所有层的缓存都会失效。

若改变 Dockerfile 指令的执行顺序,或者修改或添加指令,都会使缓存失效。

2、下载镜像

Docker 在下载镜像时也会使用缓存。例如我们下载 httpd 镜像

docker  history  debian

 

二、调试 Dockerfile

1、通过 Dockerfile 构建镜像的过程

从 base 镜像运行一个容器

执行一条指令,对容器做修改

执行类似 docker commit 的操作,生成一个新的镜像层

Docker 再基于刚刚提交的镜像运行一个新容器

重复 2-4 步,直到 Dockerfile 中的所有指令执行完毕

2、Dockerfile 由于某种原因执行到某个指令失败了,我们也将能够得到前一个指令成功执行构建出的镜像,这对调试 Dockerfile 非常有帮助

如果Dockerfile 在执行第三步 RUN 指令1时失败。我们可以利用第二步创建的镜像 111133223 进行调试,方式是通过 docker run -it 启动镜像的一个容器

docker run -it   111133223

手工执行 RUN 指令1很容易定位失败的原因

三、Dockerfile 常用指令

参考链接:

https://www.runoob.com/docker/docker-dockerfile.html

FROM

指定 base 镜像。

MAINTAINER

设置镜像的作者,可以是任意字符串。

 

COPY

将文件从 build context 复制到镜像。

COPY 支持两种形式:

COPY src dest

COPY ["src", "dest"]

注意:src 只能指定 build context 中的文件或目录。

 

ADD

与 COPY 类似,从 build context 复制文件到镜像。不同的是,如果 src 是归档文件(tar, zip, tgz, xz 等),文件会被自动解压到 dest。

 

ENV

设置环境变量,环境变量可被后面的指令使用。例如:

...

ENV MY_VERSION 1.3

RUN yum -y install -y mypackage=$MY_VERSION

...

 

EXPOSE

指定容器中的进程会监听某个端口,Docker 可以将该端口暴露出来。我们会在容器网络部分详细讨论。

 

VOLUME

将文件或目录声明为 volume。我们会在容器存储部分详细讨论。

 

WORKDIR

为后面的 RUN, CMD, ENTRYPOINT, ADD 或 COPY 指令设置镜像中的当前工作目录。

 

RUN

在容器中运行指定的命令。

 

CMD

容器启动时运行指定的命令。

Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效。CMD 可以被 docker run 之后的参数替换。

 

ENTRYPOINT

设置容器启动时运行的命令。

Dockerfile 中可以有多个 ENTRYPOINT 指令,但只有最后一个生效。CMD 或 docker run 之后的参数会被当做参数传递给 ENTRYPOINT。

注:Dockerfile 支持以“#”开头的注释

注意:Dockerfile 的指令每执行一次都会在 docker 上新建一层。所以过多无意义的层,会造成镜像膨胀过大。例如:

 

FROM centos

RUN yum install wget

RUN wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz"

RUN tar -xvf redis.tar.gz

以上执行会创建 3 层镜像。可简化为以下格式:

FROM centos

RUN yum install wget \

    && wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \

    && tar -xvf redis.tar.gz

以 && 符号连接命令,这样执行后,只会创建 1 层镜像

RUN、CMD、ENTRYPOINT 很重要且容易混淆

四、RUN、CMD 和 ENTRYPOINT

RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包

CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换

ENTRYPOINT 配置容器启动时运行的命令

1、Shell 和 Exec 格式

两种方式指定 RUN、CMD 和 ENTRYPOINT 要运行的命令:Shell 格式和 Exec 格式,二者在使用上有细微的区别。

Shell 格式

<instruction> <command>

Exec 格式

<instruction> ["executable", "param1", "param2", ...]

CMD 和 ENTRYPOINT 推荐使用 Exec 格式,因为指令可读性更强,更容易理解。RUN 两种格式shell格式和Exec格式都可以

2、RUN 有两种格式

Shell 格式:RUN

Exec 格式:RUN ["executable", "param1", "param2"]

使用 RUN 安装多个包:

RUN apt-get update && apt-get install -y \  

 bzr \

 cvs \

 git \

 mercurial \

 subversion

注意:apt-get update 和 apt-get install 被放在一个 RUN 指令中执行,这样能够保证每次安装的是最新的包。如果 apt-get install 在单独的 RUN 中执行,则会使用 apt-get update 创建的镜像层,而这一层可能是很久以前缓存的。

3、最佳实践

使用 RUN 指令安装应用和软件包,构建镜像。

如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。

如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

微信链接 :https://mp.weixin.qq.com/s/ZA7NtaCfgOhYCcj-k5tQDA

详情请见,公众号

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值