Ansible：像系统管理员一样思考的自动化框架
直到我开始接触 Ansible，我才觉得这才是系统管理员喜欢的东西。
Ansible
直到我开始接触 Ansible，我才觉得这才是系统管理员喜欢的东西。
![](/data/attachment/album/201803/21/224152x1eecp8p87qq676a.jpg)


这些年来，我已经写了许多关于 DevOps 工具的文章，也培训了这方面的人员。尽管这些工具很棒，但很明显，大多数都是按照开发人员的思路设计出来的。这也没有什么问题，因为以编程的方式接近配置管理是重点。不过，直到我开始接触 Ansible，我才觉得这才是系统管理员喜欢的东西。


喜欢的一部分原因是 Ansible 与客户端计算机通信的方式，是通过 SSH 的。作为系统管理员，你们都非常熟悉通过 SSH 连接到计算机，所以从单词“去”的角度来看，相对于其它选择，你更容易理解 Ansible。


考虑到这一点，我打算写一些文章，探讨如何使用 Ansible。这是一个很好的系统，但是当我第一次接触到这个系统的时候，不知道如何开始。这并不是学习曲线陡峭。事实上，问题是在开始使用 Ansible 之前，我并没有太多的东西要学，这才是让人感到困惑的。例如，如果您不必安装客户端程序（Ansible 没有在客户端计算机上安装任何软件），那么您将如何启动？


### 踏出第一步


起初 Ansible 对我来说非常困难的原因在于配置服务器/客户端的关系是非常灵活的，我不知道我该从何入手。事实是，Ansible 并不关心你如何设置 SSH 系统。它会利用你现有的任何配置。需要考虑以下几件事情：


1. Ansible 需要通过 SSH 连接到客户端计算机。
2. 连接后，Ansible 需要提升权限才能配置系统，安装软件包等等。


不幸的是，这两个考虑真的带来了一堆蠕虫。连接到远程计算机并提升权限是一件可怕的事情。当您在远程计算机上安装代理并使用 Chef 或 Puppet 处理特权升级问题时，似乎感觉就没那么可怕了。 Ansible 并非不安全，而是安全的决定权在你手中。


接下来，我将列出一系列潜在的配置，以及每个配置的优缺点。这不是一个详尽的清单，但是你会受到正确的启发，去思考在你自己的环境中什么是理想的配置。也需要注意，我不会提到像 Vagrant 这样的系统，因为尽管 Vagrant 在构建测试和开发的敏捷架构时非常棒，但是和一堆服务器是非常不同的，因此考虑因素是极不相似的。


### 一些 SSH 场景


#### 1）在 Ansible 配置中，root 用户以密码进入远程计算机。


拥有这个想法是一个非常可怕的开始。这个设置的“优点”是它消除了对特权提升的需要，并且远程服务器上不需要其他用户帐户。 但是，这种便利的成本是不值得的。 首先，大多数系统不会让你在不改变默认配置的情况下以 root 身份进行 SSH 登录。默认的配置之所以如此，坦率地说，是因为允许 root 用户远程连接是一个不好的主意。 其次，将 root 密码放在 Ansible 机器上的纯文本配置文件中是不合适的。 真的，我提到了这种可能性，因为这是可以的，但这是应该避免的。 请记住，Ansible 允许你自己配置连接，它可以让你做真正愚蠢的事情。 但是请不要这么做。


#### 2）使用存储在 Ansible 配置中的密码，以普通用户的身份进入远程计算机。


这种情况的一个优点是它不需要太多的客户端配置。 大多数用户默认情况下都可以使用 SSH，因此 Ansible 应该能够使用用户凭据并且能够正常登录。 我个人不喜欢在配置文件中以纯文本形式存储密码，但至少它不是 root 密码。 如果您使用此方法，请务必考虑远程服务器上的权限提升方式。 我知道我还没有谈到权限提升，但是如果你在配置文件中配置了一个密码，这个密码可能会被用来获得 sudo 访问权限。 因此，一旦发生泄露，您不仅已经泄露了远程用户的帐户，还可能泄露整个系统。


#### 3）使用具有空密码的密钥对进行身份验证，以普通用户身份进入远程计算机。


这消除了将密码存储在配置文件中的弊端，至少在登录的过程中消除了。 没有密码的密钥对并不理想，但这是我经常做的事情。 在我的个人内部网络中，我通常使用没有密码的密钥对来自动执行许多事情，如需要身份验证的定时任务。 这不是最安全的选择，因为私钥泄露意味着可以无限制地访问远程用户的帐户，但是相对于在配置文件中存储密码我更喜欢这种方式。


#### 4）使用通过密码保护的密钥对进行身份验证，以普通用户的身份通过 SSH 连接到远程计算机。


这是处理远程访问的一种非常安全的方式，因为它需要两种不同的身份验证因素来解密：私钥和密码。 如果你只是以交互方式运行 Ansible，这可能是理想的设置。 当你运行命令时，Ansible 会提示你输入私钥的密码，然后使用密钥对登录到远程系统。 是的，只需使用标准密码登录并且不用在配置文件中指定密码即可完成，但是如果不管怎样都要在命令行上输入密码，那为什么不在保护层添加密钥对呢？


#### 5）使用密码保护密钥对进行 SSH 连接，但是使用 ssh-agent “解锁”私钥。


这并不能完美地解决无人值守、自动化的 Ansible 命令的问题，但是它确实也使安全设置变得相当方便。 ssh-agent 程序一次验证密码，然后使用该验证进行后续连接。当我使用 Ansible 时，这是我想要做的事情。如果我是完全值得信任的，我通常仍然使用没有密码的密钥对，但是这通常是因为我在我的家庭服务器上工作，是不是容易受到攻击的。


在配置 SSH 环境时还要记住一些其他注意事项。 也许你可以限制 Ansible 用户（通常是你的本地用户），以便它只能从一个特定的 IP 地址登录。 也许您的 Ansible 服务器可以位于不同的子网中，位于强大的防火墙之后，因此其私钥更难以远程访问。 也许 Ansible 服务器本身没有安装 SSH 服务器，所以根本没法访问。 同样，Ansible 的优势之一是它使用 SSH 协议进行通信，而且这是一个你用了多年的协议，你已经把你的系统调整到最适合你的环境了。 我不是宣传“最佳实践”的忠实粉丝，因为实际上最好的做法是考虑你的环境，并选择最适合你情况的设置。


### 权限提升


一旦您的 Ansible 服务器通过 SSH 连接到它的客户端，就需要能够提升特权。 如果你选择了上面的选项 1，那么你已经是 root 了，这是一个有争议的问题。 但是由于没有人选择选项 1（对吧？），您需要考虑客户端计算机上的普通用户如何获得访问权限。 Ansible 支持各种权限提升的系统，但在 Linux 中，最常用的选项是 `sudo` 和 `su`。 和 SSH 一样，有几种情况需要考虑，虽然肯定还有其他选择。


#### 1）使用 su 提升权限。


对于 RedHat/CentOS 用户来说，可能默认是使用 `su` 来获得系统访问权限。 默认情况下，这些系统在安装过程中配置了 root 密码，要想获得特殊访问权限，您需要输入该密码。使用 `su` 的问题在于，虽说它可以给了您完全访问远程系统，而您确实也可以完全访问远程系统。 （是的，这是讽刺。）另外，`su` 程序没有使用密钥对进行身份验证的能力，所以密码必须以交互方式输入或存储在配置文件中。 由于它实际上是 root 密码，因此将其存储在配置文件中听起来像、也确实是一个可怕的想法。


#### 2）使用 sudo 提升权限。


这就是 Debian/Ubuntu 系统的配置方式。 正常用户组中的用户可以使用 `sudo` 命令并使用 root 权限执行该命令。 随之而来的是，这仍然存在密码存储或交互式输入的问题。 由于在配置文件中存储用户的密码看起来不太可怕，我猜这是使用 `su` 的一个进步，但是如果密码被泄露，仍然可以完全访问系统。 （毕竟，输入 `sudo` 和 `su -` 都将允许用户成为 root 用户，就像拥有 root 密码一样。）


#### 3） 使用 sudo 提升权限，并在 sudoers 文件中配置 NOPASSWD。


再次，在我的本地环境中，我就是这么做的。 这并不完美，因为它给予用户帐户无限制的 root 权限，并且不需要任何密码。 但是，当我这样做并且使用没有密码短语的 SSH 密钥对时，我可以让 Ansible 命令更轻松的自动化。 再次提示，虽然这很方便，但这不是一个非常安全的想法。


#### 4）使用 sudo 提升权限，并在特定的可执行文件上配置 NOPASSWD。


这个想法可能是安全性和便利性的最佳折衷。 基本上，如果你知道你打算用 Ansible 做什么，那么你可以为远程用户使用的那些应用程序提供 NOPASSWD 权限。 这可能会让人有些困惑，因为 Ansible 使用 Python 来处理很多事情，但是经过足够的尝试和错误，你应该能够弄清原理。 这是额外的工作，但确实消除了一些明显的安全漏洞。


### 计划实施


一旦你决定如何处理 Ansible 认证和权限提升，就需要设置它。 在熟悉 Ansible 之后，您可能会使用该工具来帮助“引导”新客户端，但首先手动配置客户端非常重要，以便您知道发生了什么事情。 将你熟悉的事情变得自动化比从头开始自动化要好。


我已经写过关于 SSH 密钥对的文章，网上有无数的设置类的文章。 来自 Ansible 服务器的简短版本看起来像这样：



```
# ssh-keygen
# ssh-copy-id -i .ssh/id_dsa.pub remoteuser@remote.computer.ip
# ssh remoteuser@remote.computer.ip

```

如果您在创建密钥对时选择不使用密码，最后一步您应该可以直接进入远程计算机，而不用输入密码或密钥串。


为了在 `sudo` 中设置权限提升，您需要编辑 `sudoers` 文件。 你不应该直接编辑文件，而是使用：



```
# sudo visudo

```

这将打开 `sudoers` 文件并允许您安全地进行更改（保存时会进行错误检查，所以您不会意外地因为输入错误将自己锁住）。 这个文件中有一些例子，所以你应该能够弄清楚如何分配你想要的确切的权限。


一旦配置完成，您应该在使用 Ansible 之前进行手动测试。 尝试 SSH 到远程客户端，然后尝试使用您选择的任何方法提升权限。 一旦你确认配置的方式可以连接，就可以安装 Ansible 了。


### 安装 Ansible


由于 Ansible 程序仅安装在一台计算机上，因此开始并不是一件繁重的工作。 Red Hat/Ubuntu 系统的软件包安装有点不同，但都不是很困难。


在 Red Hat/CentOS 中，首先启用 EPEL 库：



```
sudo yum install epel-release

```

然后安装 Ansible：



```
sudo yum install ansible

```

在 Ubuntu 中，首先启用 Ansible PPA：



```
sudo apt-add-repository spa:ansible/ansible
(press ENTER to access the key and add the repo)

```

然后安装 Ansible：



```
sudo apt-get update
sudo apt-get install ansible

```

### Ansible 主机文件配置


Ansible 系统无法知道您希望它控制哪个客户端，除非您给它一个计算机列表。 该列表非常简单，看起来像这样：



```
# file /etc/ansible/hosts

[webservers]
blogserver ansible_host=192.168.1.5
wikiserver ansible_host=192.168.1.10

[dbservers]
mysql_1 ansible_host=192.168.1.22
pgsql_1 ansible_host=192.168.1.23

```

方括号内的部分是指定的组。 单个主机可以列在多个组中，而 Ansible 可以指向单个主机或组。 这也是配置文件，比如纯文本密码的东西将被存储，如果这是你计划的那种设置。 配置文件中的每一行配置一个主机地址，并且可以在 `ansible_host` 语句之后添加多个声明。 一些有用的选项是：



```
ansible_ssh_pass
ansible_become
ansible_become_method
ansible_become_user
ansible_become_pass

```

### Ansible <ruby> 保险库 <rt>  Vault </rt></ruby>


（LCTT 译注：Vault 作为 ansible 的一项新功能可将例如密码、密钥等敏感数据文件进行加密，而非明文存放）


我也应该注意到，尽管安装程序比较复杂，而且这不是在您首次进入 Ansible 世界时可能会做的事情，但该程序确实提供了一种加密保险库中的密码的方法。 一旦您熟悉 Ansible，并且希望将其投入生产，将这些密码存储在加密的 Ansible 保险库中是非常理想的。 但是本着先学会爬再学会走的精神，我建议首先在非生产环境下使用无密码方法。


### 系统测试


最后，你应该测试你的系统，以确保客户端可以正常连接。 `ping` 测试将确保 Ansible 计算机可以 `ping` 每个主机：



```
ansible -m ping all

```

运行后，如果 `ping` 成功，您应该看到每个定义的主机显示 `ping` 的消息：`pong`。 这实际上并没有测试认证，只是测试网络连接。 试试这个来测试你的认证：



```
ansible -m shell -a 'uptime' webservers

```

您应该可以看到 webservers 组中每个主机的运行时间命令的结果。


在后续文章中，我计划开始深入 Ansible 管理远程计算机的功能。 我将介绍各种模块，以及如何使用 ad-hoc 模式来完成一些按键操作，这些操作在命令行上单独处理都需要很长时间。 如果您没有从上面的示例 Ansible 命令中获得预期的结果，请花些时间确保身份验证可以工作。 如果遇到困难，请查阅 [Ansible 文档](http://docs.ansible.com)获取更多帮助。




---


via: <http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin>


作者：[Shawn Powers](http://www.linuxjournal.com/users/shawn-powers) 译者：[Flowsnow](https://github.com/Flowsnow) 校对：[wxy](https://github.com/wxy)


本文由 [LCTT](https://github.com/LCTT/TranslateProject) 原创编译，[Linux中国](https://linux.cn/) 荣誉推出

