如何使用 Ansible 安装软件

使用 Ansible Playbook 自动化跨设备的软件安装和更新。
45 位读者喜欢这篇文章。
Puzzle pieces coming together to form a computer screen

Opensource.com

Ansible 是系统管理员和开发人员常用的自动化工具,用于保持计算机系统处于最佳状态。与可扩展框架常见的情况一样,Ansible 本身用途有限,其真正的力量在于其众多模块。在某种程度上,Ansible 模块之于 Ansible,就像命令之于 Linux 计算机。它们为特定问题提供解决方案,而维护计算机时一项常见的任务是保持你使用的所有计算机更新且一致。

我过去常常使用软件包的文本列表来保持我的系统或多或少同步:我会列出笔记本电脑上安装的软件包,然后与我的台式机或一个服务器与另一个服务器进行交叉引用,手动弥补任何差异。当然,在 Linux 机器上安装和维护应用程序是 Ansible 的一项基本任务,这意味着你可以列出你想要在你管理的所有计算机上安装的程序。

查找正确的 Ansible 模块

Ansible 模块的数量可能令人眼花缭乱。你如何找到给定任务所需的模块?在 Linux 中,你可能会在“应用程序”菜单或 /usr/bin 中查找要运行的新应用程序。当使用 Ansible 时,你需要参考 Ansible 模块索引

该索引主要按类别列出。稍微搜索一下,你很可能找到满足你任何需求的模块。对于软件包管理,软件包模块部分包含几乎适用于任何带有软件包管理器的系统的模块。

编写 Ansible Playbook

 

首先,选择本地计算机上的软件包管理器。例如,如果你要在运行 Fedora 的笔记本电脑上编写 Ansible 指令(在 Ansible 中称为“Playbook”),请从 dnf 模块开始。如果你在 Elementary OS 上编写,请使用 apt 模块,依此类推。这让你从你可以测试和验证的内容开始,并且你可以在以后扩展你的工作以用于其他计算机。

 

第一步是创建一个代表你的 Playbook 的目录。这不是绝对必要的,但养成这个习惯是个好主意。Ansible 可以仅使用以 YAML 编写的配置文件运行,但如果你想稍后扩展你的 Playbook,你可以通过布局你的目录和文件来控制 Ansible。现在,只需创建一个名为 install_packages 或类似的目录即可

$ mkdir ~/install_packages

作为 Ansible Playbook 的文件可以命名为你喜欢的任何名称,但传统上将其命名为 site.yml

$ touch ~/install_packages/site.yml

在你最喜欢的文本编辑器中打开 site.yml,并添加以下内容

---
- hosts: localhost
  tasks:
    - name: install packages
      become: true
      become_user: root
      dnf:
        state: present
        name:
          - tcsh
         - htop

你必须调整你使用的模块名称以匹配你正在使用的发行版。在本例中,我使用了 dnf,因为我在 Fedora Linux 上编写了 Playbook。

就像 Linux 终端中的命令一样,知道如何调用 Ansible 模块是成功的一半。此 Playbook 示例遵循标准的 Playbook 格式

  • hosts 定位一台或多台计算机。在本例中,定位的计算机是 localhost,它是你现在正在使用的计算机(与你要 Ansible 连接的远程系统相对)。
  • tasks 打开你要在主机上执行的任务列表。
    • name 是任务的人性化标题。在本例中,我使用 install packages ,因为这就是此任务正在执行的操作。
    • become 允许 Ansible 更改运行此任务的用户。
    • become_user 允许 Ansible 成为 root 用户来运行此任务。这是必要的,因为只有 root 用户才能使用 dnf 安装新应用程序。
    • dnf 是模块的名称,你从 Ansible 网站上的模块索引中发现的。

dnf 项下的项目特定于 dnf 模块。这是模块文档至关重要的地方。就像 Linux 命令的 man 手册一样,模块文档告诉你哪些选项可用以及需要哪些类型的参数。

 

软件包安装是一项相对简单的任务,只需要两个元素。state 选项指示 Ansible 检查系统上是否存在某些软件包name 选项列出要查找的软件包。Ansible 处理机器状态,因此模块指令始终意味着更改。如果 Ansible 扫描系统并发现 Playbook 描述系统的方式(在本例中,命令 tcshhtop 存在)与系统状态实际情况(在本例中,tcshhtop 不存在)之间存在冲突,则 Ansible 的任务是进行必要的更改,使系统与 Playbook 匹配。Ansible 可以通过 dnf(或 apt 或任何你的软件包管理器)模块进行这些更改。

每个模块都可能有一组不同的选项,因此在编写 Playbook 时,预计会经常参考模块文档。在你非常熟悉模块之前,这是期望模块执行你所需操作的唯一合理方法。

验证 YAML

Playbook 以 YAML 编写。由于 YAML 遵循严格的语法,因此安装 yamllint 命令来检查(或在计算机术语中称为“lint”)你的工作很有帮助。更好的是,有一个专门为 Playbook 创建的 Ansible linter,称为 ansible-lint。在继续之前安装这些。

在 Fedora 或 CentOS 上

$ sudo dnf install yamllint python3-ansible-lint

在 Debian、Elementary、Ubuntu 或类似系统上

$ sudo apt install yamllint ansible-lint

使用 ansible-lint 验证你的 Playbook。如果你无法访问 ansible-lint,则可以使用 yamllint

$ ansible-lint ~/install_packages/site.yml

成功返回空,但如果你的文件中存在错误,则必须先修复它们才能继续。从复制和粘贴中常见的错误包括在最后一行的末尾省略换行符以及使用制表符而不是空格进行缩进。在文本编辑器中修复它们,重新运行 linter,并重复此过程,直到你从 ansible-lintyamllint 获得任何反馈为止。

[ 提升你的自动化专业知识。获取 Ansible 清单: 迁移到 Red Hat Ansible Automation Platform 2 的 5 个理由 ]

使用 Ansible 安装应用程序

现在你已经有了一个可验证的有效 Playbook,你终于可以在本地计算机上运行它了。因为你碰巧知道 Playbook 定义的任务需要 root 权限,所以你必须在使用 Ansible 调用时使用 --ask-become-pass 选项,这样系统会提示你输入管理员密码。

开始安装

$ ansible-playbook --ask-become-pass ~/install_packages/site.yml
BECOME password: 
PLAY [localhost] ******************************

TASK [Gathering Facts] ******************************
ok: [localhost]

TASK [install packages] ******************************
ok: [localhost]

PLAY RECAP ******************************
localhost: ok=0 changed=2 unreachable=0 failed=0 [...]

命令已安装,使目标系统处于与 Playbook 描述的状态相同的状态。

在远程系统上安装应用程序

经历所有这些来替换一个简单的命令将是适得其反的,但 Ansible 的优势在于它可以跨所有系统自动化。你可以使用条件语句使 Ansible 在不同的系统上使用特定的模块,但现在,假设你的所有计算机都使用相同的软件包管理器。

要连接到远程系统,你必须在 /etc/ansible/hosts 文件中定义远程系统。此文件与 Ansible 一起安装,因此它已经存在,但除了解释性注释外,它可能为空。使用 sudo 在你最喜欢的文本编辑器中打开该文件。

你可以通过其 IP 地址或主机名定义主机,只要主机名可以解析即可。例如,如果你已经在 /etc/hosts 中定义了 liavara 并且可以成功 ping 通它,那么你可以将 liavara 设置为 /etc/ansible/hosts 中的主机。或者,如果你正在运行域名服务器或 Avahi 服务器并且可以 ping 通 liavara,那么你可以将其设置为 /etc/ansible/hosts 中的主机。否则,你必须使用其互联网协议地址。

你还必须设置与目标主机的成功安全外壳 (SSH) 连接。最简单的方法是使用 ssh-copy-id 命令,但如果你以前从未设置过与主机的 SSH 连接,请阅读我的关于如何创建自动化 SSH 连接的文章

/etc/ansible/hosts 文件中输入主机名或 IP 地址后,更改 Playbook 中的 hosts 定义

---
- hosts: all
  tasks:
    - name: install packages
      become: true
      become_user: root
      dnf:
        state: present
        name:
          - tcsh
         - htop

再次运行 ansible-playbook

$ ansible-playbook --ask-become-pass ~/install_packages/site.yml

这次,Playbook 在你的远程系统上运行。

如果你要添加更多主机,有很多方法可以过滤哪个主机执行哪个任务。例如,你可以创建主机组(服务器的 webservers、台式机的 workstations 等)。

适用于混合环境的 Ansible

到目前为止的解决方案中使用的逻辑假设 Ansible 配置的所有主机都运行相同的操作系统(特别是,使用 dnf 命令进行软件包管理的操作系统)。那么,如果你管理的主机运行不同的发行版,例如 Ubuntu(使用 apt)或 Arch(使用 pacman),甚至不同的操作系统,你该怎么办?

只要目标操作系统具有软件包管理器(并且现在甚至 MacOS 也有 HomebrewWindows 也有 Chocolatey),Ansible 就可以提供帮助。

这就是 Ansible 的优势变得最明显的地方。在 shell 脚本中,你必须检查目标主机上可用的软件包管理器是什么,即使使用纯 Python,你也必须检查操作系统。Ansible 不仅内置了这些检查,而且还具有使用 Playbook 中结果的机制。你可以使用 action 关键字来执行由 Ansible 的事实收集子系统提供的变量定义的任务,而不是使用 dnf 模块。

---
- hosts: all
  tasks:
    - name: install packages
      become: true
      become_user: root
      action: >
        {{ ansible_pkg_mgr }} name=htop,transmission state=present update_cache=yes

action 关键字加载操作插件。在本例中,它使用 ansible_pkg_mgr 变量,该变量在初始的 Gathering Facts 任务期间由 Ansible 填充。你不必告诉 Ansible 收集关于它正在运行的操作系统的事实,因此很容易忽略它,但是当你运行 Playbook 时,你会看到它列在默认输出中

TASK [Gathering Facts] *****************************************
ok: [localhost]

action 插件使用来自此探测的信息来使用相关的软件包管理器命令填充 ansible_pkg_mgr,以安装 name 参数后列出的软件包。通过 8 行代码,你可以克服其他脚本选项很少允许的复杂的跨平台难题。

使用 Ansible

现在是 21 世纪,我们都希望我们的计算设备能够连接并且相对一致。无论你维护 2 台还是 200 台计算机,你都不应该一遍又一遍地执行相同的维护任务。使用 Ansible 同步你生活中的计算机,然后看看 Ansible 还能为你做什么。

接下来阅读什么
标签
Seth Kenlon
Seth Kenlon 是一位 UNIX 极客、自由文化倡导者、独立多媒体艺术家和 D&D 爱好者。他曾在电影和计算机行业工作,通常同时进行。

3 条评论

> 到目前为止的解决方案中使用的逻辑假设 Ansible 配置的所有主机都运行相同的操作系统

这正是(也是因为懒惰)我没有对我的少数非 Fedora 机器进行 Ansible 化的原因。但是你的示例假设软件包在操作系统之间的命名是相同的。你建议如何处理名称不同的情况?

Seth,

很棒的介绍。就像 SSH 文章一样!

但是,如何访问防火墙(即,私有动态 IP)后面的 Linux 嵌入式设备(例如,运行带有 opkg 软件包管理器的 Entware)?

我读到有一个 ansible-pull 软件包,据推测它允许设备拨入服务器,以通过反向 SSH 建立连接。

有什么见解或详细信息吗?服务器和设备上需要哪些软件包?

© . All rights reserved.