您现在可以使用常规 Dockerfile 在 werf 中构建 Docker 镜像

迟到总比不到好。 或者我们几乎犯了一个严重的错误,因为不支持常规 Dockerfile 来构建应用程序映像。

您现在可以使用常规 Dockerfile 在 werf 中构建 Docker 镜像

我们将讨论 韦尔夫 — GitOps 实用程序,可与任何 CI/CD 系统集成并提供整个应用程序生命周期的管理,从而允许:

  • 收集并发布图像,
  • 在 Kubernetes 中部署应用程序,
  • 使用特殊策略删除未使用的图像。


该项目的理念是将低级工具收集到一个统一的系统中,使 DevOps 工程师能够控制应用程序。 如果可能,应使用现有实用程序(例如 Helm 和 Docker)。 如果问题无法解决,我们可以为此创造并支持一切必要的东西。

背景:您自己的图像收集器

这就是 werf 中图像收集器发生的情况:通常的 Dockerfile 对我们来说不够。 如果你快速浏览一下该项目的历史,就会发现这个问题已经出现在 werf 的第一个版本中(然后仍然存在) 称为 dapp).

在创建用于将应用程序构建到 Docker 映像中的工具时,我们很快意识到 Dockerfile 不适合我们执行一些非常具体的任务:

  1. 需要按照以下标准方案构建典型的小型Web应用:
    • 安装系统范围的应用程序依赖项,
    • 安装一组应用程序依赖库,
    • 收集资产,
    • 最重要的是,快速高效地更新镜像中的代码。
  2. 当对项目文件进行更改时,构建者必须通过对更改的文件应用补丁来快速创建新层。
  3. 如果某些文件发生了变化,那么就需要重建相应的依赖阶段。

今天,我们的收藏家还有许多其他的可能性,但这些都是最初的愿望和冲动。

一般来说,我们不假思索地用我们所使用的编程语言武装自己 (见下文) 并踏上实施之路 自己的DSL! 根据目标,旨在分阶段描述组装过程并确定这些阶段对文件的依赖性。 并对其进行了补充 自己的收藏家,这将DSL变成了最终目标——组装图像。 起初 DSL 是用 Ruby 编写的,但随着 过渡到 Golang — 我们的收集器的配置开始在 YAML 文件中描述。

您现在可以使用常规 Dockerfile 在 werf 中构建 Docker 镜像
Ruby 中 dapp 的旧配置

您现在可以使用常规 Dockerfile 在 werf 中构建 Docker 镜像
YAML 上 werf 的当前配置

随着时间的推移,收集器的机制也发生了变化。 首先,我们只是根据配置动态生成一个临时 Dockerfile,然后开始在临时容器中运行汇编指令并提交。

NB:目前,我们的收集器使用自己的配置(在 YAML 中),称为 Stapel 收集器,已经发展成为一个相当强大的工具。 其详细描述值得单独撰写文章,基本细节可以在 文件资料.

对问题的认识

但我们并没有立即意识到我们犯了一个错误:我们没有添加这种能力 通过标准 Dockerfile 构建镜像 并将它们集成到相同的端到端应用程序管理基础设施中(即收集图像、部署和清理它们)。 怎么可能制作一个在 Kubernetes 中部署的工具而不实现 Dockerfile 支持,即描述大多数项目图像的标准方法?...

我们不回答这个问题,而是提供一个解决方案。 如果您已经有一个 Dockerfile(或一组 Dockerfile)并且想要使用 werf,该怎么办?

NB:顺便问一下,你为什么要使用 werf? 主要特点如下:

  • 完整的应用程序管理周期,包括图像清理;
  • 能够通过单个配置同时管理多个图像的组合;
  • 改进了 Helm 兼容图表的部署流程。

更完整的列表可以在以下位置找到: 项目页面.

因此,如果早些时候我们愿意在配置中重写 Dockerfile,那么现在我们会很高兴地说:“让 werf 构建您的 Dockerfile!”

如何使用?

该功能的完整实现出现在发行版中 werf v1.0.3-beta.1。 总体原理很简单:用户在werf配置中指定现有Dockerfile的路径,然后运行命令 werf build...就是这样 - werf 将组装图像。 让我们看一个抽象的例子。

让我们宣布下一篇 Dockerfile 在项目根目录中:

FROM ubuntu:18.04
RUN echo Building ...

我们将宣布 werf.yaml它使用这个 Dockerfile:

configVersion: 1
project: dockerfile-example
---
image: ~
dockerfile: ./Dockerfile

全部! 左边 运行 werf build:

您现在可以使用常规 Dockerfile 在 werf 中构建 Docker 镜像

此外,您还可以声明以下内容 werf.yaml 一次从不同的 Dockerfile 构建多个镜像:

configVersion: 1
project: dockerfile-example
---
image: backend
dockerfile: ./dockerfiles/Dockerfile-backend
---
image: frontend
dockerfile: ./dockerfiles/Dockerfile-frontend

最后,它还支持传递额外的构建参数,例如 --build-arg и --add-host - 通过werf配置。 Dockerfile 映像配置的完整描述可在以下位置找到: 文档页面.

它是如何工作的呢?

在构建过程中,Docker 中本地层的标准缓存发挥作用。 然而,重要的是 werf 也 将 Dockerfile 配置集成到其基础设施中。 这是什么意思?

  1. 从 Dockerfile 构建的每个映像都包含一个称为 dockerfile (您可以阅读更多有关 werf 中的阶段的信息 这里).
  2. 舞台用 dockerfile werf 计算取决于 Dockerfile 配置内容的签名。 当 Dockerfile 配置更改时,阶段签名会更改 dockerfile werf 使用新的 Dockerfile 配置启动此阶段的重建。 如果签名没有改变,则werf从缓存中获取图像 (有关在 werf 中使用签名的更多详细信息,请参见 这份报告).
  3. 接下来,可以使用命令发布收集到的图像 werf publishwerf build-and-publish)并使用它来部署到 Kubernetes。 发布到 Docker 注册表的镜像将使用标准 werf 清理工具进行清理,即旧镜像(超过 N 天)、与不存在的 Git 分支关联的镜像以及其他策略将被自动清理。

有关此处描述的要点的更多详细信息可以在文档中找到:

注意事项及注意事项

1.ADD不支持外部URL

目前不支持在指令中使用外部 URL ADD。 当指定 URL 处的资源发生更改时,Werf 不会启动重建。 我们计划很快添加此功能。

2. 无法将.git添加到镜像中

一般来说,添加一个目录 .git 在图像中 - 这是一种恶毒的不良做法,原因如下:

  1. 如果 .git 保留在最终图像中,这违反了原则 12 因素应用程序:由于最终图像必须链接到单个提交,因此不可能这样做 git checkout 任意提交。
  2. .git 增加图像的大小(存储库可能会很大,因为大文件曾经被添加到其中然后被删除)。 仅与特定提交关联的工作树的大小不依赖于 Git 中的操作历史记录。 在这种情况下,添加和随后的删除 .git 从最终的镜像中将无法工作:镜像仍然会获得一个额外的层——这就是 Docker 的工作原理。
  3. Docker 可以启动不必要的重建,即使正在构建相同的提交,但来自不同的工作树。 例如,GitLab 在以下位置创建单独的克隆目录 /home/gitlab-runner/builds/HASH/[0-N]/yourproject 当启用并行组装时。 额外的重组将是由于目录 .git 即使构建了相同的提交,同一存储库的不同克隆版本也是不同的。

最后一点在使用 werf 时也会产生影响。 Werf 要求在运行某些命令时(例如 werf deploy)。 当这些命令运行时,werf 计算指定图像的阶段签名 werf.yaml,并且它们必须位于程序集缓存中 - 否则该命令将无法继续工作。 如果舞台签名取决于内容 .git,然后我们得到一个对不相关文件的更改不稳定的缓存,并且 werf 将无法原谅这种疏忽(有关更多详细信息,请参阅 文件资料).

在一般情况下, 仅添加某些必要的文件 通过说明 ADD 在任何情况下都会提高书面的效率和可靠性 Dockerfile,并且还提高了为此收集的缓存的稳定性 Dockerfile,到 Git 中不相关的更改。

我们为特定需求编写自己的构建器的最初路径是艰难、诚实和直接的:我们没有在标准 Dockerfile 之上使用拐杖,而是使用自定义语法编写了我们的解决方案。 这有它的优点:Stapel 收集器完美地完成了它的任务。

然而,在编写我们自己的构建器的过程中,我们忽略了对现有 Dockerfile 的支持。 这个缺陷现已修复,将来我们计划开发 Dockerfile 支持以及我们的自定义 Stapel 构建器,用于分布式组装和使用 Kubernetes 进行组装(即在 Kubernetes 内的运行器上进行组装,如 kaniko 中所做的那样)。

所以,如果你突然有几个 Dockerfile ...... 尝试 韦尔夫!

PS 有关该主题的文档列表

另请阅读我们的博客:“werf - 我们在 Kubernetes 中的 CI / CD 工具(概述和视频报告)“。

来源: habr.com

添加评论