Docker使用buildx来取代传统build并同时构建多架构镜像

简介

Docker更新了build流程,提供了全新的构建工具,原先的docker build命令已经被标记为@deprecated啦!是时候学习新的buildx工具,开始装逼啦努力追上时代啦~

1
2
# sudo pacman -S docker-buildx
sudo docker buildx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Usage:  docker buildx [OPTIONS] COMMAND

Extended build capabilities with BuildKit

Options:
--builder string Override the configured builder instance

Management Commands:
imagetools Commands to work on images in registry

Commands:
bake Build from a file
build Start a build
create Create a new builder instance
du Disk usage
inspect Inspect current builder instance
ls List builder instances
prune Remove build cache
rm Remove a builder instance
stop Stop builder instance
use Set the current builder instance
version Show buildx version information

Run 'docker buildx COMMAND --help' for more information on a command.

使用方法

其实吧,和普通的build相比,没啥区别,但是多了好多集成化的功能,请看示例:

1
2
3
4
5
sudo docker buildx build \
--platform $PLATFORM \
-t "$IMAGE:$TAG" \
-t "$IMAGE:latest" \
--pull --push .

可以看到,pull(始终拉取新镜像,指FROM里的内容),push(自动build后push),platform(新增多架构构建),还是有着节省行数的好处的(

另外,x86的机器上也可以直接构建arm镜像啦,这里使用树莓派常用的arm64(也就是aarch64)举例,首先我们要建立一个buildx环境:

1
2
3
4
5
sudo docker buildx create \
--name multi_platform \
--use --platform \
linux/amd64,linux/arm64 \
--driver docker-container

然后用ls命令即可看到这个环境支持的架构:

1
sudo docker buildx ls
1
2
3
4
5
NAME/NODE         DRIVER/ENDPOINT             STATUS  BUILDKIT             PLATFORMS
multi_platform * docker-container
multi_platform0 unix:///var/run/docker.sock running v0.12.5 linux/amd64*, linux/arm64*, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386
default docker
default default running v0.11.7+d3e6c1360f6e linux/amd64, linux/amd64/v2, linux/amd64/v3, linux/amd64/v4, linux/386

可以看到,后面有些奇怪的东西,x86怎么还有v2、v3、v4,这激发了我的好奇心,搜索发现,其实是指令集更新的区别,这里Golang给的最直观:

来自:https://go.dev/wiki/MinimumRequirements

1
2
3
4
GOAMD64=v1 (default): The baseline. Exclusively generates instructions that all 64-bit x86 processors can execute.
GOAMD64=v2: all v1 instructions, plus CMPXCHG16B, LAHF, SAHF, POPCNT, SSE3, SSE4.1, SSE4.2, SSSE3.
GOAMD64=v3: all v2 instructions, plus AVX, AVX2, BMI1, BMI2, F16C, FMA, LZCNT, MOVBE, OSXSAVE.
GOAMD64=v4: all v3 instructions, plus AVX512F, AVX512BW, AVX512CD, AVX512DQ, AVX512VL.

检测

关于自己的发行版目前支持的指令集,可以用以下命令查看:

1
/lib/ld-linux-x86-64.so.2 --help | grep "x86-64-v"
1
2
3
x86-64-v4 (supported, searched)
x86-64-v3 (supported, searched)
x86-64-v2 (supported, searched)

还有不少人(Gentoo狂热者?)把自己电脑里所有程序都改成v4构建的,以提高性能,Ubuntu文档里就有这样说:

https://cn.ubuntu.com/blog/optimising-ubuntu-performance-on-amd64-architecture_cn

还有Arch系的大佬介绍:

https://blog.chyk.ink/2022/08/11/arch-linux-upgrade-to-x86-64-v3-microarchitecture/

视频演示

B站:https://www.bilibili.com/video/BV14A4m1V7zT/

要拒绝眼高手低

Make your hands dirty!

尝试去慢慢做一些practical的事情,会让你减轻许多焦虑感,掌握一技在手,安全感也就自然而然。

其实我比较羡慕厨师这个行业,一技在手,别人都会夸你“烧得一手好菜”。但是厨子和外界的联系太多了,袁枚有言“凡物各有先天,物性不良,虽易牙烹之,亦无味也”,厨子需要外界提供上好的食材,需要屠夫和菜农,但他们在现代标准化的流程中丧失了其风味,连带影响了上游的创造者,限制了其发挥。

但是计算机是一个从无到有的世界,是构筑在现代数学之上的理想国。普通家庭花3000块买个电脑,带来的创造性不会比九万八的苹果电脑更低,这其中人的主观能动性更为重要,这也是张雪峰所说“计算机是穷人家孩子的首选”之由来,相对而言,投入的本金很少,产出很高,也即性价比很高。

喜欢计算机,作为技术人,编程是充满乐趣的创造性工作(此处的工作不是认真工作中的工作,而是诸事自己掌控,脑力的结晶),看着自己写的代码一个个work起来,心中的喜悦是溢于言表的,要记住这种感觉,时常体会,才能让自己不至于陷于迷茫。

有些同学质疑项目越来越壮大之后,个人的掌控力会渐渐不足,毕竟软件开发工作是复杂的,虽然我们在极力用各种工程实践让一切变得有序可控,但它依然是依赖个人能力的一种创造性活动。这时候就需要一个舵手作为领导者来把控方向,作为领导者,我认为也不能带着白手套,而是积极参与,深入实践。这样才能最大程度的避免外行指导内行,要跟随最新的技术趋势,保持自己的核心竞争力。

愿不忘初心。

现存项目里加人是一场豪赌

带语气视频版:https://www.bilibili.com/video/BV1ut421a7r1/

副标题:谈软工圣经《人月神话》

我的专业是软件工程,顾名思义,软件和土木之类的相似,也是一个系统性的工程,系统就不免牵扯到人、机、料、法、环的方方面面,其中占据主导因素的就是参与项目的人。

软件工程,研究的便是如何将「软件项目」以标准化「工程项目」的方式去运作,即,尽量剥离掉人的主观能动性,发挥哪里需要哪里搬的“螺丝钉”作用。而不是像现在众多开源兴趣项目那样,以个人开发者的身份掌管一切、运作一切,一旦原作者弃坑,那么项目即宣告死刑,像ReiserFS作者,进监狱之后,Linux内核就把它标记为了Deprecated,无人问津。

但是任何人都不是等同的,作为“螺丝钉”也会有不同的型号,这里先不谈作为个体的独特个性,仅仅是为了能够有效的协作,身处同一个项目的“螺丝钉”们就需要不断地交流来对抗信息差,也即同步信息

以下常见的协作问题很容易遇到:

  1. 大家对项目最终愿景的理解不同(不明白设计初衷/不了解最终客户需求)
  2. 同一职能的人们水平不同(项目中老带新非常常见/某些新技术只有少数人理解)
  3. 分工角色和责任不明确(同一问题可以从不同方面解决/团队中某小团体更为强势)

对于一些小项目可能无关痛痒,十人以内还属于可以有效对齐的规模,依靠定期的会议沟通,即可同步所有人。但一旦超出规模,还按照原先的方式沟通,项目就可能会脱离控制,因为人与人之间的沟通是全连接型的,这时候人们往往会按职能来拆分小团体解决,比如前端团队、后端团队、运维团队、测试团队,本质上还是各个团队的领头人,即leader,承担了原先的职能作用。

设想一下,这样的项目团队,在正常的开发迭代周期内,现在接到了加快推进项目的任务,领导决定派遣更多人手来支援、分担项目任务,新加入项目的人可以直接上手干吗?

很明显不太可能,新人至少需要知道项目需求,阅读项目开始至今的开发文档、会议记录,再和项目组已有的成员沟通细节,才能尽可能地无缝加入项目进程。

而加入一个人,则意味着团队原先的N人,都新增了N条沟通链路,再加一个人,就又是N+1条链路,人越多只会越乱,最终大家在沟通同步上浪费越来越多的时间,导致项目虽然看上去增加了人手,但效率只会越来越低。

有没有一种解决方法呢?我认为有,因为问题的本质出在全连接沟通上,假如有这么一个人,他和所有人交流,并且把所有人的信息都同步到和他一致,那全连接的n²级别链路就简化为了n级别,这个人就是项目经理,所以项目经理这样一个角色,职责非常重要,他是项目不至于陷入混乱的前提和保证。

项目经理就有点类似BGP组网中的路由反射器RR,常规的IBGP节点之间都需要建立全连接关系,有了路由反射器之后,反射器可以作为中间节点汇聚所有路由信息,然后同步给其他IBGP节点,这样节省了节点之间的巨量连线和处理路由信息的额外负载。

https://www.sdnlab.com/20294.html

原图链接:https://img1.sdnlab.com/wp-content/uploads/2017/11/EBGP-IBGP-fig-6.png

当然《人月神话》作为软件工程的圣经,肯定不止告诉了我们这些,后续我看看结合现实再写一篇心得体会,好书值得慢慢回味~