在 Ansible 系列的第一部分,您熟悉了 Ansible 并学会了安装它。
在本教程中,您将学习如何在 Ansible 中管理静态清单。 您还将了解各种 Ansible 配置设置。
此外,您将探索几个 Ansible 模块,并开始运行 Ansible Ad-Hoc 命令。
在您看到这一切之前,我要感谢所有 LHB Pro 成员。 在他们的支持下,这个 Ansible 系列是可能的。 如果您还不是专业会员,请考虑选择订阅。
创建 Ansible 用户
即使您可以在 Ansible 中使用 root 用户来运行 Ad-Hoc 命令和 playbook,但绝对不建议这样做并且不被视为最佳实践,因为允许 root 用户 ssh 访问可能会带来安全风险。
因此,建议您创建一个专用的 Ansible 用户 sudo 所有主机(控制和托管主机)上的权限(对所有命令)。
请记住,Ansible 使用 SSH 和 Python 在幕后完成所有繁琐的工作,因此以下是安装 Ansible 后必须遵循的四个步骤:
- 在所有主机上创建一个新用户。
- 授予 sudo 新用户在所有节点上的权限。
- 在控制节点上为新用户生成 SSH 密钥。
- 将 SSH 公钥复制到受管节点。
所以,事不宜迟,让我们从创建一个名为的新用户开始 艾略特 在所有主机上:
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
[[email protected] ~]# useradd -m elliot
设置后 艾略特的 所有主机上的密码,您可以转到第 2 步; 你可以授予 艾略特 sudo 通过将以下条目添加到无密码的所有命令的权限 /etc/sudoers 文件:
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
[[email protected] ~]# echo "elliot ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
现在,以用户身份登录 艾略特 在您的控制节点上并生成一个 ssh 密钥对:
[[email protected] ~]$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/elliot/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/elliot/.ssh/id_rsa.
Your public key has been saved in /home/elliot/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Xf5bKx0kkBCsCQ/7rc6Kv6CxCRTH2XJajbNvpzel+Ik [email protected]
The key's randomart image is:
+---[RSA 3072]----+
| .oo . |
| . ooo . o |
| . = *=.o o |
| o =.o+ . o . . |
| . . .. S . . o |
|. .. . . . . |
|.. . oo.o o o|
|. = o oo++. . +.|
| + ..++Eoo. o. |
+----[SHA256]-----+
最后,你可以复制 艾略特的 所有托管主机的公共 ssh 密钥,使用 ssh-copy-id 命令如下:
[[email protected] ~]$ ssh-copy-id node1
[[email protected] ~]$ ssh-copy-id node2
[[email protected] ~]$ ssh-copy-id node3
[[email protected] ~]$ ssh-copy-id node4
您现在应该能够在不提示输入密码的情况下通过 ssh 进入所有受管节点; 只会要求您输入 ssh 密码(如果您没有将其留空,哈哈)。
建立您的 Ansible 库存
Ansible 清单文件基本上是一个文件,其中包含服务器列表、服务器组或 IP 地址,这些文件引用您希望由 Ansible(托管节点)管理的主机。
这 /etc/ansible/主机 是默认清单文件。 我现在将向您展示如何在 Ansible 中创建自己的清单文件。
创建项目目录
你不想惹 /etc/ansible 目录; 你应该把所有东西都放在里面 /etc/ansible 完好无损,基本上只是在创建清单文件、编辑 Ansible 项目配置文件等时将其用作参考。
现在,让我们创建一个新的 Ansible 项目目录,命名为 /家/艾略特 命名为 戏剧 您将使用它来存储您将从此时开始创建的所有与 Ansible 相关的东西(剧本、库存文件、角色等):
[[email protected] ~]$ mkdir /home/elliot/plays
请注意,您从这一点开始创建的所有内容都将位于控制节点上。
创建库存文件
更改为 /home/elliot/戏剧 目录并创建一个名为 我的主机 并添加所有托管节点的主机名,使其最终看起来像这样:
[[email protected] plays]$ cat myhosts
node1
node2
node3
node4
您现在可以运行以下 Ansible 命令来列出 全部 您的主机在 我的主机 库存文件:
[[email protected] plays]$ ansible all -i myhosts --list-hosts
hosts (4):
node1
node2
node3
node4
这 -一世 选项用于指定 我的主机 库存文件。 如果你省略 -一世 选项,Ansible 将在 /etc/ansible/主机 库存文件。
请记住,我在这里使用主机名,并且我在 Azure 上创建的所有节点 (vm) 都在同一个子网上,我不必担心 DNS,因为它由 Azure 处理。
如果您没有可用的 DNS 服务器,您可以在其中添加节点 IP 地址/主机名条目 /etc/hosts下面是一个 example:
创建主机组和子组
您可以将托管主机组织成组和子组。 为了 example你可以编辑 我的主机 创建两个组的文件 测试 和 产品 如下:
[[email protected] plays]$ cat myhosts
[test]
node1
node2
[prod]
node3
node4
您可以在 产品 通过运行以下命令进行分组:
[[email protected] plays]$ ansible prod -i myhosts --list-hosts
hosts (2):
node3
node4
Ansible 中有两个默认组:
- all – 包含清单中的所有主机
- ungrouped – 包含不属于任何组的所有主机(除了所有)。
让我们添加一个假想的主机 节点5 到 我的主机 清单文件以证明 未分组 团体:
[[email protected] plays]$ cat myhosts
node5
[test]
node1
node2
[prod]
node3
node4
请注意,我添加了 节点5 到开始(而不是结束) 我的主机 文件,否则,它将被视为成员 产品 团体。
现在您可以运行以下命令列出所有 未分组 主持人:
[[email protected] plays]$ ansible ungrouped -i myhosts --list-hosts
hosts (1):
node5
您还可以创建一个包含子组(子组)的组(父组)。 看看以下 example:
[[email protected] plays]$ cat myhosts
[web_dev]
node1
[web_prod]
node2
[db_dev]
node3
[db_prod]
node4
[development:children]
web_dev
db_dev
[production:children]
web_prod
db_prod
这 发展 组包含所有主机 web_dev 加上所有在 db_dev. 同样, 生产 组包含所有主机 web_prod 加上所有在 数据库产品。
[[email protected] plays]$ ansible development -i myhosts --list-hosts
hosts (2):
node1
node3
[[email protected] plays]$ ansible production -i myhosts --list-hosts
hosts (2):
node2
node4
配置 Ansible
在本节中,您将了解最重要的 Ansible 配置设置。 在整个系列中,您将在需要时讨论其他配置设置。
这 /etc/ansible/ansible.cfg 是默认配置文件。 不过也建议大家不要乱搞 /etc/ansible/ansible.cfg 并将其用作参考。 您应该在 Ansible 项目目录中创建自己的 Ansible 配置文件。
这 ansible –version 命令将显示您当前使用的配置文件:
[[email protected] plays]$ ansible --version
ansible 2.9.14
config file = /etc/ansible/ansible.cfg
configured module search path = ['/home/elliot/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Dec 5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
从输出中可以看出, /etc/ansible/ansible.cfg 当前正在使用,因为您尚未创建自己的 ansible.cfg 项目目录下的文件。
这 /etc/ansible/ansible.cfg 包含各种 Ansible 配置设置和部分:
[[email protected] plays]$ wc -l /etc/ansible/ansible.cfg
490 /etc/ansible/ansible.cfg
您需要在 Ansible 配置文件中定义的两个最重要的部分是:
- [defaults]
- [privilege_escalation]
在里面 [defaults] 部分,这是您需要注意的最重要的设置:
- 存货 – 指定库存文件的路径。
- 远程用户 – 指定将连接到托管主机并运行 playbook 的用户。
- 叉子 – 指定 Ansible 可以并行管理/处理的主机数量; 默认值为 5。
- host_key_checking – 指定是否要打开/关闭 SSH 密钥主机检查; 默认为真。
在里面 [privilege_escalation]部分,您可以配置以下设置:
- 变得 – 指定允许/禁止权限提升的位置; 默认为假。
- 成为方法 – 指定提权方式; 默认是 sudo.
- 成为用户 – 指定您通过权限升级成为的用户; 默认是根。
- 成为_ask_pass – 指定是否询问提权密码; 默认为假。
请记住,您不需要将任何这些设置提交到内存中。 它们都记录在 /etc/ansible/ansible.cfg.
现在创建你自己的 ansible.cfg Ansible 项目目录中的配置文件 /home/elliot/戏剧 并设置以下设置:
现在运行 ansible –version 再指挥一次; 你应该看到你的新配置文件现在生效了:
[[email protected] plays]$ ansible --version
ansible 2.9.14
config file = /home/elliot/plays/ansible.cfg
configured module search path = ['/home/elliot/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/lib/python3.6/site-packages/ansible
executable location = /usr/bin/ansible
python version = 3.6.8 (default, Dec 5 2019, 15:45:45) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]
在 Ansible 中运行临时命令
到目前为止,您实际上只是在安装、设置环境和配置 Ansible。 现在,真正的乐趣开始了!
Ansible ad-hoc 命令是一个很棒的工具,您可以使用它在一个或多个托管节点上运行单个任务。 典型的 Ansible ad-hoc 命令遵循一般语法:
ansible host_pattern -m module_name -a "module_options"
了解 Ansible ad-hoc 命令如何工作的最简单方法就是运行一个! 因此,继续运行以下临时命令:
[[email protected] plays]$ ansible node1 -m command -a "uptime"
Enter passphrase for key '/home/elliot/.ssh/id_rsa':
node1 | CHANGED | rc=0 >>
18:53:01 up 5 days, 18:03, 1 user, load average: 0.00, 0.01, 0.00
系统提示我输入我的 ssh 密钥密码,然后显示 node1 的正常运行时间! 现在,检查下图以帮助您了解刚刚运行的临时命令的每个元素:

您现在可能已经猜到了; ansible 模块 是可重用的独立脚本,可由 Ansible API,或由 可靠的 或者 可靠的–剧本 程式。
命令模块是 Ansible 必须提供的众多模块之一。 你可以运行 ansible-doc -l 命令列出所有可用的 Ansible 模块:
[[email protected] plays]$ ansible-doc -l | wc -l
3387
目前,有 3387 个 Ansible 模块可用,而且每天都在增加! 您可以将希望运行的任何命令方式作为选项传递给 Ansible 命令模块。
如果您没有空的 ssh 密钥密码(就像我一样); 那么你将不得不运行 ssh 代理 为了避免每次 Ansible 尝试访问您的托管节点时都提示输入密码而引起不必要的头痛:
[[email protected] plays]$ eval `ssh-agent`
Agent pid 218750
[[email protected] plays]$ ssh-add
Enter passphrase for /home/elliot/.ssh/id_rsa:
Identity added: /home/elliot/.ssh/id_rsa ([email protected])
测试连接性
在执行更严重的任务之前,您可能需要测试 Ansible 是否可以连接到所有托管节点; 为此,您可以使用 平 模块并指定所有托管主机,如下所示:
[[email protected] plays]$ ansible all -m ping
node4 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node3 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
node2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/libexec/platform-python"
},
"changed": false,
"ping": "pong"
}
正如您在输出中看到的所有 SUCCESS 一样。 请注意,Ansible 平 模块不需要任何选项。 有些 Ansible 模块需要选项,有些则不需要,就像 Linux 命令的情况一样。
Ansible 模块文档
如果有人问我你最喜欢 Ansible 的哪一点; 我会很快说这是文档。 Ansible 有很好的文档记录 这一切都来自您自己的终端的舒适。
如果您想了解如何使用特定的 Ansible 模块,那么您可以运行 ansible 文档 后跟模块名称。
为了 example你可以查看描述 平 模块以及如何通过运行来使用它:
[[email protected] plays]$ ansible-doc ping
这将打开 平 模块文档页面:

阅读模块文档时,请特别注意是否有任何选项以等号 (=) 为前缀。 在这种情况下,这是您必须包含的强制性选项。
此外,如果您一直向下滚动,您可以看到一些关于如何运行临时命令或 Ansible 剧本的示例(我们将在稍后讨论)。
命令与外壳与原始模块
人们经常将三个 Ansible 模块相互混淆; 这些都是:
- 命令
- 贝壳
- 生的
这三个模块达到了相同的目的; 它们在受管节点上运行命令。 但是,三个模块之间存在一些关键差异。
您不能将管道或重定向与 命令 模块。 为了 example,以下临时命令将导致错误:
[[email protected] plays]$ ansible node2 -m command -a "lscpu | head -n 5"
node2 | FAILED | rc=1 >>
lscpu: invalid option -- 'n'
Try 'lscpu --help' for more information.non-zero return code
那是因为 命令 模块不支持管道或重定向。 如果您想使用管道或重定向,您可以使用 shell 模块。 再次运行相同的命令,但这一次,使用 贝壳 模块代替:
[[email protected] plays]$ ansible node2 -m shell -a "lscpu | head -n 5"
node2 | CHANGED | rc=0 >>
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 1
On-line CPU(s) list: 0
奇迹般有效! 它成功在node2上显示了lscpu命令输出的前五行。
Ansible 在幕后使用 SSH 和 Python 脚本来完成所有的魔法。 现在 生的 模块只使用 SSH 并绕过 Ansible 模块子系统。 这样,即使未安装 python(在受管节点上),该原始模块也可以在受管节点上成功运行。
我在 node4 上篡改了我的 python 二进制文件(请不要自己这样做),所以我可以模拟一个场景,如果你运行 贝壳 或者 命令 未安装 python 的节点上的模块:
[email protected]:/usr/bin# mkdir hide
[email protected]:/usr/bin# mv python* hide/
现在检查如果我运行 Ansible ad-hoc 会发生什么 贝壳 或者 命令 针对node4的模块:
[[email protected] plays]$ ansible node4 -m shell -a "whoami"
node4 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "Shared connection to node4 closed.rn",
"module_stdout": "/bin/sh: 1: /usr/bin/python: not foundrn",
}
[[email protected] plays]$ ansible node4 -m command -a "cat /etc/os-release"
node4 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"module_stderr": "Shared connection to node4 closed.rn",
"module_stdout": "/bin/sh: 1: /usr/bin/python: not foundrn",
"msg": "The module failed to execute correctly, you probably need to set the interpreter.nSee stdout/stderr for the exact error",
"rc": 127
}
我得到错误! 现在我将尝试完成同样的任务; 但这次,我将使用 生的 模块:
[[email protected] plays]$ ansible node4 -m raw -a "cat /etc/os-release"
node4 | CHANGED | rc=0 >>
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
Shared connection to node4 closed.
如您所见,原始模块是三个模块中唯一成功执行任务的模块。 现在我将回去修复我在 node4 上所做的混乱:
[email protected]:/usr/bin/hide# mv * ..
我创建了下表来帮助总结三个模块的不同用例:
描述 | 命令 | 贝壳 | 生的 |
---|---|---|---|
运行简单的命令 | 是的 | 是的 | 是的 |
使用重定向运行命令 | 不 | 是的 | 是的 |
在没有 Python 的情况下运行命令 | 不 | 不 | 是的 |
好的! 这将我们带到第二个 Ansible 教程的结尾。
请继续关注下一个教程,因为您将学习如何创建和运行 Ansible playbook。 不要忘记成为会员:)