多平台容器镜像构建就看这一篇 (2)

可以看出来 manifest list 是一个 JSON 数组,数组当中应用了不同平台镜像的 Manifest。所以,推送多平台镜像时,我们需要先分别推送不同平台的镜像层;然后创建 manifest list , 再引用平台镜像的 Manifest,最后把 manifest list 上传到 Registry 服务。而拉取镜像时,客户端应当设置 HTTP 的请求头字段 Accept 值为 application/vnd.docker.distribution.manifest.v2+json和application/vnd.docker.distribution.manifest.list.v2+json,然后检查服务端返回的响应头字段Content-Type 判断是旧镜像格式,新镜像格式或者时镜像清单。

抛开规格文档来说,只要我们使用的 Registry 服务的 Distribution 版本不低于 v2.3,Docker CLI 版本不低于 v1.10 就能过支持多平台镜像功能。

构建多平台镜像

要构建多平台的容器镜像,我们需要确保容器基础镜像和应用程序的代码或者二进制都是目标平台的。

程序代码

一些编程语言的编译器能够为其它平台编译二进制文件,最为著名的包括 Golang 和 Rust。我们将使用 Golang 编写一个演示用 web 程序——通过 HTTP 访问查看 web 服务程序的操作系统、硬件平台等信息。具体代码如代码段-03 所示。

// 代码段-03 package main import ( "net/http" "runtime" "github.com/gin-gonic/gin" ) var ( r = gin.Default() ) func main() { r.GET("http://www.likecs.com/", indexHandler) r.Run(":9090") } func indexHandler(c *gin.Context) { var osinfo = map[string]string{ "arch": runtime.GOARCH, "os": runtime.GOOS, "version": runtime.Version(), } c.JSON(http.StatusOK, osinfo) }

我们在 MacOS 上使用 go run 运行代码段-03, httpie 工具访问本机:9090 端口,将会看见如下信息。

enter image description here

代码准备好了,现在我们有两种构建方法:手动编译,使用 docker build 构建镜像;使用 docker buildx 工具自动化编译构建。

手动编译构建 前置条件

Dockerd 启用 experimental

我们需要在 Docker daemon 配置文件中配置 "experimental": true开启实验性功能:

$ vi /etc/docker/daemon.json { "experimental": true }

修改 Docker daemon 配置需要重启服务使配置生效:

$ sudo systemctl restart docker.service

使用 docker version 命令查看版本信息,配置生效后可以看到 Server: Docker Engine 中有 Experimental: true :

$ sudo docker version Client: Docker Engine - Community Version: 19.03.12 API version: 1.40 Go version: go1.13.10 Git commit: 48a66213fe Built: Mon Jun 22 15:45:36 2020 OS/Arch: linux/amd64 Experimental: false Server: Docker Engine - Community Engine: Version: 19.03.12 API version: 1.40 (minimum version 1.12) Go version: go1.13.10 Git commit: 48a66213fe Built: Mon Jun 22 15:44:07 2020 OS/Arch: linux/amd64 Experimental: true containerd: Version: 1.2.13 GitCommit: 7ad184331fa3e55e52b890ea95e65ba581ae3429 runc: Version: 1.0.0-rc10 GitCommit: dc9208a3303feef5b3839f4323d9beb36df0a9dd docker-init: Version: 0.18.0 GitCommit: fec3683 `

如果您使用的 Docker CLI 版本低于 v20.10 ,执行 docker manifest 命令会看到报错提示 docker manifest is only supported on a Docker cli with experimental cli features enabled ,此时我们需要执行 export DOCKER_CLI_EXPERIMENTAL="enabled" 开启客户端实验特性支持。在 v20.10 及以上版本的 Docker CLI 会默认开启实验特性,无需额外操作。

交叉编译

在我们的 Golang 代码中没有使用 CGO 的时候,通过简单设置环境变量就能够交叉编译出其它平台和操作系统上能够执行的二进制文件。其中:

GOARCH 用于指定编译的目标平台,如 amd64、arm64、riscv64 等平台。

GOOS 用于指定编译的目标系统,如 darwin、linux。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wspzxj.html