Dockerfile编写实践

Docker 镜像是由 Layers 组成,Dockerfile 中每一条指令都会创建一个层,层数最多 127 层。

  1. 选择更小的基础镜像通常我们使用的镜像有 Ubuntu 、CentOs、 debian 、Alpine 。其中推荐使用 Alpine ,Alpine 的基础镜像只有 4.4M 左右,1.1 scratch 镜像​ scratch 镜像是空镜像。如果要运行一个包含所有依赖的二进制文件,可以直接使用 scratch 作为基础镜像。1.2 busybox 镜像​ scratch是个空镜像,如果希望镜像里可以包含一些常用的Linux工具,busybox镜像是个不错选择,镜像本身只有1.16M,非常便于构建小镜像。
  1. 减少镜像层数将多条指令写成一条。如果有太多的 RUN,会导致镜像臃肿,使用时通过 &&/ 来实现。每个 RUN执行完后记得清理不需要的缓存文件等。降低镜像体积。

    1
    2
    rm -rf /var/lib/apt/lists/*

  2. 多阶段构建Dockerfile中每条指令都会为镜像增加一个镜像层,并且你需要在移动到下一个镜像层之前清理不需要的组件。实际上,有一个Dockerfile用于开发(其中包含构建应用程序所需的所有内容)以及一个用于生产的瘦客户端,它只包含你的应用程序以及运行它所需的内容。这被称为“建造者模式”。Docker 17.05.0-ce 版本以后支持多阶段构建。使用多阶段构建,你可以在Dockerfile中使用多个FROM语句,每条FROM指令可以使用不同的基础镜像,这样您可以选择性地将服务组件从一个阶段COPY到另一个阶段,在最终镜像中只保留需要的内容。

下面是一个使用COPY --fromFROM ... AS ... 的Dockerfile:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# Compile
FROM golang:1.9.0 AS builder
WORKDIR /go/src/v9.git...com/.../k8s-monitor
COPY . .
WORKDIR /go/src/v9.git...com/.../k8s-monitor
RUN make build
RUN mv k8s-monitor /root

# Package
# Use scratch image
FROM scratch
WORKDIR /root/
COPY --from=builder /root .
EXPOSE 8080
CMD ["/root/k8s-monitor"]

构建镜像,你会发现生成的镜像只有上面COPY 指令指定的内容,镜像大小只有2M。这样在以前使用两个Dockerfile,现在使用多阶段构建就可以搞定。

  1. 将不变的内容尽量提前如果层没有变化,Docker build 的时候会利用缓存,在开发的时候,比如 npm 、pip 之类的包管理工具,可以将配置文件提前到代码之前,然后 copy 代码后将缓存目录软连到目录,避免每次代码都需要npm 。在实际处理过程中,可能会出现一些依赖无法处理,导致不能够提前。build 时可以采用多阶段构建。或者直接 -v 本地代码目录,直接使用缓存。

  2. 提前配置国内源由于网络原因。系统源,代码包管理源速度都会慢,或者无法访问。需要将源信息提前配置到 dockerfile 中。阿里源 https://opsx.alibaba.com/mirror腾讯源 https://mirrors.cloud.tencent.com/清华大学源 https://mirrors.tuna.tsinghua.edu.cn/

  3. 设置时区不同的镜像默认的时区可能不同,导致运行时获取的时间不一致。

    1
    2
    RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

作者

张巍

发布于

2019-07-09

更新于

2019-07-09

许可协议

评论