距集装箱爆炸已经过去了几年,生态系统开始稳定下来。在行业中的所有知名企业加入到容器化旅行车中之后,他们常常提出自己的解决方案,看来基于Docker的平台终于可以保留了。
Docker成为 实际上 标准方面,已经发生了许多事情,大多数情况是在幕后。这 开放式容器激励 (OCI)的创建旨在标准化运行时间和图像格式,而Docker更改了其内部管道以适应诸如实施 运行, 和 容器垫片.
现在,经过多年的Docker冻结其面向用户的API之后,我们开始再次看到这方面的动向,并且我们习惯于在构建和运行容器时看到的许多常见做法可能有更好的选择。其他事物刚刚被弃用或失宠。
构建套件在这里
现在,可以使用 构建套件 后端。该后端比经典后端更智能,并且能够通过实现更智能的缓存,并行化构建步骤并接受新的Dockerfile选项来加快构建过程。引用 官方文件
从版本18.09开始,Docker支持由moby / buildkit项目提供的用于执行构建的新后端。与旧的实现相比,BuildKit后端提供了许多好处。例如,BuildKit可以:检测并跳过执行未使用的构建阶段并行构建独立的构建阶段在两次构建之间逐步仅转移构建上下文中已更改的文件在构建上下文中检测并跳过未使用的文件使用具有许多新功能的外部Dockerfile实现避免使用-其余API的效果(中间图像和容器)对构建缓存进行优先级排序以进行自动修剪。
In order to select this backend, we export the environment variable DOCKER_BUILDKIT=1
. If you miss the detailed output, just add --progress=plain
.
使用多阶段构建
We are used to seeing a lot of trickery to try to keep each layer size to a minimum. Very often we use a RUN
statement to download the source and build an artifact, for instance a .deb
file or to compile a binary, and try to clean it up in the same statement to keep the layer tidy.
RUN \ apt-get update ; \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y git make gcc libc-dev ; \ git clone //github.com/some_repo ; \ cd some_repo ; \ ./configure ; \ make ; \ make install; \ cd -; \ rm -rf some_repo; \ apt-get purge -y make gcc libc-dev git; \ apt-get autoremove -y; \ apt-get clean; \ find /var/lib/apt/lists -type f | xargs rm; \ find /var/log -type f -exec rm {} \;; \ rm -rf /usr/share/man/*; \ rm -rf /usr/share/doc/*; \ rm -f /var/log/alternatives.log /var/log/apt/*; \ rm /var/cache/debconf/*-old
这既浪费每个构建的时间,又很难做到。最好用 多阶段构建.
FROM debian:stretch-slim AS some_bin RUN apt-get update; \ DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install- recommends git make gcc libc-dev; \ git clone //github.com/some_repo; \ cd some_repo; \ ./configure; \ make FROM debian:stretch-slim COPY --from=some_bin /root/some_repo/some_bin /usr/local/bin/
在某些情况下,为了避免这种情况,我看到人们在git存储库中添加了一个二进制blob,以便可以对其进行复制。使用这种方法更好。
使用–squash
虽然没有’对于每个Dockerfile总是有意义的,我们经常可以压缩第一层并获得更可维护的Dockerfile。
--squash
是一个实验性参数,需要像我们解释的那样启用 这里。代替
RUN apt-get update; \ DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y mariadb; \ apt-get autoremove -y; \ apt-get clean; \ find /var/lib/apt/lists -type f | xargs rm; \ find /var/log -type f -exec rm {} \;; \ rm -rf /usr/share/man/*; \ rm -rf /usr/share/doc/*; \ rm -f /var/log/alternatives.log /var/log/apt/*; \ rm /var/cache/debconf/*-old
, 我们能做的
RUN apt-get update RUN DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y mariadb RUN apt-get autoremove -y RUN apt-get clean RUN find /var/lib/apt/lists -type f | xargs rm RUN find /var/log -type f -exec rm {} \; RUN rm -rf /usr/share/man/* RUN rm -rf /usr/share/doc/* RUN rm -f /var/log/alternatives.log /var/log/apt/* RUN rm /var/cache/debconf/*-old
对所有架构使用一个Dockerfile
We talked about a technique to use e木-user-static
for creating builds for different architectures in a 过去的文章. When building different versions of the same image for different architectures, it is very common to see three exact copies of the same Dockerfile where the only thing that changes is the FROM
line.
FROM debian:stretch-slim # the rest of the file is duplicated
FROM armhf/debian:stretch-slim # the rest of the file is duplicated
FROM arm64v8/debian:stretch-slim # the rest of the file is duplicated
像这样只有一个文件
ARG arch FROM ${arch}/debian:stretch-slim
,并使用
码头工人 build . --build-arg arch=amd64 docker build . --build-arg arch=armhf docker build . --build-arg arch=arm64v8
使用多架构清单
因此,我们现在使用一个Dockerfile进行了三个构建,并以此标记它们
码头工人 build . --build-arg arch=amd64 -t ownyourbits/example-x86 docker build . --build-arg arch=armhf -t ownyourbits/example-armhf docker build . --build-arg arch=arm64v8 -t ownyourbits/example-arm64
那’很好,但是我们现在可以通过创建一个 多拱清单.

This is still an experimental CLI feature, so we need to export DOCKER_CLI_EXPERIMENTAL=enabled
to be able to access it.
export DOCKER_CLI_EXPERIMENTAL=enabled docker manifest create --amend ownyourbits/example \ ownyourbits/example-x86 \ ownyourbits/example-armhf \ ownyourbits/example-arm64 docker manifest annotate ownyourbits/example ownyourbits/example-x86 --os linux --arch amd64 docker manifest annotate ownyourbits/example ownyourbits/example-armhf --os linux --arch arm docker manifest annotate ownyourbits/example ownyourbits/nextcloudpi-arm64 --os linux --arch arm64v8 docker manifest push -p ownyourbits/example
现在,任何架构的用户都只需要做
码头工人 pull ownyourbits/example
,他们将收到图像的正确版本。
添加健康检查
Even if we run with --restart=unless-stopped
, the only clue Docker or Docker Swarm to know that things are OK is that the container has not crashed. If it is unresponsive or returning errors it won’不能正确重启。
It is more robust to add a HEALTHCHECK
statement to the Dockerfile
HEALTHCHECK CMD curl --fail http://localhost:8080/status || exit 1
大学教师’t run as root
即使容器在理论上是隔离的,但以与root用户相同的方式在其内部以root身份运行进程也不是一个好的安全实践’t以根用户身份运行Web服务器。
在构建结束时,您应该添加以下内容
RUN \ # other stuff useradd nonroot USER nonroot
Also, if possible avoid relying on sudo
and if you don’t control the Dockerfile at least run in a different user namespace with 码头工人 run -u nonroot:nonroot
.
大学教师’别忘了用–pull
使用码头工人 build --pull
in your scripts so you are always on the latest base image.
大学教师’t use MAINTAINER
MAINTAINER
不推荐使用。代替
MAINTAINER nachoparker (nacho@ownyourbits.com)
, use LABEL
s instead so they can be inspected just like any other metadata.
LABEL maintainer="纳乔帕克 (nacho@ownyourbits.com)"
尽可能避免使用ENV
ENV
variables remain in the container at run time and pollute its own environment. Use ARG
s instead.
使用缓存安装进行构建
通过为包管理器,ccache,git等提供缓存来加快构建速度。这需要启用 DOCKER_CLI_EXPERIMENTAL=enabled
# syntax=docker/dockerfile:experimental # FROM and the rest RUN --mount=type=cache,target=/var/cache/apt --mount=type=cache,target=/var/lib/apt \ apt-get install -y --no-install-recommends mongodb-server
使用SSH代理
如果您需要SSH凭据进行构建,请不要’t copy ~/.ssh
because it will stay in the layer even if you remove it later.
设置 SSH代理,并将实验功能用于 ssh挂载
RUN --mount=type=ssh git clone //github.com/private_repo/repo.git
使用构建机密
如果您需要不应该公开的敏感文件,请使用 机密. This way, those files will only be visible to that RUN
command during its execution and its contents will disappear without a trace from all layers after that.
RUN --mount=type=secret,id=signing_key,dst=/tmp/sign.cert signing_command
再次阅读官方建议
虽然我指出对我来说最大的罪犯是什么,但回顾一下官方建议 最佳做法.
我们大多数人都熟悉:编写小型容器,重新排列图层以利用构建缓存,’添加不必要的软件包,但是’回到它并发现我们之前可能错过的东西并不少见。
2 Comments