Docker多平台、跨平台编译打包
大多数带有Docker官方标识的镜像都提供了多架构支持。如:busybox镜像支持amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, ppc64le, and s390x。当你在amd64设备上运行容器时,会拉取amd64镜像。
当你需要构建多平台镜像时,可以用 --platform 参数指定目标平台,但是通常情况下,你只能一次构建一个单一架构平台的镜像。如果想要一次构建多平台镜像,你需要使用docker container build driver,可以使用buildx插件进行配置,替换打包命令。
QEMU
跨平台打包可以使用QEMU,但是它比本机构建慢得多,依赖QEMU将本机指令转义为目标架构指令,从而实现跨平台编译。一般Linux kernel 4.8以后版本,支持binfmt-support 2.1.7及以上版本的平台,都能支持跨平台编译。你可以用以下步骤快速开启:
docker run --privileged --rm tonistiigi/binfmt --install all
为不同架构平台创建本地节点,--apend可以追加到同一个构建器中:
docker buildx create --use --name mybuild node-amd64
mybuild
docker buildx create --append --name mybuild node-arm64
同时构建多平台镜像:
docker buildx build --platform linux/amd64,linux/arm64 .
这里用buildx插件代替默认build,一次打包多平台镜像,不做过多介绍。
交叉编译
docker可以轻松打包多平台的镜像,但是目标程序的交叉编译取决于开发编译环境。Golang就很容易实现交叉编译,结合docker多阶段构建技术,可以实现一次编译打包多平台镜像。
首先安装buildx插件,
下载
重命名并放到docker插件目录里:
mv buildx-v0.11.2.linux-amd64 docker-buildx
mkdir .docker/cli-plugins -p
mv docker-buildx .docker/cli-plugins/
chmod +x .docker/cli-plugins/docker-buildx
docker-compose也可以作为插件放到插件目录里,
mv docker-compose .docker/cli-plugins/
使用时可用如下的命令,无需使用docker-compose,这是题外话。
docker compose up -d
其次创建构建器,
$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder * docker-containermybuilder0 unix:///var/run/docker.sock running v0.12.3 linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/arm64, linux/riscv64, linux/ppc64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default dockerdefault default running v0.8.2+eeb7b65 linux/amd64, linux/386, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/arm/v7, linux/arm/v6
ls命令列出已有的构建器,default是docker默认的构建器,mybuilder是我创建的构建器,可以用如下命令进行创建,
docker buildx create --name mybuilder --bootstrap --use
这条命令会创建mybuilder构建器,并启动,设置为默认构建器。
到这里环境就算配置好了,但是要想编译打包多平台镜像,还需要编辑Dockerfile,
FROM --platform=$BUILDPLATFORM golang:latest AS builder
ARG TARGETARCH
RUN apt-get update && apt-get install -y gcc-aarch64-linux-gnu
WORKDIR /app
COPY . .
RUN go env -w GOOS=linux GOARCH=$TARGETARCH CGO_ENABLED=1 GOPROXY=https://goproxy.cn,direct
RUN if [ "$TARGETARCH" = "arm64" ]; then go env -w AR=aarch64-linux-gnu-ar CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++; fi
RUN go mod tidy
RUN go build -a -ldflags '-extldflags "-static"' -o server main.goFROM alpine:latest
RUN set -eux && sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories
RUN apk update && apk add sqlite
WORKDIR /server
RUN mkdir -p /server/data
COPY --from=builder /app/server /app/config.docker.yaml ./
COPY --from=builder /app/resource/cert ./resource/cert
EXPOSE 8660
ENTRYPOINT ./server -c config.docker.yaml
上面的Dockerfile采用多阶段构建方式支持交叉编译,多平台打包。
第一阶段进行交叉编译
第二阶段进行目标平台镜像打包
里面用到docker-container驱动的环境变量有:
BUILDPLATFORM 编译平台,即当前宿主机的平台架构
TARGETPLATFORM
BUILDARCH
TARGETARCH 目标平台架构,即多平台编译打包时的目标架构GOARCH=$TARGETARCH 指定了Go编译目标架构
golang:latest、alpine:latest镜像都是支持多架构的镜像,golang:latest是基于debian构建,为了交叉编译,需要安装交叉编译环境,
apt-get install -y gcc-aarch64-linux-gnu
因为Go程序中用到了cgo特性,需要打开它
CGO_ENABLED=1
同时,如果目标平台是arm64的话,需配置go gcc等编译器环境变量
RUN if [ "$TARGETARCH" = "arm64" ]; then go env -w AR=aarch64-linux-gnu-ar CC=aarch64-linux-gnu-gcc CXX=aarch64-linux-gnu-g++; fi
最后,执行buildx命令
docker buildx build --platform linux/arm64,linux/amd64 -t 172.16.60.12:8888/star/iot-go . --push
编译打包多平台镜像并推送到仓库中。也可以输出单一平台,并保存到本地,
docker buildx build --platform linux/arm64 -t star/iot-go . --load
参考资料:
Multi-platform images | Docker Docs
How to use docker buildx to build multi-architecture Go images
相关文章:
Docker多平台、跨平台编译打包
大多数带有Docker官方标识的镜像都提供了多架构支持。如:busybox镜像支持amd64, arm32v5, arm32v6, arm32v7, arm64v8, i386, ppc64le, and s390x。当你在amd64设备上运行容器时,会拉取amd64镜像。 当你需要构建多平台镜像时,可以用 --platf…...
LLM系列 | 22 : Code Llama实战(下篇):本地部署、量化及GPT-4对比
引言 模型简介 依赖安装 模型inference 代码补全 4-bit版模型 代码填充 指令编码 Code Llama vs ChatGPT vs GPT4 小结 引言 青山隐隐水迢迢,秋尽江南草未凋。 小伙伴们好,我是《小窗幽记机器学习》的小编:卖热干面的小女孩。紧接…...
Nginx的进程结构实例演示
可以参考《Ubuntu 20.04使用源码安装nginx 1.14.0》安装nginx 1.14.0。 nginx.conf文件中worker_processes 2;这条语句表明启动两个worker进程。 sudo /nginx/sbin/nginx -c /nginx/conf/nginx.conf开启nginx。 ps -ef | grep nginx看一下进程情况。 sudo /nginx/sbin/ng…...
【Nginx36】Nginx学习:SSI静态文件服务器端包含模块
Nginx学习:SSI静态文件服务器端包含模块 这个模块让我想到了 2009 年刚刚工作的时候。最早我是做 .NET 的,而第一家公司其实是从 ASP 向 ASP.NET 转型中,因此,还是有不少的 ASP 做的页面。在那个时候,就用到了 SSI 。 …...
StripedFly恶意软件框架感染了100万台Windows和Linux主机
导语 近日,一款名为StripedFly的恶意软件框架在网络安全研究人员的监视之外悄然感染了超过100万台Windows和Linux系统。这款跨平台的恶意软件平台在过去的五年中一直未被察觉。在去年,卡巴斯基实验室发现了这个恶意框架的真实本质,并发现其活…...
蓝桥杯每日一题2023.10.25
乘积尾零 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 由于需要相乘的数很多,所以我们不能直接进行暴力模拟,我们知道10 2 * 5, 所以我们只需要找出这个数2和5的个数,其中2和5个数小的那个则为末尾0出现的个数 #include<bi…...
【C++】详解map和set基本接口及使用
文章目录 一、关联式容器与键值对1.1关联式容器(之前学的都是序列容器)1.2键值对pairmake_pair函数(map在插入的时候会很方便) 1.3树形结构的关联式容器 二、set2.1set的基本介绍2.1默认构造、迭代器区间构造、拷贝构造࿰…...
如何学习 Linux 内核内存管理
Linux内核内存管理部分是Linux内核中第二复杂的部分,但也非常有趣。学习它的最佳方法就是阅读代码。但在不了解术语和当前 mm 部分到底发生了什么的情况下,显然不能随意开始阅读代码。因此,我想这样开始学习比较好: 了解当前的 LS…...
【计算机网络】(谢希仁第八版)第一章课后习题答案
1.计算机网络可以向用户提供哪些服务? 答:例如音频,视频,游戏等,但本质是提供连通性和共享这两个功能。 连通性:计算机网络使上网用户之间可以交换信息,好像这些用户的计算机都可以彼此直接连…...
Operator开发之operator-sdk入门
1 operator-sdk 除了kubebuilder,operator-sdk是另一个常用的用于开发Operator的框架,不过operator-sdk还是基于kubebuilder,因此,通常还是建议使用kubebuilder开发Operator。 2 环境准备 跟kubebuilder类似,需要安…...
RabbitMQ生产者的可靠性
目录 MQ使用时会出现的问题 生产者的可靠性 1、生产者重连 2、生产者确认 3、数据持久化 交换机持久化 队列持久化 消息持久化 LazyQueue懒加载 MQ使用时会出现的问题 发送消息时丢失: 生产者发送消息时连接MQ失败生产者发送消息到达MQ后未找到Exchange生…...
集群节点批量执行 shell 命令
1、SSH 工具本身支持多窗口 比如 MobaXterm: 2、编写脚本通过 ssh 在多台机器批量执行shell命令 创建 ssh_hosts 配置文件,定义需要批量执行的节点(必须能够通过 ssh 免密登录,且存在同名用户) vim ssh_hostsbig…...
fl studio21.2水果软件怎么设置中文?
FL Studio编曲软件真的是个神器,不过一开始打开看到全是英文,有点头大,对吧?其实切换成中文版超级简单,只需要几个步骤就搞定啦!我自己也是用中文版的,觉得用起来更得心应手,效率也提…...
.NET CORE 3.1 集成JWT鉴权和授权2
JWT:全称是JSON Web Token是目前最流行的跨域身份验证、分布式登录、单点登录等解决方案。 通俗地来讲,JWT是能代表用户身份的令牌,可以使用JWT令牌在api接口中校验用户的身份以确认用户是否有访问api的权限。 授权:这是使用JWT的…...
nbcio-boot如何进行gitee第三方登录
更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码: https://gitee.com/nbacheng/nbcio-boot 前端代码:https://gitee.com/nbacheng/nbcio-vue.git 在线演示(包括H5) : http://122.227.135.243:9888 1、用户g…...
【C语言】字符函数、字符串函数与内存函数
简单不先于复杂,而是在复杂之后。 目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1 介绍 1.1.2 strlen 函数模拟实现 1.1.2.1 计数器方法 1.1.2.2 递归方法 1.1.2.3 指针 - 指针方法 1.2 strcpy 1.2.1 介绍 1.2.2 strcpy 函数模拟实现 1.3 strcat 1…...
生成树协议:监控 STP 端口和交换机
什么是生成树协议 生成树协议 (STP) 用于网络交换机,以防止循环和广播风暴。在局域网 (LAN) 中,两条或多条冗余路径可以连接到同一网段。当交换机或网桥从所有可用端口传输帧时,这些帧开始在网…...
【黑产攻防道03】利用JS参数更新检测黑产的协议破解
任何业务在运营一段时间之后都会面临黑产大量的破解。验证码和各种爬虫的关系就像猫和老鼠一样, 会永远持续地进行博弈。极验根据十一年和黑产博弈对抗的经验,将黑产的破解方式分为三类: 1.通过识别出验证码图片答案实现批量破解验证,即图片…...
什么是web3.0?
Web 3.0,也常被称为下一代互联网,代表着互联网的下一个重大演变。尽管关于Web 3.0的确切定义尚无共识,但它通常被认为是一种更分散、更开放且更智能的互联网。 以下是Web 3.0的一些主要特征和概念: 1. 去中心化 Web 3.0旨在减少…...
二、W5100S/W5500+RP2040树莓派Pico<DHCP>
文章目录 1 前言2 简介2 .1 什么是DHCP?2.2 为什么要使用DHCP?2.3 DHCP工作原理2.4 DHCP应用场景 3 WIZnet以太网芯片4 DHCP网络设置示例概述以及使用4.1 流程图4.2 准备工作核心4.3 连接方式4.4 主要代码概述4.5 结果演示 5 注意事项6 相关链接 1 前言 …...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
JavaScript基础-API 和 Web API
在学习JavaScript的过程中,理解API(应用程序接口)和Web API的概念及其应用是非常重要的。这些工具极大地扩展了JavaScript的功能,使得开发者能够创建出功能丰富、交互性强的Web应用程序。本文将深入探讨JavaScript中的API与Web AP…...
Linux 中如何提取压缩文件 ?
Linux 是一种流行的开源操作系统,它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间,使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的,要在 …...
GO协程(Goroutine)问题总结
在使用Go语言来编写代码时,遇到的一些问题总结一下 [参考文档]:https://www.topgoer.com/%E5%B9%B6%E5%8F%91%E7%BC%96%E7%A8%8B/goroutine.html 1. main()函数默认的Goroutine 场景再现: 今天在看到这个教程的时候,在自己的电…...
