在最近的 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,你可能想快速浏览一下 维基百科页面。对于本文,我将保持简短——我们将通过 TFTP 提供一些文件,DHCP 将引导我们的硬件。
你需要来自操作系统发行介质的 images/pxeboot/{initrd.img,vmlinuz} 用于 pxeboot。这些需要复制到 /var/lib/tftpboot/pxeboot。引用的 Ansible playbook **不会执行此步骤,**所以你需要自己复制它们。
我们还需要提供操作系统安装文件。有两种方法: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 菜单并立即重新安装自己。我建议删除符号链接作为“双保险”步骤。我将把它作为给你的练习,亲爱的读者。提示:我会让新服务器在启动时“phone home”到某个地方,运行一个清理作业。因为你不需要像我在这里那样打开控制台来演示后台发生的事情,所以“phone home”作业也会很好地表明该过程已完成。Ansible,自然。祝你好运!
如果你对这个过程有任何想法或评论,请告诉我。
5 条评论