如何使用AnsibleAdHoc命令管理多个服务器
介绍
Ansible 是一种现代化的配置管理工具,可帮助您完成设置和维护远程服务器的任务。 采用旨在让用户快速启动和运行的简约设计,它允许您使用剧本或临时命令从中央位置控制一到数百个系统。
与 playbook(由可重复使用的任务集合组成)不同,即席命令是您不经常执行的任务,例如重新启动服务或检索有关 Ansible 管理的远程系统的信息。
在本备忘单指南中,您将了解如何使用 Ansible 即席命令从 Ansible 控制节点执行常见任务,例如在一个或多个远程服务器上安装包、复制文件和重新启动服务。
先决条件
为了遵循本指南,您需要:
- 一个 Ansible 控制节点。 本指南假设您的控制节点是安装了 Ansible 并配置为使用 SSH 密钥连接到您的 Ansible 主机的 Ubuntu 20.04 机器。 确保控制节点具有具有 sudo 权限的普通用户并启用了防火墙,如我们的 初始服务器设置 指南中所述。 要设置 Ansible,请按照我们关于 如何在 Ubuntu 20.04 上安装和配置 Ansible 的指南进行操作。
- 两个或更多 Ansible 主机。 Ansible 主机是您的 Ansible 控制节点配置为自动化的任何机器。 本指南假定您的 Ansible 主机是远程 Ubuntu 20.04 服务器。 确保每个 Ansible 主机具有: Ansible 控制节点的 SSH 公钥添加到系统用户的 authorized_keys 中。 此用户可以是 root 用户,也可以是具有 sudo 权限的普通用户。 要进行设置,您可以按照如何在 Ubuntu 20.04 上设置 SSH 密钥的第 2 步进行操作。
- Ansible 控制节点 上设置的库存文件。 确保您有一个包含所有 Ansible 主机的工作清单文件。 要进行设置,请参阅 如何设置 Ansible Inventories 的指南。 然后,通过运行 测试与 Ansible 主机的连接 部分中概述的连接测试,确保您能够连接到您的节点。
测试与 Ansible 主机的连接
以下命令将测试 Ansible 控制节点和所有 Ansible 主机之间的连接性。 该命令使用当前系统用户及其对应的 SSH 密钥作为远程登录,并包含 -m
选项,它告诉 Ansible 运行 ping
模块。 它还具有 -i
标志,它告诉 Ansible ping 指定的 inventory
文件中列出的主机
ansible all -i inventory -m ping
如果这是您第一次通过 SSH 连接到这些服务器,系统会要求您确认通过 Ansible 连接的主机的真实性。 出现提示时,键入 yes
,然后点击 ENTER
进行确认。
你应该得到类似这样的输出:
Outputserver1 | SUCCESS => { "changed": false, "ping": "pong" } server2 | SUCCESS => { "changed": false, "ping": "pong" }
一旦您从主机收到 "pong"
回复,这意味着连接处于活动状态,您已准备好在该服务器上运行 Ansible 命令。
调整连接选项
默认情况下,Ansible 尝试以与当前系统用户同名的远程用户身份使用其对应的 SSH 密钥对连接到节点。
要以不同的远程用户身份连接,请在命令后面附加 -u
标志和预期用户的名称:
ansible all -i inventory -m ping -u sammy
如果您使用自定义 SSH 密钥连接到远程服务器,您可以在执行时使用 --private-key
选项提供它:
ansible all -i inventory -m ping --private-key=~/.ssh/custom_id
注意:关于如何连接节点的更多信息,请参考我们的如何使用Ansible指南,它演示了更多的连接选项。
一旦您能够使用适当的选项进行连接,您可以调整您的清单文件以自动设置您的远程用户和私钥,以防它们与 Ansible 分配的默认值不同。 然后,您无需在命令行中提供这些参数。
以下示例清单文件仅为 server1
服务器设置 ansible_user
变量:
~/ansible/库存
server1 ansible_host=203.0.113.111 ansible_user=sammy server2 ansible_host=203.0.113.112
当连接到 server1
服务器时,Ansible 现在将使用 sammy 作为默认远程用户。
要设置自定义 SSH 密钥,请包含 ansible_ssh_private_key_file
变量,如下所示:
~/ansible/库存
server1 ansible_host=203.0.113.111 ansible_ssh_private_key_file=/home/sammy/.ssh/custom_id server2 ansible_host=203.0.113.112
在这两种情况下,我们只为 server1
设置了自定义值。 如果您想对多个服务器使用相同的设置,您可以使用子组:
~/ansible/库存
[group_a] 203.0.113.111 203.0.113.112 [group_b] 203.0.113.113 [group_a:vars] ansible_user=sammy ansible_ssh_private_key_file=/home/sammy/.ssh/custom_id
此示例配置将分配一个自定义用户和 SSH 密钥,仅用于连接到 group_a
中列出的服务器。
定义命令执行的目标
使用 Ansible 运行临时命令时,您可以针对单个主机以及组、主机和子组的任意组合。 例如,您可以通过以下方式检查名为 servers
的组中每个主机的连接性:
ansible servers -i inventory -m ping
您还可以通过用冒号分隔多个主机和组来指定它们:
ansible server1:server2:dbservers -i inventory -m ping
要在模式中包含异常,请使用感叹号,前缀为转义字符 \
,如下所示。 此命令将在 group1
的所有服务器上运行,除了 server2
:
ansible group1:\!server2 -i inventory -m ping
例如,如果您只想在属于 group1
和 group2
的服务器上运行命令,则应使用 &
代替。 不要忘记在它前面加上一个 \
转义字符:
ansible group1:\&group2 -i inventory -m ping
有关如何在定义命令执行目标时使用模式的更多信息,请参阅我们关于如何设置 Ansible Inventories 的指南的 步骤 5。
运行 Ansible 模块
Ansible 模块是可以从 playbook 和命令行调用的代码片段,以促进在远程节点上执行过程。 示例包括 apt
模块,用于管理 Ubuntu 上的系统包,以及 user
模块,用于管理系统用户。 本指南中使用的 ping
命令也是一个模块,通常用于测试从控制节点到主机的连接。
Ansible 附带了大量内置模块,其中一些需要安装额外的软件才能提供完整的功能。 您还可以使用您选择的语言创建您自己的自定义模块。
要执行带有参数的模块,请包括[x48x] [x52x]标志,然后在双引号中进行适当的选项,例如:
ansible target -i inventory -m module -a "module options"
例如,这将使用 apt
模块在 server1
上安装包 tree
:
ansible server1 -i inventory -m apt -a "name=tree"
运行 Bash 命令
当没有通过 -m
选项提供模块时,默认使用 command 模块在远程服务器上执行指定的命令。
这使您几乎可以执行通常可以通过 SSH 终端执行的任何命令,只要连接用户具有足够的权限并且没有任何交互式提示。
此示例在指定清单中的所有服务器上执行 uptime
命令:
ansible all -i inventory -a "uptime"
Outputserver1 | CHANGED | rc=0 >> 14:12:18 up 55 days, 2:15, 1 user, load average: 0.03, 0.01, 0.00 server2 | CHANGED | rc=0 >> 14:12:19 up 10 days, 6:38, 1 user, load average: 0.01, 0.02, 0.00
使用权限提升运行带有 sudo
的命令
如果要在远程主机上执行的命令或模块需要扩展系统权限或不同的系统用户,则需要使用 Ansible 的权限提升模块 become。 该模块是 sudo
以及 Ansible 在不同操作系统上支持的其他提权软件的抽象。
例如,如果您想运行 tail
命令以从 inventory
名为 server1
的服务器上的 Nginx 错误日志中输出最新的日志消息,则需要包括--become
选项如下:
ansible server1 -i inventory -a "tail /var/log/nginx/error.log" --become
这相当于在远程主机上运行 sudo tail /var/log/nginx/error.log
命令,使用当前本地系统用户或在清单文件中设置的远程用户。
sudo
等权限提升系统通常要求您通过提示您提供用户密码来确认您的凭据。 这将导致 Ansible 无法执行命令或剧本。 然后,您可以使用 --ask-become-pass
或 -K
选项让 Ansible 提示您输入 sudo
密码:
ansible server1 -i inventory -a "tail /var/log/nginx/error.log" --become -K
安装和删除软件包
以下示例使用 apt
模块在提供的清单文件中的所有节点上安装 nginx
包:
ansible all -i inventory -m apt -a "name=nginx" --become -K
要删除包,请包含 state
参数并将其设置为 absent
:。
ansible all -i inventory -m apt -a "name=nginx state=absent" --become -K
复制文件
使用 file
模块,您可以在控制节点和被管节点之间双向复制文件。 以下命令将本地文本文件复制到指定清单文件中的所有远程主机:
ansible all -i inventory -m copy -a "src=./file.txt dest=~/myfile.txt"
要将文件从远程服务器复制到您的控制节点,请包含 remote_src
选项:
ansible all -i inventory -m copy -a "src=~/myfile.txt remote_src=yes dest=./file.txt"
更改文件权限
要修改远程节点上文件和目录的权限,可以使用 file
模块。
以下命令将调整远程主机上位于 /var/www
的名为 file.txt
的文件的权限。 它将文件的 umask 设置为 600
,这将为当前文件所有者启用读写权限。 此外,它将将该文件的所有权设置给一个用户和一个名为 sammy
的组:
ansible all -i inventory -m file -a "dest=/var/www/file.txt mode=600 owner=sammy group=sammy" --become -K
由于该文件位于通常由 root
拥有的目录中,因此我们可能需要 sudo
权限来修改其属性。 这就是我们包含 --become
和 -K
选项的原因。 这些将使用 Ansible 的权限提升系统 以扩展权限运行命令,并提示您为远程用户提供 sudo
密码。
重启服务
您可以使用 service
模块来管理在 Ansible 管理的远程节点上运行的服务。 这将需要扩展系统权限,因此请确保您的远程用户具有 sudo 权限,并且您包括 --become
选项以使用 Ansible 的权限提升系统。 使用 -K
将提示您为连接用户提供 sudo
密码。
例如,要在名为 webservers
的组中的所有主机上重新启动 nginx
服务,您可以运行:
ansible webservers -i inventory -m service -a "name=nginx state=restarted" --become -K
重启服务器
尽管 Ansible 没有用于重启服务器的专用模块,但您可以发出 bash 命令,在远程主机上调用 /sbin/reboot
命令。
重新启动服务器将需要扩展系统权限,因此请确保您的远程用户具有 sudo 权限,并且您包括 --become
选项以使用 Ansible 的权限提升系统。 使用 -K
将提示您为连接用户提供 sudo
密码。
Warning:以下命令将完全重启 Ansible 所针对的服务器。 这可能会导致依赖这些服务器的任何应用程序暂时中断。
例如,要重新启动 webservers
组中的所有服务器,您可以运行:
ansible webservers -i inventory -a "/sbin/reboot" --become -K
收集有关远程节点的信息
setup
模块返回有关 Ansible 管理的远程系统的详细信息,也称为 系统事实 。
要获取 server1
的系统事实,请运行:
ansible server1 -i inventory -m setup
这将打印大量 JSON 数据,其中包含有关远程服务器环境的详细信息。 要仅打印最相关的信息,请包括 "gather_subset=min"
参数,如下所示:
ansible server1 -i inventory -m setup -a "gather_subset=min"
要仅打印 JSON 的特定项目,可以使用 filter
参数。 这将接受用于匹配字符串的通配符模式,类似于 fnmatch。 例如,要获取有关 ipv4 和 ipv6 网络接口的信息,可以使用 *ipv*
作为过滤器:
ansible server1 -i inventory -m setup -a "filter=*ipv*"
Outputserver1 | SUCCESS => { "ansible_facts": { "ansible_all_ipv4_addresses": [ "203.0.113.111", "10.0.0.1" ], "ansible_all_ipv6_addresses": [ "fe80::a4f5:16ff:fe75:e758" ], "ansible_default_ipv4": { "address": "203.0.113.111", "alias": "eth0", "broadcast": "203.0.113.111", "gateway": "203.0.113.1", "interface": "eth0", "macaddress": "a6:f5:16:75:e7:58", "mtu": 1500, "netmask": "255.255.240.0", "network": "203.0.113.0", "type": "ether" }, "ansible_default_ipv6": {} }, "changed": false }
如果您想检查磁盘使用情况,可以运行 Bash 命令调用 df
实用程序,如下所示:
ansible all -i inventory -a "df -h"
Output server1 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on udev 3.9G 0 3.9G 0% /dev tmpfs 798M 624K 798M 1% /run /dev/vda1 155G 2.3G 153G 2% / tmpfs 3.9G 0 3.9G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 3.9G 0 3.9G 0% /sys/fs/cgroup /dev/vda15 105M 3.6M 101M 4% /boot/efi tmpfs 798M 0 798M 0% /run/user/0 server2 | CHANGED | rc=0 >> Filesystem Size Used Avail Use% Mounted on udev 2.0G 0 2.0G 0% /dev tmpfs 395M 608K 394M 1% /run /dev/vda1 78G 2.2G 76G 3% / tmpfs 2.0G 0 2.0G 0% /dev/shm tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 2.0G 0 2.0G 0% /sys/fs/cgroup /dev/vda15 105M 3.6M 101M 4% /boot/efi tmpfs 395M 0 395M 0% /run/user/0
结论
在本指南中,我们演示了如何使用 Ansible ad hoc 命令来管理远程服务器,包括如何执行常见任务,例如重新启动服务或将文件从控制节点复制到 Ansible 管理的远程服务器。 我们还看到了如何使用限制和过滤参数从远程节点收集信息。
作为附加资源,您可以查看 Ansible 的 官方文档 关于 ad hoc 命令。