14 KiB
Ansible:像系统管理员一样思考的自动化框架
这些年来,我已经写了许多关于DevOps工具的文章,也培训了这方面的人员,尽管这些工具很棒,但很明显,大多数都是按照开发人员的思路设计出来的。这也没有什么问题,因为以编程的方式接近配置管理是重点。不过,直到我开始接触Ansible,我才觉得这才是系统管理员喜欢的东西。
喜欢的一部分原因是Ansible与客户端计算机通信的方式,是通过SSH的。作为系统管理员,你们都非常熟悉通过SSH连接到计算机,所以从单词“去”的角度来看,你对Ansible的了解要比其他选择更好。
考虑到这一点,我打算写一些文章,探讨如何使用Ansible。这是一个很好的系统,但是当我第一次接触到这个系统的时候,不知道如何开始。也不是学习曲线陡峭。事实上,问题是在开始使用Ansible之前,我并没有太多的东西要学,这才是让人感到困惑的。例如,如果您不必安装客户端程序(Ansible没有在客户端计算机上安装任何软件),那么您将如何启动?
踏出第一步
起初Ansible对我来说非常困难的原因在于配置服务器/客户端的关系是非常灵活的,我不知道我该从何入手。事实是,Ansible并不关心你如何设置SSH系统。它会利用你现有的任何配置。需要考虑以下几件事情:
- Ansible需要通过SSH连接到客户端计算机。
- 连接后,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 Vault保险库
(译者注:Vault作为 ansible 的一项新功能可将例如passwords,keys等敏感数据文件进行加密,而非明文存放)
我也应该注意到,尽管安装程序比较复杂,而且不是在您首次进入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文档获取更多帮助。
via: http://www.linuxjournal.com/content/ansible-automation-framework-thinks-sysadmin
作者:Shawn Powers 译者:Flowsnow 校对:校对者ID