在最近的 Ansible London Meetup 上,我与人聊起了自动化硬件构建。“现在都上云了!” 我听到你这么说。啊,但是对于许多大型组织来说并非如此——他们仍然有大量的数据中心堆满了硬件。几乎经常有人在我们的内部邮件列表中冒出来问,“Ansible 可以进行硬件配置吗?” 是的,你可以使用 Ansible 配置硬件……
要求
硬件引导主要与网络服务有关。在安装任何操作系统 (OS) 之前,我们必须设置一些服务。我们将需要
- DHCP
- PXE
- TFTP
- 操作系统介质
- Web 服务器
设置
除了 DHCP 配置之外,本文中的所有其他内容都由 此存储库 中包含的 Ansible Playbook 处理。
DHCP 服务器
我在这里写作是假设你可以控制你的 DHCP 配置。如果你无法访问你的 DHCP 服务器,你需要请求所有者设置两个选项。DHCP 选项 67 需要设置为 pxelinux.0,next-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 会引导我们的硬件访问这些文件。
你需要来自 pxeboot 的 OS 发行介质中的 images/pxeboot/{initrd.img,vmlinuz}。这些需要复制到 /var/lib/tftpboot/pxeboot。引用的 Ansible Playbook 不会执行此步骤, 因此你需要自己复制它们。
我们还需要提供 OS 安装文件。有两种方法:1) 通过 HTTP 从互联网安装,或 2) 再次通过 HTTP 从本地服务器安装。对于我的测试,由于我是在私有 LAN 上(我猜你也是),最快的安装方法是第二种。准备此操作的最简单方法是挂载 DVD 镜像,并将 images
、Packages
和 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,自然地。祝你好运!
如果你对这个过程有任何想法或评论,请告诉我。
5 条评论