docker buildx构建多平台架构镜像

通过 binfmt_misc 模拟目标硬件的用户空间

在 Linux 上,QEMU 除了可以模拟完整的操作系统之外,还有另外一种模式叫 用户态模式(User mod)。该模式下 QEMU 将通过 binfmt_misc 在 Linux 内核中注册一个二进制转换处理程序,并在程序运行时动态翻译二进制文件,根据需要将系统调用从目标 CPU 架构转换为当前系统的 CPU 架构。最终的效果看起来就像在本地运行目标 CPU 架构的二进制文件。

通过 QEMU 的用户态模式,我们可以创建轻量级的虚拟机,然后在虚拟机系统中编译程序,和本地编译一样简单轻松。后面我们就会看到,跨平台构建 Docker 镜像用的就是这个方法。
docker 版本不低于19.03 建议20以上

linux系统内核建议4.X以上,不然会报错
# Cannot write to /proc/sys/fs/binfmt_misc/register: write /proc/sys/fs/binfmt_misc/register: invalid argument

查看buildx是否开启

docker buildx version
github.com/docker/buildx v0.5.1-docker 11057da37336192bfc57d81e02359ba7ba848e4a

# 如果没有开启,可通过以下两种方式开启
1.export DOCKER_CLI_EXPERIMENTAL=enabled
2.编辑/etc/docker/daemon.json,新增如下条目
{
  "experimental": true
}

docker buildx介绍 https://docs.docker.com/buildx/working-with-buildx/

启用 binfmt_misc

docker run --rm --privileged docker/binfmt:a7996909642ee92942dcd6cff44b9b95f08dad64

# 验证
ls -al /proc/sys/fs/binfmt_misc/
# 会有qemu相关文件

# 验证是否启用了相应的处理器
cat /proc/sys/fs/binfmt_misc/qemu-aarch64

从默认的构建器切换到多平台构建器

docker buildx create --use --name mybuilder
docker buildx use mybuilder

# 启动构建器
docker buildx inspect mybuilder --bootstrap

# 查看当前使用的构建器及构建器支持的 CPU 架构,可以看到支持很多 CPU 架构
docker buildx ls

构建多平台镜像


cat > hello.go <<EOF
package main

import (
        "fmt"
        "runtime"
)

func main() {
        fmt.Printf("Hello, %s!\n", runtime.GOARCH)
}
EOF

cat > Dockerfile <<EOF
FROM golang:alpine AS builder
ENV GO111MODULE auto
RUN mkdir /app
ADD . /app/
WORKDIR /app
RUN go build -o hello .

FROM alpine
RUN mkdir /app
WORKDIR /app
COPY --from=builder /app/hello .
CMD ["./hello"]
EOF

# 现在就可以使用 buildx 构建一个支持 arm、arm64 和 amd64 多架构的 Docker 镜像了,同时将其推送到 Docker Hub
docker buildx build -t giaogiao/hello --platform=linux/arm,linux/arm64,linux/amd64 . --push

# 需要提前通过 docker login 命令登录认证 Docker Hub

# buildx 会通过 QEMU 和 binfmt_misc 分别为 3 个不同的 CPU 架构(arm,arm64 和 amd64)构建 3 个不同的镜像。构建完成后,就会创建一个 manifest list,其中包含了指向这 3 个镜像的指针。

# 现在就可以通过 docker pull giaogiao/hello 拉取刚刚创建的镜像了,Docker 将会根据你的 CPU 架构拉取匹配的镜像


多平台构建参考

保存到本地并推送到私有仓库

# 如果想将构建好的镜像保存在本地,可以将 type 指定为 docker,但必须分别为不同的 CPU 架构构建不同的镜像,不能合并成一个镜像,即:
docker buildx build -t giaogiao/hello-arch --platform=linux/arm -o type=docker .
docker buildx build -t giaogiao/hello-arch --platform=linux/arm64 -o type=docker .
docker buildx build -t giaogiao/hello-arch --platform=linux/amd64 -o type=docker .

推送私有仓库参考

你可能感兴趣的:(容器管理,docker,架构,linux)