Ansible,第四部分:整合一切
角色是 Ansible 中最复杂但又最容易学习的方面。
我之前提到过,Ansible 的临时命令模式经常被忽视,仅仅被看作是学习如何使用 Ansible 的一种方式。我非常不同意这种看法。事实上,临时命令模式是我在日常工作中倾向于最常使用的方式。 尽管如此,使用 playbook 和角色是利用 Ansible 功能的非常强大的方法。事实上,当大多数人想到 Ansible 时,他们倾向于想到角色功能,因为这是共享大多数 Ansible 代码的方式。所以首先,重要的是要理解临时命令模式、playbook 和角色之间的关系。
临时命令模式这有点像回顾,但一旦你开始创建 playbook,就很容易忘记。临时命令模式只是一个单行命令,它使用 Ansible 模块在一组计算机上完成给定的任务。例如:
ansible cadlab -b -m yum -a "name=vim state=latest"
将在 cadlab 组中的每台计算机上安装 vim。 -b
表示提升权限(“become” root),-m
表示使用 yum
模块,-a
表示要执行的操作。在本例中,它是安装最新版本的 vim。
通常,当我使用临时命令模式安装软件包时,我会接着执行类似这样的命令:
ansible cadlab -b -m service -a "name=httpd state=started
↪enabled=yes"
这个单行命令将确保 httpd 服务正在运行并设置为在启动时自动启动(后者是 “enabled” 的意思)。就像我一开始说的那样,我在日常工作中最常使用 Ansible 的临时命令模式。 但是,当需要进行新的部署或升级时,创建 playbook 就更有意义了,playbook 是一个包含一堆 Ansible 命令的文本文件。
Playbook 模式我在上一篇文章中描述了 playbook。 它们是 YAML(Yet Another Markup Language)格式的文本文件,其中包含 Ansible 要完成的一系列任务。 例如,要在实验室的一堆计算机上安装 Apache,您需要创建一个类似这样的文件:
---
- hosts: cadlab
tasks:
- name: install apache2 on CentOS
yum: name=httpd state=latest
notify: start httpd
ignore_errors: yes
- name: install apache2 on Ubuntu
apt: update_cache=yes name=apache2 state=latest
notify: start apache2
ignore_errors: yes
handlers:
- name: start httpd
service: name=httpd enable=yes state=started
- name: start apache2
service: name=apache2 enable=yes state=started
请注意,这不是最优雅的 playbook。 它包含一个 play,试图使用 yum 安装 httpd,并使用 apt 安装 apache2。 如果实验室是 CentOS 和 Ubuntu 机器的混合环境,则其中一种安装方法会失败。 这就是为什么每个任务中都有 ignore_errors
命令的原因。 否则,Ansible 在遇到错误时会退出。 再次强调,这种方法有效,但不够美观。 最好创建条件语句,以便在不兼容的平台上能够优雅地退出。 实际上,更复杂、执行更多操作的 playbook 往往会演变成 Ansible 中的 “角色”。
角色实际上并不是一种操作模式。 实际上,角色是 playbook 不可或缺的一部分。 就像 playbook 可以有任务、变量和处理程序一样,它们也可以有角色。 简而言之,角色只是一种组织 playbook 中引用的各种组件的方式。 它从文件夹布局开始:
roles/
webserver/
tasks/
main.yml
handlers/
main.yml
vars/
main.yml
templates/
index.html.j2
httpd.conf.j2
files/
ntp.conf
Ansible 在当前目录中查找 roles 文件夹,也在系统范围的位置(如 /etc/ansible/roles)中查找,因此您可以存储您的角色以保持它们的组织性,并使其远离您的主文件夹。 使用角色的优势在于,您的 playbook 可以像这样简单:
---
- hosts: cadlab
roles:
- webserver
然后, “webserver” 角色将应用于 “cadlab” 组,而无需在 playbook 中键入更多信息。 当指定角色时,Ansible 会在您的 roles 文件夹(在当前目录或系统范围的目录中)中查找与名称 “webserver” 匹配的文件夹。 然后,它将执行 webserver/tasks/main.yml 中的任务。 在该 playbook 中提到的任何处理程序都将在 webserver/handlers/main.yml 中自动搜索。 此外,任何时候通过模板模块或 file/copy 模块引用文件时,都不需要指定路径。 Ansible 会自动在 webserver/files/ 或 /webserver/templates/ 中查找这些文件。
基本上,使用角色将为您节省大量的路径声明和 include 语句。 这可能看起来很简单,但这种组织结构创建了一个标准,不仅可以轻松了解角色所做的事情,还可以轻松地与他人共享您的代码。 如果您始终知道任何文件都必须存储在 roles/rolename/files/ 中,这意味着您可以与他人共享 “角色”,并且他们会确切地知道如何处理它——即,只需将其放入他们自己的 roles 文件夹中并开始使用它。
共享角色:Ansible Galaxy当前 DevOps 工具(如 Chef、Puppet 和 Ansible)的最佳方面之一是,有一个社区的人们愿意分享他们的辛勤工作。 在小范围内,角色是与您的同事分享的好方法,特别是当您有专门为您的环境定制的角色时。 由于许多环境相似,角色可以与更广泛的受众共享——这就是 Ansible Galaxy 发挥作用的地方。
老实说,Ansible 对我的吸引力一部分在于命名约定中的科幻主题。 我知道我在这方面有点傻,但仅仅将某物命名为 Ansible 或 Ansible Galaxy 就引起了我的注意。 这可能是那种 “由书呆子构建,为书呆子服务” 的东西。 我完全可以接受。 如果您访问 Galaxy 网站,您会找到共享角色的在线存储库——而且有很多。
对于仅仅下载和使用其他人的角色,您不需要在 Ansible Galaxy 上拥有任何类型的帐户。 您可以通过访问 Galaxy 并单击页面左侧的 “Browse Roles”(浏览角色)(图 1)在网站上搜索。 目前有超过 13,000 个角色上传到 Ansible Galaxy,所以我强烈建议您利用搜索功能! 在图 2 中,您将看到我搜索了 “apache” 并按 “downloads”(下载次数)排序,以便找到最受欢迎的角色。

图 1. 单击该链接以浏览和搜索角色。

图 2. Jeff Geerling 的角色总是值得一看。
您会发现许多非常流行的标准角色都是由 Jeff Geerling 编写的,他的用户名是 geerlingguy。 他是一位 Ansible 开发人员,至少写过一本我读过的 Ansible 书籍,可能还有其他书籍。 他分享了他的角色,我鼓励您查看它们——不仅是为了使用它们,也是为了了解他是如何解决诸如为给定发行版有条件地选择正确模块之类的问题。 您可以单击角色名称并查看所有涉及的代码。 您可能会注意到,如果您想检查代码,您需要单击 GitHub 链接。 这是 Ansible Galaxy 的天才之举之一——所有角色都存储在用户的 GitHub 页面上,而不是 Ansible Galaxy 服务器上。 由于大多数开发人员将他们的代码保存在 GitHub 上,因此他们无需记住也要上传到 Ansible Galaxy。
顺便说一句,如果您想分享您自己的 Ansible 角色,您需要使用 GitHub 用户名上传它们,因为同样,角色都存储在 GitHub 上。 但这有点超前了; 首先您需要学习如何在您的环境中使用角色。
使用 ansible-galaxy 安装角色当然可以下载整个存储库,然后将内容解压缩到您的 roles 文件夹中。 由于它们只是文本文件和结构化文件夹,因此这样做并没有什么问题。 只是与使用 Ansible 内置的工具相比,它不太方便。
Ansible 命令行上有一个用于搜索 Ansible Galaxy 站点的搜索机制,但为了找到我想使用的角色,我通常会访问该网站找到它,然后使用命令行工具下载并安装它。 这是 Jeff Geerling 的 “apache” 角色的一个示例。 为了使用 Ansible 下载角色,您需要这样做:
sudo ansible-galaxy install geerlingguy.apache
请注意两件事。 首先,您需要以 root 权限执行此命令。 这是因为 ansible-galaxy
命令会将角色安装到您的系统范围的 roles 文件夹中,而该文件夹默认情况下对于您的普通用户帐户是不可写的。 其次,请注意 Ansible Galaxy 上命名的角色的格式。 格式为 username.rolename,因此在本例中为 geerlingguy.apache,这也是您在 playbook 中引用角色的方式。
如果您想查看以正确格式列出的角色,可以使用 ansible-galaxy
的搜索命令,但就像我说的那样,我发现它不太有用,因为它不按受欢迎程度排序。 事实上,我根本弄不清楚它是按什么排序的。 我唯一使用命令行搜索功能的时候是当我也使用 grep
按单个人员缩小角色范围时。 无论如何,图 3 显示了 ansible-galaxy
搜索结果的外观。 请注意 username.rolename 格式。

图 3. 我喜欢命令行,但这些搜索结果令人沮丧。
一旦您安装了角色,它就可以立即在您自己的 playbook 中使用,因为它已安装在系统范围的 roles 文件夹中。 在我的情况下,那是 /etc/ansible/roles(图 4)。 所以现在,如果我创建一个像这样的 playbook:
---
- hosts: cadlab
roles:
- geerlingguy.apache
Apache 将安装在我所有的 cadlab 计算机上,无论它们使用的是什么发行版。 如果您想了解角色(它只是一堆任务、处理程序等等)是如何工作的,只需浏览 /etc/ansible/roles/geerlingguy.apache/ 内的文件夹结构即可。 所有内容都在那里供您使用或修改。

图 4. 小菜一碟
创建您自己的角色这里真的没有什么神奇之处,因为您可以轻松地创建一个 roles 文件夹,然后在其中手动创建您自己的角色,但是 ansible-galaxy
通过为您创建一个骨架角色来提供一个快捷方式。 确保您有一个 roles 文件夹,然后只需键入:
ansible-galaxy init roles/rolename
您将获得一个为您的新角色精心创建的文件夹结构。 它没有做任何神奇的事情,但作为以前拼错 “Templates” 的人,我可以告诉您,如果您像我一样手指笨拙,它将为您节省很多挫败感。
分享您的角色如果您到了想在 Ansible Galaxy 上分享您的角色的地步,这很容易做到。 确保您的角色在 GitHub 上(使用 git 超出了本文的范围,但无论如何,使用 git 和 GitHub 是跟踪您的代码的好方法)。 一旦您的角色在 GitHub 上,您就可以使用 ansible-galaxy
将它们 “导入” 到可公开搜索的 Ansible Galaxy 站点。 您首先需要进行身份验证:
ansible-galaxy login
在您尝试使用命令行工具登录之前,请确保您已访问 Ansible Galaxy 网站并使用您的 GitHub 帐户登录。 您可以在图 5 中看到,起初我无法登录。 然后我在网站上登录,之后,我能够使用命令行工具成功登录。

图 5. 试图弄清楚为什么我无法进行身份验证让我很恼火。
登录后,您可以通过键入以下内容来添加您的角色:
ansible-galaxy import githubusername githubreponame
该过程需要一段时间,因此如果您愿意,可以添加 -no-wait
选项,角色将在后台导入。 我真的不建议您这样做,除非您已经创建了值得分享的角色。 请记住,Ansible Galaxy 上有超过 13,000 个角色,因此正在发生许多 “重复造轮子” 的事情。
嗯,我写了四篇文章,但我认为如果您一直在关注,您应该已经到了可以从这里开始的程度。 Playbook 和角色通常是人们在 Ansible 中关注的重点,但我也鼓励您利用临时命令模式进行日常维护任务。 在某些方面,Ansible 只是另一种 DevOps 配置管理工具,但对我而言,它感觉最像我几十年来使用 Bash 脚本完成的传统问题解决方案。 也许我只是喜欢 Ansible,因为它和我的思维方式相同。 无论您的动机如何,我都鼓励您充分学习 Ansible,以便您可以确定它是否像适合我的工作流程一样适合您的工作流程。
资源以下是 Shawn Powers 本系列前三篇文章的链接