buildkit和buildx
buildx是docker cli的插件,镜像构建是通过调用buildkit api实现的。
BuildKit 被设计成可以很好地支持多个平台进行镜像构建,构建时,可以设置 –platform 标志来指定构建输出的目标平台。
Buildx 和 Dockerfiles 支持三种不同策略来构建多平台映像(参考 https://docs.docker.com/build/building/multi-platform/):
- 在内核中使用 QEMU 模拟支持
当 BuildKit 需要为不同的体系构建运行二进制文件时,它会通过在 binfmt_misc 处理程序中注册的二进制文件自动加载它。
为了在主机操作系统上注册到 binfmt_misc 的 QEMU 二进制文件透明地在容器中工作,它们必须使用fix_binary标志进行注册。这需要一个内核 kernel >= 4.8 和 binfmt-support >= 2.1.7。您可以通过检查 F 是否在 /proc/sys/fs/binfmt_misc/qemu-* 中的标志中来检查是否正确注册。
虽然 Docker Desktop 为其他平台预先配置了 binfmt_misc 支持,但可能依旧需要使用 tonistiigi/binfmt 镜像来安装。
- 使用相同的构建器实例在多个原生节点上构建
使用多个原生节点可以支持 QEMU 无法处理的复杂情况,并且通常具有更好的性能。您可以使用 –append 标志向构建器实例添加额外的节点。
假设在 docker context ls 中存在 node-amd64 和 node-arm64 上下文:
- 使用 Dockerfile 中的一个阶段交叉编译到不同的架构
Dockerfiles 中的多阶段构建可以有效地用于为使用 –platform 指定的平台构建二进制文件,使用构建节点的本地架构。像 BUILDPLATFORM 和 TARGETPLATFORM 这样的构建参数列表在你的 Dockerfile 中自动可用,并且可以被作为构建的一部分运行的进程所利用。
Dockerfile 支持如下架构相关的变量:
TARGETPLATFORM 构建镜像的目标平台,例如 linux/amd64, linux/arm/v7, windows/amd64。
TARGETOS TARGETPLATFORM 的 OS 类型,例如 linux, windows
TARGETARCH TARGETPLATFORM 的架构类型,例如 amd64, arm
TARGETVARIANT TARGETPLATFORM 的变种,该变量可能为空,例如 v7
BUILDPLATFORM 构建镜像主机平台,例如 linux/amd64
BUILDOS BUILDPLATFORM 的 OS 类型,例如 linux
BUILDARCH BUILDPLATFORM 的架构类型,例如 amd64
BUILDVARIANT BUILDPLATFORM 的变种,该变量可能为空,例如 v7
FROM
支持3种格式:
FROM <image>
FROM <image>:<tag>
FROM <image>@<digest>
FROM指令必须指定,且需要在dockerfile其他指令的前面,指定的基础image可以是官方远程仓库中的,也可以位于本地仓库。 后续的指令都依赖于该指令指定的image。
WORKDIR
WORKDIR指令用于指定容器的一个目录,容器启动时执行的命令会在该目录下执行。
RUN
RUN执行命令并创建新的镜像层,RUN经常用于安装软件包
ADD
将本地文件或文件夹添加到docker镜像的指定文件下 COPY和ADD命令具有相同的特点:只复制目录中的内容而不包含目录本身。 比如:
nickdir/
- file1
- file2
WORKDIR /app
COPY nickdir .
app/
- file1
- file2
- COPY命令区别于ADD命令的一个用法是在multistage场景中。在multistage的用法中, 可以使用COPY命令把前一阶段构建的产物拷贝到另一个镜像中,比如:
# Dockerfile.build
FROM golang:1.7.3
WORKDIR /go/src/github.com/sparkdevo/href-counter/
RUN go get -d -v golang.org/x/net/html
COPY app.go .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app .
# Dockerfile
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
# COPY命令需要通过指定--from=0参数,把前一个阶段构建的产物拷贝到当前的镜像中
COPY --from=0 /go/src/github.com/sparkdevo/href-counter/app .
CMD ["./app"]
- ADD命令还可以干其他事情
- 解压压缩文件并把它们添加到镜像中
- 从url拷贝文件到镜像中
ENV
设置镜像的环境变量
ARG
设置构建参数的默认值,在构建命令docker build
中用--build-arg <参数名>=<值>
来覆盖它的值。
在 1.13 之前的版本,要求 –build-arg 中的参数名,必须在 Dockerfile 中用 ARG 定义过了,换句话说, 就是 –build-arg 指定的参数,必须在 Dockerfile 中使用了。如果对应参数没有被使用,则会报错退出构建。 从 1.13 开始,这种严格的限制被放开,不再报错退出,而是显示警告信息,并继续构建。
ARG 指令有生效范围,如果在 FROM 指令之前指定,那么只能用于 FROM 指令中。 如果想在FROM指令之后使用该变量,就在FROM指令之后再定义一遍。
CMD
CMD指令允许用户指定容器的默认执行的命令 此命令会在容器启动且docker run没有指定其他命令时运行。
- 如果docker run指定了其他命令,CMD指定的默认命令被忽略。
- 如果Dockerfile中有多个CMD指令,只有最后一个CMD有效
CMD有三种格式
- Exec格式:CMD [“executable”, “param1”, “param2”]
- CMD格式:CMD [“param1”, “param2”]为ENTRYPOINT提供额外的参数,此时ENTRYPOINT必须使用Exec格式。
- Shell格式:CMD command param1 param2
下面看看CMD是如何工作的。Dockerfile片段如下:
CMD echo "Hello world"
运行容器docker run -it [image]将输出:
Hello world
但当后面加上一个命令,比如docker run -it [image] bash, CMD会被忽略,命令bash将被执行:
ENTRYPOINT
ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执行的命令及其参数。 不同的地方在于 ENTRYPOINT 不会被忽略,一定会被执行,即使运行 docker run 时指定了其他命令。
ENTRYPOINT有2中格式:
- Exec格式
- Shell格式
alpine中如何安装git
FROM alpine:3.9
# set up nsswitch.conf for Go's "netgo" implementation
# https://github.com/golang/go/issues/35305
RUN [ ! -e /etc/nsswitch.conf ] && echo 'hosts: files dns' > /etc/nsswitch.conf
RUN echo "http://mirrors.tencent.com/alpine/latest-stable/main/" > /etc/apk/repositories
RUN echo "http://mirrors.tencent.com/alpine/latest-stable/community/" >> /etc/apk/repositories
#install
RUN apk update && \
apk add --no-cache \
openssh-client \
ca-certificates \
bash \
git \
rsync \
&& rm -rf /var/cache/apk/*
#git
RUN git config --global pull.rebase false
本文发表于 0001-01-01,最后修改于 0001-01-01。
本站永久域名「 jiavvc.top 」,也可搜索「 后浪笔记一零二四 」找到我。