后浪笔记一零二四

buildkit和buildx

buildx是docker cli的插件,镜像构建是通过调用buildkit api实现的。

BuildKit 被设计成可以很好地支持多个平台进行镜像构建,构建时,可以设置 –platform 标志来指定构建输出的目标平台。

Buildx 和 Dockerfiles 支持三种不同策略来构建多平台映像(参考 https://docs.docker.com/build/building/multi-platform/):

  1. 在内核中使用 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 镜像来安装。

1
2
3
4
5
# 参考: https://github.com/tonistiigi/binfmt
$ docker run --privileged --rm tonistiigi/binfmt --install all

# 查看构建器信息
$ docker buildx ls
  1. 使用相同的构建器实例在多个原生节点上构建

使用多个原生节点可以支持 QEMU 无法处理的复杂情况,并且通常具有更好的性能。您可以使用 –append 标志向构建器实例添加额外的节点。

假设在 docker context ls 中存在 node-amd64 和 node-arm64 上下文:

1
2
3
$ docker buildx create --use --name mybuild node-amd64
$ docker buildx create --append --name mybuild node-arm64
$ docker buildx build --platform linux/amd64,linux/arm64 .
  1. 使用 Dockerfile 中的一个阶段交叉编译到不同的架构

Dockerfiles 中的多阶段构建可以有效地用于为使用 –platform 指定的平台构建二进制文件,使用构建节点的本地架构。像 BUILDPLATFORM 和 TARGETPLATFORM 这样的构建参数列表在你的 Dockerfile 中自动可用,并且可以被作为构建的一部分运行的进程所利用。

1
2
3
4
5
6
FROM --platform=$BUILDPLATFORM golang:alpine AS build
ARG TARGETPLATFORM
ARG BUILDPLATFORM
RUN echo "I am running on $BUILDPLATFORM, building for $TARGETPLATFORM" > /log
FROM alpine
COPY --from=build /log /log

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
  1. 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"]
  1. 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没有指定其他命令时运行。

  1. 如果docker run指定了其他命令,CMD指定的默认命令被忽略。
  2. 如果Dockerfile中有多个CMD指令,只有最后一个CMD有效

CMD有三种格式

  1. Exec格式:CMD [“executable”, “param1”, “param2”]
  2. CMD格式:CMD [“param1”, “param2”]为ENTRYPOINT提供额外的参数,此时ENTRYPOINT必须使用Exec格式。
  3. 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中格式:

  1. Exec格式
  2. 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 」,也可搜索「 后浪笔记一零二四 」找到我。


上一篇 « 下一篇 »

赞赏支持

请我吃鸡腿 =^_^=

i ysf

云闪付

i wechat

微信

推荐阅读

Big Image