使用 Ansible 引导硬件

175 位读者喜欢这篇文章。
computer servers processing data

Opensource.com

在最近的 Ansible London Meetup 上,我与一位人士聊起了自动化硬件构建。“现在都是云了!” 我仿佛听见您这么说。啊,但对于许多大型组织来说并非如此——他们仍然拥有大量装满硬件的数据中心。几乎 регулярно 有人出现在我们的内部邮件列表中并询问,“Ansible 可以进行硬件配置吗?” 嗯,是的,您可以使用 Ansible 配置硬件……

要求

引导硬件主要与网络服务有关。在我们安装任何操作系统 (OS) 之前,我们必须设置一些服务。我们将需要

  • DHCP
  • PXE
  • TFTP
  • 操作系统介质
  • Web 服务器

设置

除了 DHCP 配置之外,本文中的所有其他内容都由 此存储库 中包含的 Ansible playbook 处理。

DHCP 服务器

我在这里写作是假设您可以控制您的 DHCP 配置。如果您无法访问您的 DHCP 服务器,您需要请求所有者设置两个选项。DHCP 选项 67 需要设置为 pxelinux.0next-server(即选项 66——但您可能不需要知道这一点;通常 DHCP 服务器会有一个用于“next server”的字段/选项)需要设置为您的 TFTP 服务器的 IP 地址。

如果您可以拥有 DHCP 服务器,我建议使用 dnsmasq。它体积小且简单。我不会在此处介绍如何配置它,但请查看 手册页--enable-tftp 选项。

TFTP

上面我们 DHCP 服务器的 next-server 设置将指向一台提供 TFTP 的机器。在这里,我使用了 CentOS Linux 虚拟机,因为它只需要一个软件包 (syslinux-tftpboot) 和一项启动的服务即可使 TFTP 启动并运行。我们将坚持默认路径 /var/lib/tftpboot

PXE

如果您还不熟悉 PXE,您可能想快速浏览一下 Wikipedia 页面。对于本文,我将保持简短——我们将通过 TFTP 提供一些文件,DHCP 将引导我们的硬件访问这些文件。

您将需要来自 OS 发行介质的 images/pxeboot/{initrd.img,vmlinuz} 用于 pxeboot。这些需要复制到 /var/lib/tftpboot/pxeboot。引用的 Ansible playbook 不执行此步骤,因此您需要自己复制它们。

我们还需要提供 OS 安装文件。有两种方法可以做到这一点:1) 通过 HTTP 从互联网安装,或 2) 再次通过 HTTP 从本地服务器安装。对于我的测试,由于我在专用 LAN 上(我猜您也是),最快的安装方法是第二种。准备此方法的最简单方法是挂载 DVD 映像,并将 imagesPackages repodata 目录 rsync 到您的 Web 服务器位置。引用的 Ansible playbook 将安装 httpd,但不会复制这些文件,因此在运行 playbook 后不要忘记执行此操作。对于本文,我们将再次坚持默认设置以保持简单——因此文件需要复制到 Apache 的标准文档根目录 /var/www/html

目录

我们最终应该得到像这样的目录结构

PXE/TFTP

[root@c7 ~]# tree  /var/lib/tftpboot/pxe{b*,l*cfg}
/var/lib/tftpboot/pxeboot
└── 6
    ├── initrd.img
    └── vmlinuz

httpd

[root@c7 ~]# tree -d /var/www/html/
/var/www/html/
├── 6 -> centos/6
├── 7 -> centos/7
├── centos
│   ├── 6
│   │   └── os
│   │       └── x86_64
│   │           ├── images
│   │           │   └── pxeboot
│   │           ├── Packages
│   │           └── repodata
│   └── 7
│       └── os
│           └── x86_64
│               ├── images
│               │   └── pxeboot
│               ├── Packages
│               └── repodata
└── ks

您会注意到我的 Web 设置看起来比上面的文字描述要复杂一些!我粘贴了我的实际结构,为您提供一些想法。我使用的硬件非常老旧,甚至让 CentOS 7 工作都很糟糕(如果您有兴趣,这是因为缺少用于 HP Smart Array 控制器的 cciss 驱动程序——是的,有一个答案,但这需要大量繁琐的操作才能使其工作),因此所有示例都是 CentOS 6 的。我还想要一个灵活的设置,可以安装多个版本。在这里,我使用符号链接实现了这一点——这种安排也完全适用于 RHEL。但基本结构仍然存在——请注意 images、Packages 和 repodata 目录。

这些路径直接关系到我们将要提供的 PXE 菜单 文件和 kickstart 文件

如果您没有 DHCP

如果您无法管理自己的 DHCP 服务器,或者您的基础设施所有者无法提供帮助,则还有另一种选择。过去,我使用 iPXE 创建了一个引导映像,我将其作为虚拟介质加载。现代硬件上的许多带外/远程管理 (LOM) 接口都支持此功能。您可以使用 iPXE 在几秒钟内创建一个自定义的嵌入式 PXE 菜单。我不会在此处介绍这一点,但如果这最终成为您的问题,请在 Twitter 上给我留言,如果足够多的人要求,我会考虑写一篇后续博文。

安装硬件

现在我们已经搭建好了结构,我们可以 kickstart 一台服务器。在我们这样做之前,我们必须向 TFTP 设置添加一些配置,以使给定的硬件能够获取 PXE 引导菜单。

在这里我们遇到了一个小的先有鸡还是先有蛋的问题。我们需要主机的 MAC 地址来创建指向我们要 kickstart 的特定硬件的链接。如果硬件已经在运行,并且我们可以使用 Ansible 访问它,那就太好了——我们可以通过 setup 模块找到引导接口 MAC 地址(请参阅 reinstall playbook)。但是,如果是新的硬件,我们需要获取 MAC 地址并告诉我们的设置如何处理它。这可能意味着一些手动干预——启动服务器并查看屏幕,或者可能从清单或其他类似的东西中获取 MAC 地址。无论您以何种方式获得它,我们都可以通过清单告诉我们的 playbook。

让我们在简单的 INI 格式 清单文件 中放入一个自定义变量,但运行一个 playbook 来设置 TFTP……

(pip)iMac:ansible-hw-bootstrap$ ansible-inventory --host hp.box
{
    "ilo_ip": "192.168.1.68",
    "ilo_password": "administrator"
}
(pip)iMac:ansible-hw-bootstrap$ ansible-playbook plays/install.yml

PLAY [kickstart] *******************************************************************************************************

TASK [Host inventory entry has a MAC address] **************************************************************************
failed: [ks.box] (item=hp.box) => {
    "assertion": "hostvars[item]['mac'] is defined",
    "changed": false,
    "evaluated_to": false,
    "item": "hp.box",
    "msg": "Assertion failed"
}

PLAY RECAP *************************************************************************************************************
ks.box                     : ok=0    changed=0    unreachable=0    failed=1

哦,playbook 失败了。它 包含一项检查,检查我们要安装的主机实际上是否已添加 MAC 地址。让我们修复它并再次运行 playbook……

(pip)iMac:ansible-hw-bootstrap$ ansible-inventory --host hp.box
{
    "ilo_ip": "192.168.1.68",
    "ilo_password": "administrator",
    "mac": "00:AA:BB:CC:DD:EE"
}
(pip)iMac:ansible-hw-bootstrap$ ansible-playbook plays/install.yml

PLAY [kickstart] *******************************************************************************************************

TASK [Host inventory entry has a MAC address] **************************************************************************
ok: [ks.box] => (item=hp.box) => {
    "changed": false,
    "item": "hp.box",
    "msg": "All assertions passed"
}

TASK [Set PXE menu to install] *****************************************************************************************
ok: [ks.box] => (item=hp.box)

TASK [Reboot target host for PXE boot] *********************************************************************************
skipping: [ks.box] => (item=hp.box)

PLAY RECAP *************************************************************************************************************
ks.box                     : ok=2    changed=0    unreachable=0    failed=0

成功了!它做了什么?查看我们 TFTP 根目录下的 pxelinux.cfg 目录,我们可以看到一个符号链接……

[root@c7 pxelinux.cfg]# pwd
/var/lib/tftpboot/pxelinux.cfg
[root@c7 pxelinux.cfg]# l
total 12
drwxr-xr-x. 2 root root   65 May 13 14:23 ./
drwxr-xr-x. 4 root root 4096 May  2 22:13 ../
-r--r--r--. 1 root root  515 May  2 12:22 00README
lrwxrwxrwx. 1 root root    7 May 13 14:12 01-00-aa-bb-cc-dd-ee -> install
-rw-r--r--. 1 root root  682 May  2 22:07 install

install 文件被符号链接到一个以我们的 MAC 地址命名的文件。这是关键且有用的部分。它将确保当 MAC 地址为 00-aa-bb-cc-dd-ee 的硬件从其网卡启动时,将为其提供 PXE 菜单。

那么让我们启动我们的机器。

有用的是,Ansible 具有一些 远程管理模块。我们在这里使用的是 HP 服务器,因此我们可以使用 hpilo_boot 模块,从而无需直接与 LOM Web 界面交互。

让我们在一个已启动的服务器上运行 reinstall playbook……

您会注意到 hpilo_boot 模块的妙处在于,它将引导介质设置为网络。当安装完成时,服务器重新启动并从其硬盘驱动器启动。眼尖的人会发现这里的关键问题——如果服务器再次从其网卡启动会发生什么?它会获取 PXE 菜单并立即重新安装自身。我建议删除符号链接作为“双保险”步骤。我将其留给您,亲爱的读者,作为练习。提示:我会让新服务器在启动时“呼叫主页”到某个地方,该地方运行清理作业。由于您不需要像我在这里那样打开控制台来演示后台发生的事情,“呼叫主页”作业也会很好地指示该过程已完成。Ansible,自然。祝您好运!

如果您对这个过程有任何想法或评论,请告诉我。

User profile image.
Mark 拥有四分之一世纪的行业经验,在各个层面设计和构建了自动化基础设施——从初创公司中的少量主机到投资银行中的数万台主机。

5 条评论

在我的公司,我们正在做类似的事情。但是现在 HPE 拥有 HTTP 引导,我们跳过了 DHCP、TFTP 和 PXE。在我的案例中,我利用了 rear 备份。我创建了一个 EL7 安装的 rear 备份,然后编辑了它创建的 ISO,使其指向位于 Web 服务器上的 kickstart 文件。使用 HTTP 引导,我们将其指向也位于 Web 服务器上的 ISO,它会启动,加载 kickstart,然后开始工作。我确实做了一个奇怪的解决方法,以便能够通过 DHCP 连接到主机。我最终将序列号添加到 DNS,并让 Ansible 以这种方式连接到主机以完成服务器设置。

做得好 feeble!是的,我以前也使用过自定义 ISO 来进行“定制的 kickstart”。使用 iPXE 和“kssendmac”为 kickstart 脚本提供唯一的 ID 以交付定制的配置,效果很好。几年前,我使用了这里写的方法来管理一个 24 节点的视频墙——节点可以完全远程动态重建,Ansible 的东西非常简单易用。效果很好。感谢您告诉我们您正在做什么,很高兴听到!

回复 feeble

感谢 Mark,解释得很好。我添加了 cobbler 以及 cobbler ansible 模块来完成相同的任务,另一种方法是使用 hpilo_boot 通过虚拟介质挂载 Golden 镜像。但是,如果 kickstart 文件可以自动化(使用 j2)以获取 IP、主机名,是否有任何帮助?假设我有 100 台服务器,每台服务器都使用 Ansible 引导并指向一个 HTTP kickstart 文件。我希望每台主机都使用静态 IP 和静态主机名。

你好!您可以通过让内核 'ks=' 行指向脚本来制作自定义的 kickstart 文件。使用 'kssendmac',X 标头会随请求一起发送(从内存中,X-RHN-Provisioning-MAC-0)。由此,您可以将 MAC 地址与主机名等关联起来,并返回自定义的 kickstart 文件。这真的不需要是一个复杂的 CGI 脚本,只要您可以解析 X-RHN... 标头,您就搞定了。很久很久以前,当我还在编写 Perl 代码时,我写了一些东西来做这件事 https://github.com/phips/bacio 我不建议使用它,除非是为了获得灵感!最好只是用您习惯使用的任何语言编写一个简单的 CGI。HTH

回复 kanchan Chakraborty (未验证)

在阅读本文后,所有人都可以轻松理解基本原理。

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 获得许可。
© . All rights reserved.