docker

关注公众号 jb51net

关闭
首页 > 网站技巧 > 服务器 > 云和虚拟化 > docker > docker 缓存机制

一文弄懂docker的缓存机制

作者:Cherry Xie

Docker的缓存机制是指当你构建镜像时,Docker会尽可能重用之前步骤的输出,本文主要介绍了一文弄懂docker的缓存机制,具有一定的参考价值,感兴趣的可以了解一下

docker文档

docker的缓存机制

镜像层缓存(Image Layer Cache)

Docker 镜像是分层构建的,每一个 Dockerfile 指令都会生成一个新的镜像层。
Docker 会缓存每一个镜像层,当构建新的镜像时,如果检测到某个层之前已经构建过,就会直接复用该层,而不需要重新构建。

FROM ubuntu:18.04
RUN apt-get update
RUN apt-get install -y nginx
COPY app/ /var/www/html/
CMD ["nginx", "-g", "daemon off;"]

在上面的 Dockerfile 中, 前两个 RUN 指令对应的镜像层会被缓存。当再次构建镜像时,如果这两个层没有变化,Docker 就会直接复用缓存,而不需要重新执行这两条命令,大大加快了构建速度。

容器层缓存(Container Layer Cache)

每个容器都有自己的可写容器层,位于镜像层之上,用于存储容器的动态数据。
Docker 也会缓存容器层,当重新启动容器时,Docker 会复用之前的容器层,避免重新创建。

# 创建并启动容器
docker run -d --name my-app my-app:v1

# 停止并重启容器
docker stop my-app
docker start my-app

在上面的示例中,当我们停止并重启容器时,Docker 会复用之前的容器层,避免了重新创建容器的开销,使容器启动速度更快。

构建缓存(Build Cache)

Docker 还提供了一个专门的构建缓存机制,可以进一步优化镜像构建过程。
构建缓存会将之前构建过程中用到的中间层缓存起来,下次构建时如果检测到相同的指令,就会复用这些缓存层。
用户可以通过设置 --cache-from 参数来指定需要复用的缓存层。

# 构建镜像时启用构建缓存
docker build --cache-from my-app:v1 -t my-app:v2 .

在上面的示例中,我们指定了 --cache-from my-app:v1 参数,告诉 Docker 复用之前构建 my-app:v1 时使用的缓存层,这样可以进一步加快构建速度。

Registry 缓存

Docker Registry 也提供了缓存机制,可以缓存之前拉取的镜像层,下次拉取时直接从缓存中获取,提高拉取速度。
这种缓存机制对于分布式环境下的镜像分发非常有用,可以减轻 Registry 服务器的压力。

综上所述,Docker 的缓存机制涵盖了镜像层、容器层、构建过程以及 Registry 等多个方面,充分利用缓存可以大幅提升 Docker 的性能和效率。如果您还有其他问题,欢迎继续提出

docker的几种写法

指令顺序优化

例如:

# 不好的写法
RUN apt-get update
COPY . /app
RUN pip install -r requirements.txt

# 更好的写法  
FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .

在第二个例子中,我们先复制 requirements.txt 并安装依赖包,这部分内容相对稳定,可以很好地利用缓存。而后面的 COPY . . 指令是最易变的,放在最后可以最大化利用缓存。

分层构建

例如:

# 基础层
FROM ubuntu:18.04
RUN apt-get update && apt-get install -y nodejs npm

# 应用层  
FROM base-image
COPY . /app
WORKDIR /app
RUN npm install
CMD ["node", "server.js"]

在这个例子中,我们将 Dockerfile 划分为两个阶段:基础层和应用层。基础层负责安装 Node.js 环境,这部分内容相对稳定,可以很好地利用缓存。应用层则负责复制源代码并安装依赖,这部分内容更容易变更。

多阶段构建

例如:

# 构建阶段
FROM golang:1.16 AS builder
WORKDIR /app
COPY . .
RUN go build -o myapp

# 运行阶段 
FROM alpine:latest
COPY --from=builder /app/myapp /myapp
CMD ["/myapp"]

在这个例子中,我们先在 builder 阶段编译 Go 代码,然后在 runtime 阶段只复制编译好的二进制文件到最终镜像中。这种方式可以大幅减小最终镜像的体积,同时也能很好地利用缓存。

关于docker的builder阶段

在多阶段构建的场景中,即使在 builder 阶段复制了源代码,最终也只会把编译好的二进制文件复制到运行时容器中。这是因为 COPY --from=builder 指令会选择性地复制指定阶段的文件。

让我们更详细地解释一下:

在多阶段构建中,builder 阶段的源代码确实会被保存下来,但不会被包含在最终的容器镜像中。这里有几点需要说明:

Docker 缓存

最终镜像

开发与部署分离

到此这篇关于一文弄懂docker的缓存机制的文章就介绍到这了,更多相关docker 缓存机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文