首页 > 其他分享 >四、Docker Buildx 构建支持多系统架构的Docker镜像

四、Docker Buildx 构建支持多系统架构的Docker镜像

时间:2023-08-25 16:12:54浏览次数:36  
标签:Buildx buildx linux go 镜像 Docker docker

一、前言

1. 本文主要内容

使用 Docker Buldx 构建支持AMD64、ARM、ARM64等架构的镜像并传送到Docker Hub。

2. 环境支持

  1. 安装Docker >= 19.03
    该版本包含 buildx,该功能仅适用于 Docker v19.03+ 版本。

  2. Linux kernel >= 4.8
    自该Linux内核版本 binfmt_misc 支持 fix-binary (F) flag。fix_binary 标志允许内核在容器或chroot内使用binfmt_misc注册的二进制格式处理程序,即使该处理程序二进制文件不是该容器或chroot内可见的文件系统的一部分。

3. 启用 Buildx

Docker在19.03引入了一个新的特性,使得Docker可以构建不同CPU体系结构的镜像,比如ARM镜像,这是不必引入模拟器的情况下,Docker自身所提供的原生统一构建机制,但是使用时需要进行设定才能进行使用。(从 v20.10 版本开始,Docker CLI 所有实验特性的命令均默认开启,无需再进行配置或设置系统环境变量。)

buildx 命令属于实验特性,因此首先需要开启该特性。

运行命令

docker buildx version

出现如下问题,因为没开启Buildx 特性

docker: 'buildx' is not a docker command.
See 'docker --help'

运行命令安装

docker buildx install

在此运行命令,出现版本即可

docker buildx version
github.com/docker/buildx v0.9.1-docker ed00243a0ce2a0aee75311b06e32d33b44729689

查看已有的builder 实例

docker buildx ls

NAME/NODE    DRIVER/ENDPOINT             STATUS  BUILDKIT PLATFORMS
mybuilder *  docker-container                             
  mybuilder0 unix:///var/run/docker.sock stopped          
default      docker                                       
  default    default                     running 20.10.21 linux/amd64, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6

如果缺少一些架构,可以执行以下命令增加

docker run --privileged --rm tonistiigi/binfmt --install all

二、镜像制作准备

1. 准备应用代码

用 golang 简单的写了一个 http server,监听8000端口,默认输出helloworld,并返回操作系统、HostName以及IP地址信息

新建 main.go 保存以下代码

package main

import (
    "fmt"
    "log"
    "net"
    "net/http"
    "os"
    "runtime"
    "strings"
)

func getHostName() string {
    hostname, err := os.Hostname()
    if err != nil {
        log.Fatalf("Failed to open log file: %v", err)
    }
    return hostname
}

func getIpAddresses() string {
    addrs, err := net.InterfaceAddrs()
    if err != nil {
        log.Fatal(err)
        return ""
    }
    var ips []string
    for _, address := range addrs {
        if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
            if ipnet.IP.To4() != nil {
                ips = append(ips, ipnet.IP.String())
            }
        }
    }
    return strings.Join(ips, ",")
}

func handler(w http.ResponseWriter, r *http.Request) {
    log.Println("received request from", r.RemoteAddr, r.URL.Path[1:])
    var welcome = r.URL.Path[1:]
    if len(welcome) == 0 {
        welcome = "World"
    }
    fmt.Fprintf(w, "Hello, %s!  ---ken.io \r\n", welcome)
	fmt.Fprintf(w, "OS:%s/%s,Host:%s,IP:%s\r\n", runtime.GOOS, runtime.GOARCH, getHostName(), getIpAddresses())
}

func main() {
    http.HandleFunc("/", handler)
    log.Println("starting server on port 8000")
    log.Fatal(http.ListenAndServe(":8000", nil))
}

2. 编写Dockerfile 文件

新建 Dockerfile.build 文件并保存以下内容

# 使用官方提供的 Go 镜像作为基础镜像
FROM --platform=$TARGETPLATFORM$ golang:1.20

# 将工作目录设置为 /app
WORKDIR /app

# 将helloworld.go复制到 /app 下
COPY main.go /app

# 设置go mod 镜像
RUN go env -w GO111MODULE=on
RUN go env -w  GOPROXY=https://goproxy.cn,direct

# 导入依赖的Redis go module
RUN go mod init main

# 允许宿主机访问容器的 8000 端口
EXPOSE 8000

# 设置容器进程为:go run helloworld.go
CMD go run main.go

$TARGETPLATFORM 是内置变量,由 --platform 参数来指定其值

由于是基于 golang 的镜像来制作的,而 golang 是支持以下 7 种系统架构的,因此我们制作的镜像也就跟着支持这 7 种系统架构

linux/amd64, linux/arm/v6, linux/arm/v7, linux/arm64/v8, linux/386, linux/ppc64le, linux/s390x

这里穿插一句吐槽,简单统计了一下,ARM 的系统架构有如下各种简称:

arm64, armv8l, arm64v8, aarch64
arm, arm32, arm32v7, armv7, armv7l, armhf
arm32v6, armv6, armv6l, arm32v5, armv5,  armv5l, armel, aarch32

而对比 Intel 和 AMD 的就简单多了:

x86, 386, i386, i686
x86_64, x64, amd64

三、镜像制作

1. 确认 基础镜像 支持架构

2. 登录账号

访问 https://hub.docker.com/signup 注册账号,然后在Docker Desktop登录账号,或者通过命令登录

# 登录命令
docker login

# 根据命令号交互输入注册时的账号密码即可成功登录
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: xxx
Password:
Login Succeeded

Logging in with your password grants your terminal complete access to your account.
For better security, log in with a limited-privilege personal access token. Learn more at https://docs.doc

3. 构建镜像

# 进入main.go 所在目录
cd /data/dev


# 构建镜像(默认为latest)(注意结尾一定要加.)
# 这里选择构建常用 linux/amd64,linux/arm64 的架构,如有需要可以根据支持的架构自行追加或删减
docker buildx build \
--platform linux/amd64,linux/arm64 \
-f Dockerfile.build \
-t shyurongli/go-buildx . --push

4. 查看构建结果

命令执行成功后,你就会在 Docker Hub 看到你上传的镜像啦。示例图如下:
image

5. 镜像测试

# 拉取镜像
docker pull shyurongli/go-buildx

# 启动容器
docker run -itd --name go-buildx -p 8000:8000 shyurongli/go-buildx

# 访问测试
curl localhost:8000

# 输出示例
Hello, World!  ---ken.io 
OS:linux/amd64,Host:68dc587fb24f,IP:172.17.0.3

6. 查看镜像信息

docker buildx imagetools inspect shyurongli/go-buildx

image

最后

在制作多系统架构的 Docker 镜像时,建议使用 CPU 比较强或者多核心的 VPS 来构建,否则会非常耗时,本篇文章主要讲的是手动进行多架构镜像的构建,也可以是用cicd工具来自动化进行构建,后续文章进行说明

参考链接

标签:Buildx,buildx,linux,go,镜像,Docker,docker
From: https://www.cnblogs.com/shyurongli/p/17657011.html

相关文章

  • docker-compose的简单使用并搭建zookeeper集群
    简介DockerCompose是一个用于定义和运行多容器Docker应用程序的工具。它能够简化在单个主机上使用多个容器的部署过程。使用DockerCompose,您可以使用简单的YAML文件来定义应用程序的服务、网络和卷,并通过单个命令一键启动、停止和重建整个应用程序。DockerCompose允许......
  • linux docker公网源下载示例
    1.get-docker.sh百度一下,进入docker官网直接下载该文件,然后执行即可2.直接下载repo文件示例:wgethttps://download.docker.com/linux/centos/docker-ce.repo-O/etc/yum.repos.d/docker.sh--no-check或者yum-config-manager--add-repohttps://download.docker.com/lin......
  • Docker下spark环境搭建
    RUNecho"InstallSpark"&&\wget-O/tmp/spark-2.3.4-bin-hadoop2.6.tgzhttp://mirror.bit.edu.cn/apache/spark/spark-2.3.4/spark-2.3.4-bin-hadoop2.6.tgz&&\cd/tmp/&&\tar-zxvf/tmp/spark-2.3.4-bin-hado......
  • 交互式Docker以及Yaml
    EulerOS、openEulerEulerOSLinux又为被称为华为欧拉Linux.华为欧拉系统主要针对企业级的Linux服务器操作系统,针对B端用户,一般用在企业的大型计算机上,是企业IT系统的基础架构平台进程内存管理网络容器技术编译系统、虚拟存储系统、CPU调度、IO驱动、网络和文件系统Harm......
  • docker 清除日志文件
    查看日志大小:在linux系统中创建docker_logs.sh文件,输入sh docker_logs.sh命令查看日志文件大小/var/lib/docker/containers为docker默认日志输出路径echo"========dockercontainerslogsfilesize========"logs=$(find/var/lib/docker/containers/-name*-json.log)......
  • Exceptionless系列:简介和部署(Windows、Linux、Docker)
    目录一、简介二、版本三、运行说明1、Exceptionless2、Elasticsearch3、Exceptionless.UI四、打包Exceptionless.UI五、window部署1.Elasticsearch2.Exceptionless六、Docker部署一、简介Exceptionless为您提供了跟踪错误、日志和事件的工具,同时指导您找到可行的解决方案。首先......
  • Docker 安装Redis 无法使用配置文件设置密码问题
    背景最近开发需要使用各种组件,如果都到开发机上安装,会占用电脑资源较多。所以使用docker容器来安装这些组件。例如redis、mongodb、mysql、rabitmq、elasticsearch等等。遇到的问题用edis官方镜像启动容器后,发现没有加载配置文件。解决方案1.redis镜像拉下来......
  • 使用 docker 打包构建部署 Vue 项目,一劳永逸解决node-sass安装问题
    文章源于Jenkins构建Vue项目失败,然后就把node_modules删了重新构建发现node-sass安装不上了,折腾一天终于可以稳定构建了。犹记得从学node的第一天,就被node-sass折磨了一整天,后面本地没问题了然后服务器开始折磨了,这次又遇到,尝试了一次又一次,还是用本地包构建最稳,觉......
  • 三、利用 Docker-Slim 缩小 Docker 镜像大小
    有时项目构建出来的Docker大小挺大的,找了好几个缩小Docker镜像的方法,在这里分享一个很棒的方法来优化和缩小Docker镜像并减小镜像体积大小。Docker-SlimDocker-Slim不会更改Docker容器映像中的任何内容并将其缩小多达30倍。Docker-Slim将通过使用各种分析技术了解您的......
  • docker想保留ip和端口其他的不要,想把这个变成linux的命令怎么做?
    docker想保留ip和端口其他的不要,想把这个变成linux的命令怎么做?dockerps只会显示这样一坨东西,看ip和端口又不好看456746ec7581moxi/mogu_blog_nacos"/usr/sbin/init"12hoursagoUp12hours0.0.0.0:465->465/tcp,:::465->465/tcp,0.0.0.0:3306->3306/tcp,:......