如何使用 Ansible Container 管理 Linux 容器

Ansible Container 解决了 Dockerfile 的缺点,并为容器化项目提供了完整的管理。
434 位读者喜欢这篇文章。
open source button on keyboard

Opensource.com

我热爱容器技术,并且每天都在使用它。即便如此,容器也并非完美无缺。然而,在过去的几个月中,出现了一系列项目,旨在解决我遇到的一些问题。

我开始使用 Docker 容器,因为这个项目使这项技术如此普及。除了使用容器引擎之外,我还学习了如何使用 docker-compose 并开始使用它来管理我的项目。我的生产力突飞猛进!只需一个命令即可运行我的项目,无论它有多么复杂。我非常高兴。

过了一段时间,我开始注意到一些问题。最明显的问题与创建容器镜像的过程有关。Docker 工具使用自定义文件格式作为生成容器镜像的配方——Dockerfile。这种格式很容易学习,在很短的时间内你就可以自己生成容器镜像。一旦你想掌握最佳实践或心中有复杂的场景,问题就出现了。

让我们休息一下,前往另一个领域:Ansible 的世界。你了解它吗?它很棒,对吧?你不了解?好吧,是时候学习一些新东西了。Ansible 是一个项目,允许你通过编写任务并在你选择的环境中执行它们来管理你的基础设施。无需安装和设置任何服务;一切都可以轻松地从你的笔记本电脑上运行。许多人已经接受了 Ansible。

想象一下这种情况:你在 Ansible 上进行了投资,编写了大量 Ansible 角色和剧本,你用它们来管理你的基础设施,并且你正在考虑投资容器。你应该怎么做?开始通过 shell 脚本和 Dockerfile 编写容器镜像定义?这听起来不太对。

Ansible 开发团队的一些人提出了这个问题,并意识到人们编写和日常使用的那些 Ansible 角色和剧本也可以用于生成容器镜像。但不仅如此——它们还可以用于管理容器化项目的完整生命周期。从这些想法中,Ansible Container 项目诞生了。它利用现有的 Ansible 角色,这些角色可以转化为容器镜像,甚至可以用于完整的应用程序生命周期,从构建到生产环境部署。

让我们来谈谈我提到的关于 Dockerfile 上下文中的最佳实践的问题。一个警告:这将非常具体和技术性。以下是我遇到的前三个问题

1. 嵌入在 Dockerfile 中的 Shell 脚本。

在编写 Dockerfile 时,你可以指定一个将通过 /bin/sh -c 解释的脚本。它可以是这样的:

RUN dnf install -y nginx

其中 RUN 是 Dockerfile 指令,其余的是它的参数(传递给 shell)。但是想象一个更复杂的场景

RUN set -eux; \
    \
# this "case" statement is generated via "update.sh"
    %%ARCH-CASE%%; \
    \
    url="https://golang.ac.cn/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \
    wget -O go.tgz "$url"; \
    echo "${goRelSha256} *go.tgz" | sha256sum -c -; \

这个例子取自 官方 golang 镜像。看起来不太漂亮,对吧?

2. 你无法轻松解析 Dockerfile。

Dockerfile 是一种新的格式,没有正式的规范。如果你需要在你的基础设施中处理 Dockerfile(例如,自动化构建过程),这将很棘手。唯一的规范是 代码,它是 dockerd 的一部分。问题是你不能将它用作库。最简单的解决方案是自己编写一个解析器,并寄希望于最好的结果。使用一些众所周知的标记语言,例如 YAML 或 JSON,会不会更好?

3. 难以控制。

如果你熟悉容器镜像的内部结构,你可能知道每个镜像都由层组成。一旦创建了容器,这些层就会像煎饼一样堆叠在一起,使用联合文件系统技术。问题是,你无法显式控制这种分层——你不能说,“这里开始一个新的层。” 你被迫以可能损害可读性的方式更改你的 Dockerfile。更大的问题是,必须遵循一套最佳实践才能获得最佳结果——新手在这里会非常困难。

比较 Ansible 语言和 Dockerfile

与 Ansible 相比,Dockerfile 的最大缺点是 Ansible 作为一种语言,功能更强大得多。例如,Dockerfile 没有变量的直接概念,而 Ansible 却有一个完整的模板系统(变量只是其功能之一)。Ansible 包含大量可以轻松使用的模块,例如 wait_for,它可以用于服务就绪检查——例如,等待服务准备就绪后再继续。使用 Dockerfile,一切都是 shell 脚本。因此,如果你需要弄清楚服务是否就绪,则必须使用 shell(或单独安装)。shell 脚本的另一个问题是,随着复杂性的增加,维护成为一种负担。很多人已经意识到了这一点,并将这些 shell 脚本变成了 Ansible。

如果你对这个主题感兴趣并想了解更多信息,请来布拉格的 开源峰会 观看我在 10 月 23 日星期一下午 4:20 在 Palmovka 房间的 演讲

在 10 月 23 日至 26 日在布拉格举行的 欧洲开源峰会 上,了解更多关于 Tomas Tomecek 的演讲 从 Dockerfile 到 Ansible Container 的信息。

human
工程师。黑客。演讲者。修补匠。红帽人。喜欢容器、Linux、开源、Python 3、Rust、zsh、tmux。

2 条评论

很棒的文章,Tomas!很遗憾布拉格离我现在能负担得起的旅行距离太远了。祝你演讲顺利!

做得好,伙计!布拉格见。

© . All rights reserved.