文章目录
- 1. 写在最前面
- 1.1 问题说明
- 1.2 问题解决
- 1.2.1 次优解
- 1.2.2 中优解
- 1.2.3 最优解
- 1.3 最优解引发的问题
- 2. Buildx 介绍
- 2.1 安装
- 2.2 介绍
- 2.2.1 特点
- 2.2.2 工作原理
- 3. 碎碎念
- 4 参考资料
1. 写在最前面
遇到不懂问题的解决方式大概分为以下两种:
-
正面解决,下次遇见的时候就可以完美绕过
-
反面避开,每次遇到都会被坑一次
注:遇到困难不要慌,如果有临时性方案就先暂时绕过去,然后记录下不懂的地方,待到有时间的时候,抽丝剥茧详细分析一下原因。
1.1 问题说明
需要在 Dockerfile 的步骤中,增加配置 rsyslog 的日志切割规则的步骤。日志切割规则是一个多行的,从美观的角度,以多行的原始配置直接 append 到文件的末尾,为最优解。
1.2 问题解决
1.2.1 次优解
使用一个不是很美观,但是可以解决问题的方式。
RUN echo -e "if \$programname contains \"worker\" then {\n set \$!trimed = \$programname;\n call worker_rules\n}" >> /etc/rsyslog.d/rworker.conf
1.2.2 中优解
使用一个美观,但是表示起来稍显复杂的方式。
RUN echo 'if $programname contains "worker" then {' >> /etc/rsyslog.d/worker.conf && \echo ' set $!trimed = $programname;' >> /etc/rsyslog.d/worker.conf && \echo ' call worker_rules' >> /etc/rsyslog.d/worker.conf && \echo '}' >> /etc/rsyslog.d/worker.conf
1.2.3 最优解
使用 「Here Document」语法,以简洁且明了的方式
RUN cat <<EOF >> /etc/rsyslog.d/worker.conf
if \$programname contains "worker" then {set \$!trimed = \$programname;call worker_rules
}
EOF
注:Here Document 是一种在 Unix/Linux shell 编程中使用的特色语法,用于将多行文本直接嵌入到脚本中。这种语法特别适合于需要将多行字符串传递给命令或程序的场景。
1.3 最优解引发的问题
由于备选方案存在 3 种,但明显从简洁和易维护的角度上,闭眼也要选择「最优解」。但是就是这个最优解,让笔者额外加班了一个晚上。
结论:「传统的 Docker 构建引擎在处理多行字符串时可能会有一些限制,尤其是在 Here Document 语法的解析上。」
解决:「使用 BuildKit,BuildKit 是 Docker 的新构建引擎,它对 Dockerfile 中的许多语法特性提供了更好的支持,包括 Here Document。启用 BuildKit 后,Docker 能够更好地解析和执行复杂的命令。」
2. Buildx 介绍
2.1 安装
如果使用的是 Docker Desktop,则默认包含 Buildx。但如果使用的是 Linux 或更早版本的 Docker 则需要手动安装。
安装步骤:
$ mkdir ~/.docker/cli-plugins
$ wget https://github.com/docker/buildx/releases/download/v0.8.2/buildx-v0.8.2.linux-amd64
$ mv buildx-v0.8.2.linux-amd64 docker-buildx
$ chmod +x ~/.docker/cli-plugins/docker-buildx
注:不要使用 chatgpt 返回的
https://github.com/docker/buildx/releases/latest/download/buildx-$(uname -s)-$(uname -m) -o ~/.docker/cli-plugins/docker-buildx
这种方式,因为这个写法有问题
校验安装成功:
$ docker buildx version
github.com/docker/buildx v0.8.2 6224def4dd2c3d347eee19db595348c50d7cb491
使用 buildx 构建镜像的示例步骤:
docker buildx create --name mybuilder
docker buildx use mybuilder
docker buildx build --platform linux/amd64,linux/arm64 -t my_image:latest .
注:
启用 buildkit export DOCKER_BUILDKIT=1
禁用 export DOCKER_BUILDKIT=0
2.2 介绍
BuildKit 是 Docker 的一个现代构建引擎,它旨在提高 Docker 镜像的构建性能、灵活性和可扩展性。BuildKit 最初作为 Docker 的实验性功能引入,后来成为 Docker 的核心组成部分,支持更复杂的构建场景和优化。
2.2.1 特点
高效的构建缓存:BuildKit 支持更细粒度的缓存机制,能够缓存每个构建步骤的输出,减少重复构建的时间。它可以使用本地缓存和远程缓存(如 Docker Hub 或其他注册表)来加速构建过程。
并行构建:BuildKit 可以并行执行多个构建步骤,充分利用系统资源,加快整体构建速度。这是通过依赖关系分析来实现的,BuildKit 会识别可以独立执行的步骤并同时运行它们。
多平台支持:BuildKit 支持在不同的 CPU 架构和操作系统上构建镜像,如 amd64
、arm64
和 arm
。这使得开发者能够为多种设备(如服务器和嵌入式设备)构建兼容的镜像。
更灵活的 Dockerfile 语法:BuildKit 引入了一些新的语法和指令,例如 RUN --mount
,允许在构建过程中挂载外部文件系统(如缓存、源代码等),从而提高构建的灵活性和可维护性。
输出格式自定义:BuildKit 允许用户自定义构建的输出格式,可以将构建的镜像推送到 Docker Hub 或其他容器注册表,或者导出为 tar 文件等格式。
安全性:BuildKit 提供了更好的安全性,通过构建上下文的隔离和构建步骤的限制,减少了潜在的攻击面。
2.2.2 工作原理
简述工作原理如下:
解析 Dockerfile:BuildKit 首先解析 Dockerfile,分析其中的指令和依赖关系,构建一个有向无环图(DAG),确定构建步骤的执行顺序。
构建上下文:BuildKit 收集构建所需的上下文,包括 Dockerfile、源代码、依赖文件等。
执行构建步骤:根据 DAG 的顺序,BuildKit 并行执行构建步骤。每个步骤的输出会被缓存,以便后续构建可以重用。
生成镜像:最后,BuildKit 将构建的结果打包成 Docker 镜像,并根据用户的配置将其推送到指定的容器注册表。
3. 碎碎念
chatgpt 真的可以让知识的学习和理解更加的快速!
-
无论这个世界对你怎样,都请你一如既往的努力、勇敢、充满希望。
-
当我们努力使自己变得比现在更好地时候, 我们周围的一切也会变得更好。
-
长大之后越来越对年终总结祛魅,逐渐不再被「什么也没做」激起焦虑了。怎么会什么也没做呢,每天从床上爬起来的是你,每天好好吃饱饭的是你,被挫折击溃后艰难地痊愈了的是你,那些大笑的、哭泣的、潸然泪下的微小又动人的时刻,每一个都是你亲自经历的。生活是一条满是痛苦的沟壑,你是如此小心翼翼,才终于平安地站在年关前。
4 参考资料
-
Introducing BuildKit
-
linux - Output of a command within here-document - Stack Overflow
-
使用 buildx 构建多种系统架构支持的 Docker 镜像
-
docker buildx | Docker Docs
-
Buildx · Docker 文档