了解如何使用 Ansible 在容器中执行命令。容器和 Ansible 可以很好地融合在一起：从管理和编排到供应和构建。在本文中，我们将重点介绍构建部分。如果你熟悉 Ansible，就会知道你可以编写一系列任务，ansible-playbook 命令将为你执行这些任务。你知道吗，如果你编写 Dockerfile 并运行 podman build，你还可以在容器环境中执行此类命令，并获得相同​​的结果。这是一个例子：- name: Serve our file using httpd hosts: all tasks: - name: Install httpd package: name: httpd state: installed - name: Copy our file to httpd’s webroot copy: src: our-file.txt dest: /var/www/html/你可以在 Web 服务器本地或容器中执行这个剧本，并且只要你记得先创建 our-file.txt，它就可以工作。但是这里缺少了一些东西。你需要启动（并配置）httpd 以便提供文件。这是容器构建和基础架构供应之间的区别：构建镜像时，你只需准备内容；而运行容器是另一项任务。另一方面，你可以将元数据附加到容器镜像，它会默认运行命令。这有个工具可以帮助。试试看 ansible-bender 怎么样？$ ansible-bender build the-playbook.yaml fedora:30 our-httpd该脚本使用 ansible-bender 对 Fedora 30 容器镜像执行该剧本，并将生成的容器镜像命名为 our-httpd。但是，当你运行该容器时，它不会启动 httpd，因为它不知道如何操作。你可以通过向该剧本添加一些元数据来解决此问题：- name: Serve our file using httpd hosts: all vars: ansible_bender: base_image: fedora:30 target_image: name: our-httpd cmd: httpd -DFOREGROUND tasks: - name: Install httpd package: name: httpd state: installed - name: Listen on all network interfaces. lineinfile: path: /etc/httpd/conf/httpd.conf regexp: '^Listen ' line: Listen 0.0.0.0:80 - name: Copy our file to httpd’s webroot copy: src: our-file.txt dest: /var/www/html现在你可以构建镜像（从这里开始，请以 root 用户身份运行所有命令。目前，Buildah 和 Podman 不会为无 root 容器创建专用网络）：# ansible-bender build the-playbook.yaml PLAY [Serve our file using httpd] **************************************************** TASK [Gathering Facts] *************************************************************** ok: [our-httpd-20191004-131941266141-cont] TASK [Install httpd] ***************************************************************** loaded from cache: 'f053578ed2d47581307e9ba3f64f4b4da945579a082c6f99bd797635e62befd0' skipping: [our-httpd-20191004-131941266141-cont] TASK [Listen on all network interfaces.] ********************************************* changed: [our-httpd-20191004-131941266141-cont] TASK [Copy our file to httpd’s webroot] ********************************************** changed: [our-httpd-20191004-131941266141-cont] PLAY RECAP *************************************************************************** our-httpd-20191004-131941266141-cont : ok=3 changed=2 unreachable=0 failed=0 skipped=1 rescued=0 ignored=0 Getting image source signatures Copying blob sha256:4650c04b851c62897e9c02c6041a0e3127f8253fafa3a09642552a8e77c044c8 Copying blob sha256:87b740bba596291af8e9d6d91e30a01d5eba9dd815b55895b8705a2acc3a825e Copying blob sha256:82c21252bd87532e93e77498e3767ac2617aa9e578e32e4de09e87156b9189a0 Copying config sha256:44c6dc6dda1afe28892400c825de1c987c4641fd44fa5919a44cf0a94f58949f Writing manifest to image destination Storing signatures 44c6dc6dda1afe28892400c825de1c987c4641fd44fa5919a44cf0a94f58949f Image 'our-httpd' was built successfully \o/镜像构建完毕，可以运行容器了：# podman run our-httpd AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.88.2.106. Set the 'ServerName' directive globally to suppress this message是否提供文件了？首先，找出你容器的 IP：# podman inspect -f '{{ .NetworkSettings.IPAddress }}' 7418570ba5a0 10.88.2.106你现在可以检查了：$ curl http://10.88.2.106/our-file.txt Ansible is ❤你文件内容是什么？这只是使用 Ansible 构建容器镜像的介绍。如果你想了解有关 ansible-bender 可以做什么的更多信息，请查看它的 GitHub 页面。构建快乐！via: https://opensource.com/article/19/10/building-container-images-ansible作者：Tomas Tomecek 选题：lujun9972 译者：geekpi 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出
Ansible Container 解决了 Dockerfile 的不足，并对容器化项目提供了完整的管理。Image by : opensource.com我喜欢容器，并且每天都使用这个技术。即便如此，容器并不完美。不过，在过去几个月里，一系列项目已经解决了我遇到的一些问题。我刚开始时，用 Docker 使用容器，这个项目使得这种技术非常流行。除了使用这个容器引擎之外，我学到了怎么去使用 docker-compose 以及怎么去用它管理我的项目。使用它使得我的生产力猛增！一个命令就可以运行我的项目，而不管它有多复杂。因此，我太高兴了。使用一段时间之后，我发现了一些问题。最明显的问题是创建容器镜像的过程。Docker 工具使用一个定制的文件格式作为生成容器镜像的依据：Dockerfile。这个格式易于学习，并且很短的一段时间之后，你就可以自己制作容器镜像了。但是，一旦你希望进一步掌握它或者考虑到复杂场景，问题就会出现。让我们打断一下，先去了解一个不同的东西：Ansible 的世界。你知道它吗？它棒极了，是吗？你不这么认为？好吧，是时候去学习一些新事物了。Ansible 是一个允许你通过写一些任务去管理你的基础设施，并在你选择的环境中运行它们的项目。不需要去安装和设置任何的服务；你可以从你的笔记本电脑中很容易地做任何事情。许多人已经接受 Ansible 了。想像一下这样的场景：你在 Ansible 中，你写了很多的 Ansible 角色 role 和 剧本 playbook ，你可以用它们去管理你的基础设施，并且你想把它们运用到容器中。你应该怎么做？通过 shell 脚本和 Dockerfile 去写容器镜像定义？听起来好像不对。来自 Ansible 开发团队的一些人问到这个问题，并且他们意识到，人们每天编写和使用的那些同样的 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.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \ wget -O go.tgz "$url"; \ echo "${goRelSha256} *go.tgz" | sha256sum -c -; \ 这仅是从 golang 官方镜像 中拿来的一段。它看起来并不好看，是不是？2、 解析 Dockerfile 并不容易Dockerfile 是一个没有正式规范的新格式。如果你需要在你的基础设施（比如，让构建过程自动化一点）中去处理 Dockerfile 将会很复杂。仅有的规范是 这个代码，它是 dockerd 的一部分。问题是你不能使用它作为一个 库 library 来使用。最容易的解决方案是你自己写一个解析器，然后祈祷它运行的很好。使用一些众所周知的标记语言不是更好吗？比如，YAML 或者 JSON。3、 管理困难如果你熟悉容器镜像的内部结构，你可能知道每个镜像是由 层 layer 构成的。一旦容器被创建，这些层就使用联合文件系统技术堆叠在一起（像煎饼一样）。问题是，你并不能显式地管理这些层 — 你不能说，“这儿开始一个新层”，你被迫使用一种可读性不好的方法去改变你的 Dockerfile。最大的问题是，必须遵循一套最佳实践以去达到最优结果 — 新来的人在这个地方可能很困难。Ansible 语言和 Dockerfile 比较相比 Ansible，Dockerfile 的最大缺点，也是 Ansible 的优点，作为一个语言，Ansible 更强大。例如，Dockerfile 没有直接的变量概念，而 Ansible 有一个完整的模板系统（变量只是它其中的一个特性）。Ansible 包含了很多更易于使用的模块，比如，wait\_for，它可以被用于服务就绪检查，比如，在处理之前等待服务准备就绪。在 Dockerfile 中，做任何事情都通过一个 shell 脚本。因此，如果你想去找出已准备好的服务，它必须使用 shell（或者独立安装）去做。使用 shell 脚本的其它问题是，它会变得很复杂，维护成为一种负担。很多人已经发现了这个问题，并将这些 shell 脚本转到 Ansible。关于作者Tomas Tomecek - 工程师、Hacker、演讲者、Tinker、Red Hatter。喜欢容器、linux、开源软件、python 3、rust、zsh、tmux。More about mevia: https://opensource.com/article/17/10/dockerfiles-ansible-container作者：Tomas Tomecek 译者：qhwdw 校对：wxy本文由 LCTT 原创编译，Linux中国 荣誉推出