Docker大学生看了都会系列(九、Docker使用Buildx构建不同CPU架构镜像)

news2024/12/28 18:24:09

系列文章目录
第一章 Docker介绍
第二章 2.1 Mac通过Homebrew安装Docker
第二章 2.2 CentOS安装Docker
第三章 Docker常用命令
第四章 常用命令实战
第五章 Docker镜像详解
第六章 Docker容器数据卷
第七章 Dockerfile详解
第八章 Dokcerfile部署go项目
第九章 Docker使用Buildx构建不同CPU架构镜像

文章目录

  • 一、前言
  • 二、环境
  • 三、Buildx 基本介绍
    • 3.1 什么是Buildx
    • 3.2 Buildx常见命令
  • 四、创建builder实例流程
    • 4.1 创建builder实例
    • 4.2 启动builder实例
    • 4.3 查看builder实例状态
  • 五、go项目案例
    • 5.1 config.yaml文件
    • 5.2 main.go文件
  • 六、Dockerfile文件
    • 6.1 完整的Dockerfile文件
    • 6.2 dockerfile中的环境变量
    • 6.3 构建过程说明
  • 七、 构建不同CPU架构镜像
    • 7.1 构建本地镜像
    • 7.2 保存镜像存成tar 归档文件
  • 八、拓展,写个shell文件
  • 九、总结


一、前言

在上一篇Dokcerfile部署go项目中,只讲到了在本机部署使用,实际商业需求,都需要上传到服务器。不同的服务器架构不一样。为了解决这个需求,所以需要用到Docker Buildx。

二、环境

名称备注
MackBook Pro2023年
芯片Apple M2 Pro(arm64)
macOSSonoma 14.5
操作命令对象Docker 版本26.1.3
简单go项目Go 版本1.22.2

三、Buildx 基本介绍

3.1 什么是Buildx

buildx 是 Docker 官方提供的一个构建工具,它可以帮助用户快速、高效地构建 Docker 镜像,并支持多种平台的构建。使用 buildx,用户可以在单个命令中构建多种架构的镜像,例如 x86 和 ARM 架构,而无需手动操作多个构建命令。此外,buildx 还支持 Dockerfile 的多阶段构建和缓存,这可以大大提高镜像构建的效率和速度。要安装并使用 buildx,需要 Docker Engine 版本号大于等于 19.03。如果你使用的是 Docker Desktop,则默认安装了 buildx。可以使用 docker buildx version 命令查看安装版本,得到以下类似输出,证明已经安装过了。

3.2 Buildx常见命令

更多命令可以通过--help去查找

# 查看buildx的帮助指令
docker buildx --help
# 查看当前的builder实例
docker buildx ls
# 创建新的builder实例
docker buildx create --name [NAME]
# 切换到指定的builder实例
docker buildx use [NAME]
# 检查当前builder实例确保该实例已经启动
docker buildx inspect [NAME] --bootstrap
# 开始构建镜像
docker buildx build [NAME]
# 停止builder实例
docker buildx stop [NAME]
# 删除builder实例
docker buildx rm [NAME]

四、创建builder实例流程

4.1 创建builder实例

docker buildx create --use --name mybuilder

这时候通过docker buildx ls,可以看到刚创建的mybuilder实例的状态还是inactive

4.2 启动builder实例

inspect 子命令用来检查构建器状态,--bootstrap 参数则可以启动 mybuilder构建器

docker buildx inspect --bootstrap mybuilder

4.3 查看builder实例状态

再次通过docker buildx ls,可以看到mybuilder实例的状态是running

五、go项目案例

这里还是以上一篇Dokcerfile部署go项目中gindemo项目为例,更具体的代码解释,安装过程请查看上一篇章。

5.1 config.yaml文件

mysql:
  url: 127.0.0.1
  port: 3306

5.2 main.go文件

package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"gopkg.in/yaml.v3"
	"os"
)

type Config struct {
	Mysql Mysql `json:"mysql"`
}

type Mysql struct {
	Url  string
	Port int
}

func main() {
	dataBytes, err := os.ReadFile("config.yaml")
	if err != nil {
		fmt.Println("读取文件失败:", err)
		return
	}
	config := Config{}
	err = yaml.Unmarshal(dataBytes, &config)
	if err != nil {
		fmt.Println("解析 yaml 文件失败:", err)
		return
	}

	r := gin.Default()
	r.GET("/", func(c *gin.Context) {
		c.JSON(200, gin.H{
			"Mysql": config.Mysql,
		})
	})
	r.Run(":8080")
}

六、Dockerfile文件

6.1 完整的Dockerfile文件

#Go版本,最好跟本地(本机电脑)版本一样
ARG GO_VERSION=1.22.4
FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-alpine AS builder
ARG TARGETOS
ARG TARGETARCH
#donkor是我的名字
LABEL author="donkor"

ENV GOPROXY=https://goproxy.cn,direct \
    GOOS=$TARGETOS \
    GO111MODULE=auto \
    GOARCH=$TARGETARCH
#设置国内软件仓库镜像
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories

#alpine 基础镜像中没有包含时区信息文件 所以需要安装tzdata
RUN apk update --no-cache && apk add --no-cache tzdata
#设置工作目录
WORKDIR /build
#拷贝当前所有文件到build目录
COPY . .
#安装go项目依赖
RUN go mod download

#-ldflags="-s -w" -w为去掉调试信息(无法使用gdb调试),-s为去掉符号表。 -o 编译输出的名称,代替默认的包名
RUN go build -ldflags="-s -w" -o /build/main


#FROM scratch
FROM --platform=$TARGETPLATFORM scratch
#设置时区
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo/Asia/Shanghai /usr/share/zoneinfo/Asia/Shanghai
ENV TZ Asia/Shanghai

WORKDIR /app
#拷贝编译后的二进制文件
COPY --from=builder /build/main .
#设置数据卷
VOLUME ["/app/config.yaml"]
#暴漏的端口
EXPOSE 8080
#运行程序
ENTRYPOINT ["/app/main"]

6.2 dockerfile中的环境变量

BuildKit 提供的全局变量

名称备注
BUILDPLATFORM构建节点的平台信息,例如linux/amd64、linux/arm64
TARGETOS操作系统,例如linux
TARGETARCH架构,例如amd64、arm64
TARGETPLATFORM构建镜像的目标平台,例如scratch、centos

Go 提供的全局变量

名称备注
GO_VERSIONgo版本,我们自己定义的常量
GOPROXY代理设置
GOOS操作系统
GO111MODULE环境变量
GOARCH架构

6.3 构建过程说明

构建过程分为两个阶段:

1、在一阶段中,我们将拉取一个和当前构建节点相同平台的 golang 镜像,并使用 Go 的交叉编译特性将其编译为目标架构的二进制文件
2、然后拉取目标平台的 scratch 镜像,并将上一阶段的编译结果拷贝到镜像中

七、 构建不同CPU架构镜像

7.1 构建本地镜像

docker buildx build --platform ${BUILDPLATFORM} -f Dockerfile  -t ${imgname}:${imgversion} . --load 

BUILDPLATFORM:构建节点的平台信息,例如linux/amd64、linux/arm64
--load 将镜像保存的本地主机
--push 提交到远程仓库 DockerHub

7.2 保存镜像存成tar 归档文件

docker save -o  filename.tar ${imgname}:${imgversion}

到这里,完整的构建不同CPU架构镜像的流程就完结了

八、拓展,写个shell文件

新建 buildimage.sh文件,智能化构建不同CPU镜像。只需要在终端中执行sh buildimage.sh
完整流程:
1、输入镜像名称。一般为项目名称
2、输入版本号。我比较喜欢写v1,v2,v3…
3、选择操作系统。比如linux/arm64、linux/amd64
4、选择是否推送到阿里云

完整代码

author='donkor'
read -r -p "请输入镜像名称(默认为gindemo): " imgname
#-z字符串为空时
if [[ -z "$imgname" ]]; then
  imgname="${author}/gindemo"
fi
read -r -p "请输入版本号(默认为v1): " imgversion
# -z字符串为空时
if [[ -z "$imgversion" ]]; then
  imgversion="v1"
fi
#可选择的操作系统
#linux/arm64, linux/amd64, linux/amd64/v2, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
printf "请选择操作系统编号(默认使用linux/arm64)\n1.linux/arm64\n2.linux/amd64\n: "
read -r -n 1 buildplatform
if [[ ${buildplatform} -eq 1 ]];then
   buildplatform="linux/arm64"
elif [[ ${buildplatform} -eq 2 ]]; then
  buildplatform="linux/amd64"
else
  buildplatform="linux/arm64"
fi
#删除镜像
rm -f ${imgname}_${imgversion}_${buildplatform:6}.tar
echo "删除本地镜像完成"
#--load 将镜像保存的本地主机
#--push 提交到远程仓库 DockerHub
docker buildx build --platform ${buildplatform} -f Dockerfile  -t ${imgname}:${imgversion} . --load
docker save -o  ${imgname:7}_${imgversion}_${buildplatform:6}.tar ${imgname}:${imgversion}
echo "构建完成"
echo "镜像操作系统:${buildplatform}"
echo "指定镜像名称:${imgname}:${imgversion}"
echo "本地tar名称:${imgname:7}_${imgversion}_${buildplatform:6}.tar"

printf "是否推送到阿里云(默认不推送)\n0.不推送\n1.推送\n: "
read -r -n 1 push_aliyun
if [[ ${push_aliyun} -eq 1 ]];then
   docker login --username=xx --password=yy registry.cn-shenzhen.aliyuncs.com
   docker tag ${imgname}:${imgversion} registry.cn-shenzhen.aliyuncs.com/donkor/aa:${imgversion}
   docker push registry.cn-shenzhen.aliyuncs.com/donkor/aa:${imgversion}
fi

没有太复杂的东西,sh文件也不是通用的,看看注释改一下成为自己的,就可以用了。

九、总结

最近刚更docker文章,docker国内镜像源就关了。不知道该怎么说。文章可能有纰漏。有问题可以私信或者评论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1814476.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【云岚到家】-day02-4-我的账户-实名认证

【云岚到家】-day02-4-我的账户-实名认证 1 我的账户设置-实战1.1 配置OSS1.2 需求分析1.2.1 服务端设置银行账户1.2.2 机构端设置银行账户1.2.3 表结构设计1.2.4 表结构相关的controller、service、mapper、entity 1.3 服务端设置银行账户接口设计1.3.1 新增或更新银行账号信息…

【WWDC 2024 发表会懒人包】iOS 18、iPadOS 18、macOS 15、Apple Intelligence 重点一次看

苹果今天(6/11)发布了全新iOS 18、iPadOS 18、macOS 15、watchOS 11以及visionOS 2,这次的WWDC大会首场发表会久违的快要2 个小时,下面就带大家来看看最新的iOS 18、iPadOS 18、macOS 15、watchOS 11、visionOS 2 特色功能懒人包。…

【FreeRTOS】源码概述

FreeRTOS源码概述 参考《FreeRTOS入门与工程实践(基于DshanMCU-103)》里《第7章 FreeRTOS源码概述》 相关文章:http://t.csdnimg.cn/QK0aO 1 FreeRTOS目录结构 使用 STM32CubeMX 创建的 FreeRTOS 工程中, FreeRTOS 相关的源码如下: 主要设计两个目录 C…

第2章 Rust初体验2/8:变量值绑定:默认不可变增强代码安全性:猜骰子冷热游戏

讲动人的故事,写懂人的代码 2.3.6 变量值绑定:默认不可变增强代码安全性 赵可菲:“那句给 guess 赋值的,没特别写出类型来,看起来Rust是自动帮我们搞定类型判断的吧。” let mut guess = String::new();贾克强:“对啊,Rust会自动帮我们做类型推断(type inference),这…

Linux 基本指令1

ls指令 ls【-选项】【目录或文件】当不指定目录或文件时指令能列出当前目录下所有文件除隐藏文件 选项: -a 列出所有包括隐藏的文件-隐藏文件以.开头。 -d 将目录如文件般显示-一般用ls显示目录是显示其目录中所有文件,加-d则显示目录的信息 -r 以反…

【数据结构】单链表(C语言)

在数据结构和算法中,链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据和指向下一个节点的指针。在C语言中,我们可以使用指针来实现单向链表。下面将详细讲述如何利用C语言实现单向链表。 1.单链表的概念和结构 概…

C++发送邮件的性能如何优化?有哪些方法?

C发送邮件怎么配置SMTP服务器?如何使用C库发信? 在现代应用程序中,电子邮件发送是一个常见的功能。尤其对于需要发送大量邮件的企业级应用,优化邮件发送性能变得尤为重要。AokSend将探讨在使用C发送邮件时,如何通过各…

电脑想加个WIFI功能,怎么选!

在快速发展的物联网和智能家居时代,Wi-Fi模块作为连接各类智能设备与互联网的桥梁,其重要性不言而喻。而为了让这些模块能够适应各式各样的应用场景,不同的接口技术应运而生。今天,我们就来深入浅出地探讨几种常见的Wi-Fi模块接口,包括它们的工作原理、特点以及适用场景,…

Docker以挂载方式安装RocketMQ

Docker 挂载安装RocketMQ Docker 挂载安装RocketMQ安装 Docker安装NameServer1.拉取容器2.创建NameServer容器3.查看容器状态 安装 broker创建 broker.conf 文件启动容器 安装RocketMQ-console构建镜像启动容器开通安全组策略访问控制台 Docker 挂载安装RocketMQ 在 Docker 中…

LangChain入门学习笔记(二)——LangChain表达式语言(LCEL)

基于LangChain框架编写大模型应用的过程就像垒积木,其中的积木就是Prompts,LLMs和各种OutputParser等。如何将这些积木组织起来,除了使用基本Python语法调用对应类的方法,一种更灵活的方法就是使用位于LangChain-Core层中的LCEL&a…

python的四个进度条

哈喽,我是快乐吗喽,今天简单的给大家介绍一下python的四个进度条工具,希望各位喜欢。 第一个进度条工具tqdm,好记点我叫她淘气大妈 安装tqdm库 pip install tqdm 基本用法 from tqdm import tqdm import timefor i in tqdm(ran…

SpringBoot2+Vue3开发课程审核流程系统

SpringBoot2Vue3开发课程审核流程系统 简介 此系统实现了课程审核全流程功能并使用了Activiti7工作流技术,功能包含:课程管理、用户管理、流程定义、课程审核(我的申请、我的代办、我的已办) 功能介绍 课程管理 对课程信息的管…

录音转文字软件:一键让工作学习更高效

在职场这个大舞台上,每一场会议都是关键的演出,而会议记录就是这场演出的剧本。但剧本要整理得好,才能让演出更精彩,不是吗? 把那些长串的会议音频变成清晰的文字记录,听起来就像变魔术一样难。但不用担心…

人工智能强化学习:核心内容、社会影响及未来展望

欢迎来到 Papicatch的博客 文章目录 🐋引言 🐋强化学习的核心内容 🦈强化学习基本概念 🐋强化学习算法 🦈Q学习(Q-Learning) 🦈深度Q网络(Deep Q-Network, DQN&…

AI日报|苹果生态全面整合AI功能,字节跳动被曝秘密启动AI手机研发

文章推荐 粽叶飘香,端午安康!AI视频送祝福啦~ 谁是最会写作文的AI“考生”?“阅卷老师”ChatGPT直呼惊艳! ⭐️搜索“可信AI进展“关注公众号,获取当日最新AI资讯 苹果WWDC 2024:AI为苹果带来了什么&am…

24年系统架构设计师考试真题大放送

哈喽,简单介绍一下,我是研究系统架构设计师/系统分析师考试3 年,累计帮助千人备考系统架构设计师的——凯恩。芝士架构刷题免费!芝士架构 | 软考备考第一站 这周,凯恩抽空把2024年系统架构设计师真题的选择题&#xff…

【qt】视口和窗口坐标

视口和窗口坐标 一.视口和窗口坐标的原理二.视口和窗口坐标的好处三.演示好处四.总结 一.视口和窗口坐标的原理 在绘图事件中进行绘图 void Widget::paintEvent(QPaintEvent *event) {QPainter painter(this);QRect rect(200,0,200,200);painter.drawRect(rect);//设置视口的…

Vue3学习日记(day3)

目录详解: 简单解释: 详细解释: .vscode public assets compents router views app.vue package.json package-lock.json 区别 探究文档 应用配置​ 语法合集 插值表达式​ V- HTML(易造成xss漏洞)​…

2024世界人工智能大会“SAIL奖”发布

作为世界人工智能大会的最高奖项,SAIL 奖(Super AI Leader,卓越人工智能引领者)坚持“追求卓越、引领未来”的理念,评选和运营秉持“高端化、国际化、专业化、市场化、智能化”原则,从全球范围发掘在人工智…

VS2019+QT5.15调用动态库dll带有命名空间

VS2019QT5.15调用动态库dll带有命名空间 vs创建动态库 参考: QT调用vs2019生成的c动态库-CSDN博客 demo的dll头文件: // 下列 ifdef 块是创建使从 DLL 导出更简单的 // 宏的标准方法。此 DLL 中的所有文件都是用命令行上定义的 DLL3_EXPORTS // 符号…