Skip to content

Files

Latest commit

869c669 · Dec 29, 2021

History

History
472 lines (303 loc) · 25.3 KB

File metadata and controls

472 lines (303 loc) · 25.3 KB

一、Ansible 入门

Ansible 与目前可用的其他配置管理工具有着深刻的不同。从简单的英文配置语法到易于设置,它的设计几乎在所有方面都让配置变得容易。您会发现,Ansible 允许您停止编写自定义配置和部署脚本,并允许您继续工作。

Ansible 只需要安装在用于管理基础架构的计算机上。它不需要在被管理的机器上安装客户端,也不需要在使用之前设置任何服务器基础设施。正如我们将在本章中向您展示的那样,您甚至应该能够在安装后几分钟内使用它。

本章包含以下主题:

  • 安装 Ansible
  • 配置 Ansible
  • 从命令行使用 Ansible
  • 使用 Ansible 管理 Windows 机器
  • 如何获得帮助

所需硬件和软件

您将在一台机器上从命令行使用【Ansible,我们称之为控制器机器,而使用它来配置另一台机器,我们称之为 被管理机器。Ansible 目前只支持一台 Linux 或 OS X 控制器机器;但是,被管理的机器可以是 Linux、OS X、其他类似 Unix 的机器或 Windows。Ansible 对控制器机器的要求不多,对被管理机器的要求更少。

控制器机器的要求如下:

  • Python 2.6 或更高版本
  • 帕拉马里科
  • 皮亚米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅米雅
  • 金耶 2
  • httplib2
  • 基于 Unix 的操作系统

被管理的机器需要 Python 2.4 或更高版本和 simplejson 但是,如果您的 Python 是 2.5 或更高版本,则只需要 Python。受管理的 Windows 机器将需要打开 Windows 远程处理,以及大于 3.0 的 Windows PowerShell 版本。虽然 Windows 机器确实有更多的要求,但所有的工具都是免费提供的,Ansible 项目甚至包括脚本来帮助您轻松设置依赖关系。

安装方法

如果您想使用 Ansible 来管理一组现有的机器或基础设施,您可能会希望使用这些系统中包含的任何包管理器。这意味着当您的发行版更新 Ansible 时,您将获得它的更新,这可能比其他方法落后几个版本。但是,这意味着您将运行一个经过测试的版本,以便在您正在使用的系统上工作。

如果您运行现有的基础设施,但需要更新版本的 Ansible,您可以通过 pip 安装 Ansible。 Pip 是一个用来管理 Python 软件和库的包的工具。Ansible 版本一发布就被推送到 pip,所以如果你是 pip 的最新版本,你应该总是运行最新的版本。

如果你想象自己开发了许多模块,并可能对 Ansible 做出贡献,那么你应该运行一个从源代码安装的版本。由于您将运行最新且测试最少的 Ansible 版本,您可能会遇到一两个问题。

从您的发行版安装

大多数现代的发行版都包含一个包管理器,可以自动为你管理包的依赖关系和更新。这使得通过包管理器安装 Ansible 成为最简单的 Ansible 入门方式;通常只需要一个命令。它也会随着你更新你的机器而更新,尽管它可能会落后一两个版本。以下是在最常见的发行版上安装 Ansible 的命令。如果您使用的是不同的产品,请参考您的产品包的用户指南或您的发行版产品包列表:

  • Fedora、RHEL、CentOS 和兼容:

    $ yum install ansible
    
    
  • Ubuntu、Debian 和兼容:

    $ apt-get install ansible
    
    

请注意,RHEL 和 CentOS 要求安装 EPEL 存储库。关于 EPEL 的详细信息,包括如何安装,可以在https://fedoraproject.org/wiki/EPEL找到。

如果您在 Ubuntu 上并希望使用最新版本而不是您的操作系统提供的版本,您可以使用 Ansible 提供的 Ubuntu PPA。关于设置的细节可以在https://launchpad.net/~ansible/+archive/ubuntu/ansible找到。

从管道安装

Pip,就像发行版的包管理器一样,将处理您要求的包及其依赖项的查找、安装和更新。这使得通过 pip 安装 Ansible 就像从您的软件包管理器安装一样简单。但是,应该注意的是,它不会随您的操作系统更新。此外,更新您的操作系统可能会破坏您的 Ansible 安装;然而,这不太可能。如果您是 Python 用户,您可能希望在隔离环境(虚拟环境)中安装 Ansible:这是不支持的,因为 Ansible 试图将其模块安装到系统中。您应该使用 pip 在系统范围内安装 Ansible。

以下是通过 pip 安装 Ansible 的命令:

$ pip install ansible

从源代码安装

从安装源代码是获得最新版本的一个很好的方法,但是它可能不会像发布的版本那样被正确地测试为。您还需要自己负责更新到较新的版本,并确保 Ansible 将继续使用您的操作系统更新。要克隆git存储库并安装它,请运行以下命令。为此,您可能需要系统的 root 访问权限:

$ git clone git://github.com/ansible/ansible.git
$ cd ansible
$ sudo make install

类型

下载示例代码

您可以从您在http://www.packtpub.com的账户中下载您购买的所有 Packt 书籍的示例代码文件。如果您在其他地方购买了这本书,您可以访问http://www.packtpub.com/support并注册,以便将文件直接通过电子邮件发送给您。

设置 Ansible

Ansible 需要能够获得您想要配置的机器的清单,以便管理它们。由于清单插件,这可以通过许多方式实现。基本安装包括几个不同的清单插件。我们将在本书的后面讨论这些。现在,我们将介绍简单主机的文件清单。

默认的 Ansible 清单文件名为 hosts,位于/etc/ansible。它的格式类似于INI文件。组名用方括号括起来,其下的所有内容,一直到下一个组标题,都被分配给该组。机器一次可以分成许多组。组用于允许您一次配置多台计算机。在后面的示例中,您可以使用一个组而不是主机名作为主机模式,并且 Ansible 将立即在整个组上运行该模块。

在下面的例子中,我们有三台机器在一个名为webservers的组中,即site01site02site01-dr。我们还有一个由site01site02db01bastion组成的production小组。

[webservers]
site01
site02
site01-dr

[production]
site01
site02
db01
bastion

将主机放入 Ansible 清单后,您可以开始对它们运行命令。Ansible 包含一个名为ping的简单模块,可以让你测试自己和主机之间的连通性。让我们从命令行对我们的一台机器使用 Ansible 来确认我们可以配置它们。

Ansible 的设计非常简单,开发人员实现这一点的方法之一是使用 SSH 连接到被管理的机器。然后,它通过 SSH 连接发送代码并执行它。这意味着您不需要在被管理的计算机上安装 Ansible。这也意味着 Ansible 使用您已经在使用的频道来管理机器。这使得设置变得更加容易,因为在大多数情况下,在防火墙中不需要设置,也不需要打开端口。

首先,我们使用 Ansible ping模块检查要配置的服务器的连通性。该模块只需连接到以下服务器:

$ ansible site01 -u root -k -m ping

这应该要求 SSH 密码,然后产生如下结果:

site01 | success >> {
 "changed": false,
 "ping": "pong"
}

如果您为远程系统设置了 SSH 密钥,您将能够省略-k参数跳过提示并使用密钥。您还可以配置 Ansible 始终使用特定的用户名,方法是在清单中按主机进行配置,或者在全局 Ansible 配置中进行配置。

要全局设置用户名,编辑/etc/ansible/ansible.cfg并在[defaults]部分更改设置remote_user的行。您也可以更改remote_port来更改 Ansible 将 SSH 连接到的默认端口。这将更改所有计算机的默认设置,但它们可以在清单文件中按服务器或按组覆盖。

要在清单文件中设置用户名,只需将ansible_ssh_user追加到清单中的行。例如,下面的代码部分显示了一个清单,其中site01主机使用用户名root,而site02主机使用用户名daniel。你还可以使用其他变量。ansible_ssh_host变量允许您设置不同的主机名,ansible_ssh_port变量允许您设置不同的端口,这在site01-dr主机上演示。最后db01主机使用用户名fred,也使用ansible_ssh_private_key_file设置私钥。

[webservers]      #1
site01 ansible_ssh_user=root     #2
site02 ansible_ssh_user=daniel      #3
site01-dr ansible_ssh_host=site01.dr ansible_ssh_port=65422      #4
[production]      #5
site01      #6
site02      #7
db01 ansible_ssh_user=fred ansible_ssh_private_key_file=/home/fred/.ssh.id_rsa     #8
bastion      #9

如果您不喜欢让 Ansible 直接访问被管理机器上的根帐户,或者您的机器不允许 SSH 访问根帐户(如 Ubuntu 的默认配置),您可以使用sudo配置 Ansible 以获得根访问权限。将 Ansible 与sudo一起使用意味着您可以以与其他方式相同的方式实现审计。配置 Ansible 使用sudo和配置端口一样简单,只是需要在被管理机器上配置sudo

第一步是在/etc/sudoers文件中增加一行;在托管节点上,如果您选择使用自己的帐户,这可能已经设置好了。您可以使用带sudo的密码,也可以使用不带密码的sudo。如果您决定使用密码,您需要将-k参数设置为 Ansible,或者在/etc/ansible/ansible.cfg中将ask_sudo_pass值设置为true。要使 Ansible 使用 sudo,请将--sudo添加到命令行,如下所示:

ansible site01 -s -m command -a 'id -a'

如果这有效,它应该返回类似于以下内容的内容:

site01 | success | rc=0 >>
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

在 Windows 上设置

Ansible 最近增加了管理 Windows 机器的功能。现在,您可以像管理 Linux 机器一样,使用 Ansible 轻松管理 Windows 机器。

这使用了 Windows PowerShell Remoting 工具,就像在 Linux 机器上使用 SSH 来远程执行模块一样。已经添加了几个明确支持 Windows 的新模块,但是一些现有模块也被赋予了与 Windows 管理的机器一起工作的能力。

要开始管理您的 Windows 机器,您必须执行一点复杂的设置。您需要遵循以下步骤:

  1. 在您的清单中创建一些 Windows 计算机
  2. 安装 Python-winrm 以允许 Ansible 连接到 Windows 机器
  3. 升级到 PowerShell 3.0+以支持 Windows 模块
  4. 启用 Windows 远程处理,以便 Ansible 可以连接

Windows 计算机的创建方式与您清单中的所有其他计算机相同。它们由ansible_connection变量的值来区分。当ansible_connection设置为winrm时,它会尝试通过 winrm 连接到远程机器上的 Windows PowerShell。Ansible 还像在其他机器上一样使用ansible_ssh_useransible_ssh_passansible_ssh_port值。尽管它们中有 ssh 这个名称,但它们被用来提供将用于连接到 Windows PowerShell Remoting 服务的端口和凭据。下面是一个 Windows 机器的示例:

[windows]
dc.ad.example.com
web01.ad.example.com
web02.ad.example.com

[windows:vars]
ansible_connection=winrm
ansible_ssh_user=daniel
ansible_ssh_pass=s3cr3t
ansible_ssh_port=5986

出于安全的原因,您可能不想将密码存储在库存文件中。您可以像我们之前在 Unix 系统中展示的那样,通过简单地省略ansible_ssh_useransible_ssh_pass变量,而是使用-k-u参数来让 Ansible 提示输入密码。您也可以选择将它们存储在 Ansible 保管库中,这将在本书后面介绍。

创建清单后,需要在控制器机器上安装 winrm Python 库。该库将使 Ansible 能够连接到 Windows 远程管理服务并配置远程 Windows 系统。

目前,这个库是相当实验性的,它与 Ansible 的连接并不十分完美,所以您必须安装与您正在使用的 Ansible 版本相匹配的特定版本。随着 Ansible 1.8 的发布,这应该会解决一些问题。大多数发行版还没有打包的库,所以你可能想通过 pip 安装它。作为根用户,您需要运行:

$ pip install https://github.com/diyan/pywinrm/archive/df049454a9309280866e0156805ccda12d71c93a.zip

但是,对于较新的版本,您应该能够运行:

pip install http://github.com/diyan/pywinrm/archive/master.zip

这将安装与 Ansible 1.7 一起工作的 winrm 的特定版本。对于 Ansible 的其他较新版本,您可能需要不同的版本,最终 winrm Python 库应该由不同的发行版打包。您的计算机现在可以使用 Ansible 连接和管理 Windows 计算机。

接下来,您必须在要管理的机器上执行一些设置步骤。其中第一个是确保您安装了 PowerShell 3.0 或更高版本。您可以使用以下命令检查已安装的版本:

$PSVersionTable.PSVersion.Major

如果您得到的值不是 3 或高于 3,那么您将需要升级您的 PowerShell 版本。您可以选择通过为您的系统下载和安装最新的 Windows 管理框架来手动完成此操作,也可以使用 Ansible 项目提供的脚本。为了节省空间,我们将在这里解释脚本安装;手动安装留给读者练习。

Invoke-WebRequest https://raw.githubusercontent.com/ansible/ansible/release1.7.0/examples/scripts/upgrade_to_ps3.ps1 -OutFile upgrade_to_ps3.ps1
.\upgrade_to_ps3.ps1

第一个命令从 GitHub 上的 Ansible 项目存储库中下载升级脚本并保存到磁盘。第二个命令将检测您的操作系统,以下载并安装正确版本的 Windows 管理框架。

接下来,您需要配置 Windows 远程管理服务。Ansible 项目提供了一个脚本,可以按照 Ansible 期望的方式自动配置 Windows 远程管理。虽然您可以手动设置,但强烈建议您使用此脚本来防止错误配置。要下载并运行此脚本,请打开 PowerShell 终端并运行以下命令:

Invoke-WebRequest https://raw.githubusercontent.com/ansible/ansible/release1.7.0/examples/scripts/ConfigureRemotingForAnsible.ps1 -OutFile ConfigureRemotingForAnsible.ps1
.\ConfigureRemotingForAnsible.ps1

第一个命令从 GitHub 上的 Ansible 项目下载配置脚本,第二个命令运行它。如果一切正常,您应该会收到第二个脚本的输出Ok

现在,您应该能够连接到您的机器,并使用 Ansible 对其进行配置。正如我们之前所做的,让我们运行一个 ping 命令来确认 Ansible 能够远程执行它的模块。而 Unix 机器可以使用ping模块,Windows 机器使用win_ping模块。用法几乎完全一样;然而,由于我们已经将密码添加到库存文件中,您不需要-k选项。

$ ansible web01.ad.example.com -u daniel -m win_ping

如果一切正常,您应该会看到以下输出:

web01.ad.example.com | success >> {
 "changed": false,
 "ping": "pong"
}

输出表明,Ansible 能够连接到 Windows 远程管理服务,成功登录,并在远程主机上执行模块。如果运行正常,那么您应该能够使用所有其他的 Windows 模块来管理您的机器。

使用 Ansible 的第一步

Ansible 模块获取看起来类似于key=value的键值对中的参数,在远程服务器上执行一个作业,并将关于该作业的信息作为JSON返回。键值对允许模块知道在被请求时该做什么。它们可以是硬编码的值,或者在行动手册中它们可以使用变量,这将在第 2 章简单行动手册中介绍。从模块返回的数据让 Ansible 知道托管主机中是否有任何更改,或者 Ansible 保存的任何信息是否应该在之后更改。

模块通常在行动手册中运行,因为这样可以将许多模块链接在一起,但是它们也可以在命令行中使用。之前,我们使用ping命令检查 Ansible 是否已正确设置并能够访问配置的节点。ping模块只检查 Ansible 的内核是否能够在远程机器上运行,但实际上什么都不做。

一个稍微有用的模块叫做setup。该模块连接到已配置的节点,收集有关系统的数据,然后返回这些值。从命令行运行时,这对我们来说并不特别方便。但是,在行动手册中,您可以稍后在其他模块中使用收集的值。

要从命令行运行 Ansible,您需要传递两件事,尽管通常是三件。首先是主机模式,以匹配您想要应用模块的机器。其次,您需要提供您希望运行的模块的名称,以及您希望提供给该模块的任何可选参数。对于主机模式,您可以使用组名、计算机名、glob 和波浪号(~),后跟匹配主机名的正则表达式。或者,为了象征所有这些,你可以使用单词all或简单的*。以这种方式在命令行上运行 Ansible 模块被称为临时 Ansible 命令。

要在您的一个节点上运行setup模块,您需要以下命令行:

$ ansible machinename -u root -k -m setup

setup模块然后将连接到机器,并给你一些有用的事实回来。由setup模块本身提供的所有事实都预先加上了ansible_,以区别于变量。

本模块将在 Windows 和 Unix 机器上运行。目前,Unix 机器会比 Windows 机器提供更多的信息。然而,随着 Ansible 新版本的发布,您可以期待看到 Ansible 包含更多的 Windows 功能。

machinename | success >> {
 "ansible_facts": {
 "ansible_distribution": "Microsoft Windows NT 6.3.9600.0",
 "ansible_distribution_version": "6.3.9600.0",
 "ansible_fqdn": "ansibletest",
 "ansible_hostname": "ANSIBLETEST",
 "ansible_ip_addresses": [
 "100.72.124.51",
 "fe80::1fd:fc3b:1eff:350d"
 ],
 "ansible_os_family": "Windows",
 "ansible_system": "Win32NT",
 "ansible_totalmem": "System.Object[]"
 },
 "changed": false
}

以下是一张你将使用的最常用值的表格;并非所有的都可以在所有的机器上使用。Windows 机器从设置模块返回的数据特别少。

|

|

例子

|

描述

| | --- | --- | --- | | ansible_architecture | x86_64 | 这是被管理机器的架构 | | ansible_distribution | CentOS | 这个是被管理机器上的 Linux 或者 Unix 发行版 | | ansible_distribution_version | Six point three | 这个是之前发行版的版本 | | ansible_domain | example.com | 这个是服务器主机名的域名部分 | | ansible_fqdn | machinename.example.com | 这个是被管理机器的全限定域名 | | ansible_interfaces | [“我”、“eth 0”] | 这是机器所有接口的列表,包括环回接口 | | ansible_kernel | 2 . 6 . 32-279 . 6 . x86 _ 64 版 | 这个是被管理机器上安装的内核版本 | | ansible_memtotal_mb | Nine hundred and ninety-six | 这是被管理机器上可用的总内存(兆字节) | | ansible_processor_count | one | 这些是被管理机器上可用的 CPU 总数 | | ansible_virtualization_role | 客人 | 此决定机器是客人还是主机 | | ansible_virtualization_type | 千伏计(kilovoltmeter 的缩写) | 这是被管理机器上虚拟化设置的类型 |

在 Unix 机器上,这些变量是使用 Python 从托管机器上收集的;如果远程节点上安装了 facter 或 ohai,setup模块将执行它们,也将返回它们的数据。和其他事实一样,ohai 事实是加上ohai_的,facter 事实加上facter_的。虽然安装模块在命令行上似乎不太有用,但是一旦您开始编写行动手册,它就很有用。请注意,facter 和 ohai 在 Windows 主机中不可用。

如果 Ansible 中的所有模块都像setupping模块那样做得很少,我们将无法在远程机器上更改任何内容。Ansible 提供的几乎所有其他模块,例如file模块,都允许我们实际配置远程机器。

可以用单路径参数调用file模块;这将使返回有关文件的信息。如果你给它更多的参数,它会尝试改变文件的属性,并告诉你它是否改变了什么。Ansible 模块会告诉您它们是否改变了什么,这在您编写行动手册时变得更加重要。

可以调用file模块,如下命令所示,查看/etc/fstab的详细信息:

$ ansible machinename -u root -k -m file -a 'path=/etc/fstab'

前面的命令应该会引发如下响应:

machinename | success >> {
 "changed": false,
 "group": "root",
 "mode": "0644",
 "owner": "root",
 "path": "/etc/fstab",
 "size": 779,
 "state":
 "file"
}

或者,响应可以类似于下面的命令,在/tmp中创建新的测试目录:

$ ansible machinename -u root -k -m file -a 'path=/tmp/teststate=directory mode=0700 owner=root'

前面的命令应该返回如下内容:

machinename | success >> {
 "changed": true,
 "group": "root",
 "mode": "0700",
 "owner": "root",
 "path": "/tmp/test",
 "size": 4096,
 "state": "directory"
}

我们可以看到,在响应中,已更改的变量被设置为true,因为目录不存在或具有不同的属性,并且需要进行更改以使其与所提供的参数给出的状态相匹配。如果使用相同的参数再次运行,更改的值将被设置为false,这意味着模块没有对系统进行任何更改。

有几个模块接受与file模块相似的参数,其中模块就是一个这样的例子。copy模块在控制器机器上获取一个文件,将其复制到被管理机器上,并根据需要设置属性。例如,要将/etc/fstab文件复制到被管理机器上的/tmp,您将使用以下命令:

$ ansible machinename -m copy -a 'src=/etc/fstab dest=/tmp/fstab'

前面的命令在第一次运行时,应该返回如下内容:

machinename | success >> {
 "changed": true,
 "dest": "/tmp/fstab",
 "group": "root",
 "md5sum": "fe9304aa7b683f58609ec7d3ee9eea2f",
 "mode": "0700",
 "owner": "root",
 "size": 637,
 "src": "/root/.ansible/tmp/ansible-1374060150.96- 77605185106940/source",
 "state": "file"
}

还有一个名为command的模块,它将在被管理的机器上运行任意命令。这使您可以使用任意命令对其进行配置,例如preprovided安装程序或自行编写的脚本;它对于重启机器也很有用。请注意,此模块不在 shell 中运行命令,因此您不能执行重定向、使用管道、展开 shell 变量或后台命令。

Ansible 模块努力防止在不需要时进行更改。这被称为幂等性,可以使针对多台服务器运行命令的速度更快。不幸的是,Ansible 无法知道您的命令是否改变了什么,所以为了帮助它变得更幂等,您必须给它一些帮助。它可以通过createsremoves参数来实现。如果给出一个creates参数,如果文件名参数存在,命令将不会运行。removes论点则相反;如果文件名存在,命令将运行。

您可以按如下方式运行该命令:

$ ansible machinename -m command -a 'rm -rf /tmp/testing removes=/tmp/testing'

如果没有名为/tmp/testing的文件或目录,命令输出将指示其被跳过,如下所示:

machinename | skipped

否则,如果文件确实存在,它将看起来像下面的代码:

ansibletest | success | rc=0 >>

通常最好使用另一个模块来代替command模块。其他模块提供了更多的选项,可以更好地捕捉他们工作的问题领域。例如,在这种情况下,使用file模块对 Ansible 和编写配置的人来说要少得多,因为如果状态设置为absent,则file模块将递归删除某些内容。因此,前面的命令相当于下面的命令:

$ ansible machinename -m file -a 'path=/tmp/testing state=absent'

如果在运行命令时需要使用通常在外壳中可用的功能,则需要 shell模块。这种方式可以使用重定向、管道或作业背面接地。您可以选择与可执行参数一起使用的 shell。您可以使用shell模块,如下所示:

$ ansible machinename -m shell -a '/opt/fancyapp/bin/installer.sh >/var/log/fancyappinstall.log creates=/var/log/fancyappinstall.log'

模块帮助

不幸的是,我们没有足够的空间来覆盖 Ansible 中可用的每个模块;不过幸运的是,Ansible 包含一个命令名ansible-doc,可以检索帮助信息。 Ansible 中包含的所有模块都填充了此数据;但是,从其他地方收集的模块可能会发现帮助较少。ansible-doc命令还允许您查看所有可用模块的列表。

要获得所有可用模块的列表以及每种类型的简短描述,请使用以下命令:

$ ansible-doc -l

要查看特定模块的帮助文件,可以将其作为单个参数提供给ansible-doc。例如,要查看file模块的帮助信息,请使用以下命令:

$ ansible-doc file

总结

在本章中,我们已经介绍了安装 Ansible 应该选择哪种安装类型,以及如何构建一个清单文件来反映您的环境。在此之后,我们看到了如何在简单任务中使用特定风格的 Ansible 模块。最后,我们讨论了如何了解系统中哪些模块可用,以及如何使用命令行获取模块使用说明。

在下一章中,您将学习如何在行动手册中一起使用多个模块。这允许您执行比单独使用单个模块更复杂的任务。