Cobbler分离DHCP的实践

在大部分需要自动化部署系统的环境中,都是已经存在DHCP服务的,所以分离服务角色是很有助于帮助运维或者技术人员基于当前环境的建设预期目标。

Cobbler分离DHCP的实践

背景

对于经常做实验的技术从业者,尝尝因为做各种架构验证或搭建类的操作,其中包含IaaS和PaaS类;因此需要多种操作系统运行环境;后期希望再配合vagrant和Cobbler绑定Mac地址的方式,来进一步到各种环境的自动初始化。

研究了几天Cobbler,也就它可以跨操作系统类型,Windows的WDS只支持自家的;网上也随着搜了几天,发现都是一股脑的全套部署,目前还没找到有人做这种分离部署(也可能我没收到);官档上也没提这方面;在大部分的部署环境中,我觉得9成都是已经有了DHCP,所以这种分离部署就成了我的出发点;

既然基于复用DHCP功能,那么其实这种复用还是对DHCP的可配置项有要求的;

所以,那就开始探索之路吧。

环境

  • CentOS 7.9 Minimal(1908)
  • CentOS 8.2 Minimal(2004)
  • openSUSE Tumbleweed
  • VMware Workstation 16 Pro
  • Windows Hyper-V(2019)
  • ikuai x32 3.5.4
  • pfSense CE 2.5.1
  • Cobbler 2.8.5
  • Cobbler 3.2
  • 为什么会有这么多环境?还不是因为没有尝到爱情的毒,却中了生活的苦......

版本差异

大同小异,不同的系统和版本区别就是一些包名称不同而已;配置方法区别也较小。

明显区别(坑):

CentOS 7是因为Python版本过低导致get-loaders命令无法下载。7.9默认安装的是Cobbler 2.8版本;CentOS 8也是因为urllib3的包问题无法执行get-loaders;究其原因,是因为GitHub取消了TLS 1.0;但其实这个错误可以忽略,因为只要安装了syslinux,那么Cobbler可以不用额外下载其他引导文件,对于x86和x86_64的引导已经有了。除非你需要ARM和POWER架构的系统引导。

CentOS 8的check没有提示debmirror,不知道deb系能不能安装。

openSUSE压根没有get-loaders这个命令。

全套部署

因为CentOS7是相对于CentOS8和openSUSE支持功能最全的,所以以7为例;先走一遍;不过这里只涉及环境搭建,并没有调优(估计后面会单独写);因为主要是为了梳理部署过程和分离验证。所以也不涉及原理陈述。

CentOS7

初始化

# 关闭selinux
sed -i 's/enforcing/disabled/g' /etc/selinux/config

# 安装软件包
yum install cobbler cobbler-web httpd pykickstart syslinux xinetd dhcp -y
# 开机自启动
systemctl enable cobblerd httpd tftp rsyncd xinetd dhcpd
# 查看是否成功
systemctl list-unit-files | grep enabled | grep -E 'cobblerd|tftp|rsyncd|xinetd|dhcpd'

配置服务

cobbler

vim /etc/cobbler/settings

server: 192.168.0.106

# 这个参数重点说明一下:
# 这里指的是TFTP的地址,有些说是DHCP地址,也不能算是错;因为DHCP会把这个地址作为选项一起传送过去;所以这个地址很重要。
# 如果TFTP也做分离部署的话,那么这里就是指向TFTP的地址;这里要和DHCP选项的next_server对应,后面会有详细介绍。
# 所以这里就是一个对当前DHCP要求的指标之一,如果当前环境中的DHCP不支持这个选项,那么就没戏了。
next_server: 192.168.0.106

# 装系统重启后,不再进入PXE引导菜单,直接引导硬盘的系统。
pxe_just_once: 1

# 动态配置自动重启cobbler服务,可选开启
allow_dynamic_settings: 1

# 这里不用修改,注意一下,导入的每个ISO镜像都会默认关联一个ks文件作为自动应答文件。这里是默认的。
default_kickstart: /var/lib/cobbler/kickstarts/default.ks

# 修改默认密码,使用命令 openssl passwd -1 -salt "" "cobbler"
# ""为密语,cobbler为要加密的密码。

# 这里是新系统的root密码!
# 这里是新系统的root密码!
# 这里是新系统的root密码!
default_password_crypted: 

# 因为是全套配置,所以这次包含DHCP
# 这里的管理指的是cobbler对于这些服务的配置文件定义,当使用sync命令同步的时候,会覆盖这些服务的配置文件;
manage_dhcp: 1
manage_rsync: 1

# 文件的末尾有2行代理设置,如果访问GitHub不好的,酌情添加。(前提是你得搞定Python包问题)

TFTP

vim /etc/xinetd.d/tftp

disable = no

DHCP

dhcp目录下的配置文件是空的,所以配置DHCP的配置在/etc/cobbler/dhcp.template

# 默认配置

# 省略
subnet 192.168.1.0 netmask 255.255.255.0 {
     option routers             192.168.1.5;
     option domain-name-servers 192.168.1.1;
     option subnet-mask         255.255.255.0;
     range dynamic-bootp        192.168.1.100 192.168.1.254;
     default-lease-time         21600;
     max-lease-time             43200;
     next-server                $next_server;
     # 省略

# 修改后
# 我采用了23位子网,酌情配置;如果是最小修改就是路由那里;保持和你的PC电脑一致,不然装完SSH进不去。
# 这个网段要和当前部署的机器所处同一网段,不然DHCP服务起不来。

subnet 192.168.0.0 netmask 255.255.254.0 {
     option routers             192.168.0.1;
     option domain-name-servers 192.168.0.1;
     option subnet-mask         255.255.254.0;
     range dynamic-bootp        192.168.0.100 192.168.1.254;
     default-lease-time         21600;
     max-lease-time             43200;
     next-server                $next_server;

拷贝引导文件

cp -v /usr/share/syslinux/{pxelinux.0,menu.c32} /var/lib/cobbler/loaders/

其他服务不用动;马上就要启动服务了,却把局域网内的其他DHCP停止服务,不然会有冲突。

启动服务

# 再启动服务之前,需要执行一次sync命令去同步配置文件,不然有些服务因为缺少配置文件起不来或者没有按照我们定义的配置运行,还得再次重启。
cobbler sync
systemctl start cobblerd httpd rsyncd tftp dhcpd xinetd
# 查看服务状态是否有报错
systemctl status cobblerd httpd rsyncd tftp dhcpd xinetd

初始化Cobbler

# 先执行检察
[root@cobbler ~]# cobbler check
The following are potential configuration items that you may want to fix:

1 : Some network boot-loaders are missing from /var/lib/cobbler/loaders, you may run 'cobbler get-loaders' to download them, or, 
if you only want to handle x86/x86_64 netbooting, you may ensure that you have installed a *recent* version of the syslinux package installed and can ignore this message entirely. 
Files in this directory, should you want to support all architectures, should include pxelinux.0, menu.c32, elilo.efi, and yaboot. 
The 'cobbler get-loaders' command is the easiest way to resolve these requirements.
2 : debmirror package is not installed, it will be required to manage debian deployments and repositories
3 : fencing tools were not found, and are required to use the (optional) power management features. install cman or fence-agents to use them

Restart cobblerd and then run 'cobbler sync' to apply changes.
  1. 引导文件

    1. 第一条如上面所说的,只用于x86/x86_64的话,无需下载额外的引导文件;

    2. CentOS 7执行get-loaders必然会失败,不信你看;原因是GitHub取消了TLS 1.0

    3. [root@cobbler ~]# cobbler get-loaders
      task started: 2021-06-19_125325_get_loaders
      task started (id=Download Bootloader Content, time=Sat Jun 19 12:53:25 2021)
      downloading https://cobbler.github.io/loaders/README to /var/lib/cobbler/loaders/README
      Exception occured: <class 'urlgrabber.grabber.URLGrabError'>
      Exception value: [Errno 14] HTTPS Error 404 - Not Found
      Exception Info:
        File "/usr/lib/python2.7/site-packages/cobbler/remote.py", line 82, in run
          rc = self._run(self)
         File "/usr/lib/python2.7/site-packages/cobbler/remote.py", line 176, in runner
          return self.remote.api.dlcontent(self.options.get("force",False), self.logger)
         File "/usr/lib/python2.7/site-packages/cobbler/api.py", line 735, in dlcontent
          return grabber.run(force)
         File "/usr/lib/python2.7/site-packages/cobbler/action_dlcontent.py", line 73, in run
          urlgrabber.grabber.urlgrab(src, filename=dst, proxies=proxies)
         File "/usr/lib/python2.7/site-packages/urlgrabber/grabber.py", line 773, in urlgrab
          return default_grabber.urlgrab(url, filename, **kwargs)
         File "/usr/lib/python2.7/site-packages/urlgrabber/grabber.py", line 1220, in urlgrab
          return _run_callback(opts.failfunc, opts)
         File "/usr/lib/python2.7/site-packages/urlgrabber/grabber.py", line 1071, in _run_callback
          return cb(obj)
         File "/usr/lib/python2.7/site-packages/urlgrabber/grabber.py", line 1065, in _do_raise
          raise obj.exception
      
      !!! TASK FAILED !!!
      
    4. 解决办法是升级Python版本到3.x,所以这里就会出现判断分支,如果这台机器仅仅用于Cobbler的话,那么升级Python版本无所谓,升级到3.x之后,在变更一下yum的配置文件就行了,如果还有其他服务依赖于Python2的话,那就得注意。

  2. debmirror是安装deb包系用的,如Debian和Ubuntu;

    1. yum install debmirror -y
      
      # 配置服务
      vim /etc/debmirror.conf
      
      # 注释掉2行
      @dists="sid";
      @arches="i386";
      
  3. fencing是电源管理的,这对于IDC运维会有帮助,结合IPMI之类的;我这忽略。

cobbler-web

这里注意,cobbler传输文件是用HTTP发布的;而Web控制台是用HTTPS发布的;

http://192.168.0.106/cobbler

https://192.168.0.106/cobbler_web

用户名:cobbler

密码:cobbler

更多关于cobbler-web的配置在[官方文档](5. Web Interface — Cobbler 2.8.5 documentation)

导入镜像

通过挂载光驱的方式或者直接上传ISO镜像的方式,把文件挂到目录里;

# 挂在ISO
mount CentOS-7-x86_64-Minimal-1908.iso /mnt/
# 导入
cobbler import --name=CentOS7 --path=/mnt

开启防火墙

如果关闭了firewalld,则忽略;

[root@cobbler ~]# ss -tunl
Netid  State      Recv-Q Send-Q           Local Address:Port                          Peer Address:Port              
udp    UNCONN     0      0                            *:67                                       *:*                  
udp    UNCONN     0      0                            *:68                                       *:*                  
udp    UNCONN     0      0                            *:69                                       *:*                  
udp    UNCONN     0      0                         [::]:69                                    [::]:*                  
tcp    LISTEN     0      5                            *:873                                      *:*                  
tcp    LISTEN     0      128                          *:22                                       *:*                  
tcp    LISTEN     0      100                  127.0.0.1:25                                       *:*                  
tcp    LISTEN     0      5                    127.0.0.1:25151                                    *:*                  
tcp    LISTEN     0      5                         [::]:873                                   [::]:*                  
tcp    LISTEN     0      128                       [::]:80                                    [::]:*                  
tcp    LISTEN     0      128                       [::]:22                                    [::]:*                  
tcp    LISTEN     0      100                      [::1]:25                                    [::]:*                  
tcp    LISTEN     0      128                       [::]:443                                   [::]:*

# 69是TFTP的
# 873是cobbler的
# 80是http的,拉取文件需要
# 443是控制台的
firewall-cmd --add-service=http --per
firewall-cmd --add-service=https --per
firewall-cmd --add-service=tftp --per
firewall-cmd --add-port=873/tcp --per
firewall-cmd --reload

PXE引导

此时是用桥接模式,不管是HYPER-V还是VMware Workstation,以网络启动,就可以完成自动化装系统了,默认也关联了ks文件。

2.8版本的[官方文档](Welcome to Cobbler's documentation! — Cobbler 2.8.5 documentation)

自动应答ks文件

CentOS 7版本装完后,会在当前用户目录下有个anaconda-ks.cfg;这是最好的ks文件,里面包含了你这次的一些自定义设置。

CentOS8

Cobbler 3.2的文档相比2.8的完善了很多[官方3.2文档](Welcome to Cobbler's documentation! — Cobbler 3.2.1 documentation)

  1. 同上,关闭selinux

  2. 部署软件

    1. dnf install epel-release
      dnf module enable cobbler
      dnf install cobbler rsyncd dhcp-server -y
      # 会包含tftp-server,rsync和dhcp;rsyncd需要单独安装,它是rsync的守护进程。
      # cobbler-web无法安装,依赖的Django版本不同。
      
  3. 其他配置都同上

openSUSE

  1. 安装软件更简单,依赖的都基本上都一次装齐了;apache2、fence-agents、tftp、xinetd,除了没有dhcp服务,这也是我将在这个基础上实现分离部署的环境。

    1. sudo zypper in -y cbbler syslinux yum-utils
      
      # 因为需要这两个包,所以需要yum-utils
      reposync not installed, install yum-utils
      yumdownloader is not installed, install yum-utils
      # 安装时候会提示有个冲突,卸载冲突那个包就行了
      
      问题: 要安装的 yum-utils-4.0.21-1.1.noarch 与安装的 zypper-needs-restarting-1.14.46-1.1.noarch 所提供的 "zypper-needs-restarting" 冲突
       解决方案 1: 卸载 zypper-needs-restarting-1.14.46-1.1.noarch
       解决方案 2: 不安装 yum-utils-4.0.21-1.1.noarch
      
      请通过数字从以上解决方案中选择,或取消 [1/2/c/d/?] (c): 1
      
    2. TFTP无法设置开机自启动,缺少配置文件;启动后,可以看到调用的服务文件,添加2行即可

      ● tftp.service - Tftp Server
           Loaded: loaded (/usr/lib/systemd/system/tftp.service; static)
           Active: active (running) since Sun 2021-06-20 16:05:10 CST; 3s ago
      TriggeredBy: ● tftp.socket
         Main PID: 3481 (in.tftpd)
            Tasks: 1 (limit: 2153)
              CPU: 10ms
           CGroup: /system.slice/tftp.service
                   └─3481 /usr/sbin/in.tftpd -u tftp -s /srv/tftpboot
      # 修改
      sudo vim /usr/lib/systemd/system/tftp.service
      # 在末尾增加
      [Install]
      WantedBy=network.target
      Alias=tftp.service
      
      # 重载服务
      sudo systemctl daemon-reload
      sudo systemctl enable tftp
      sudo systemctl status tftp
      
  2. cobbler配置

    1. # 先生成新系统的root密码
      openssl passwd -1 -salt "" "123456"
      
      sudo vim /etc/cobbler/settings.yaml
      
      allow_dynamic_settings: true
      default_password_crypted: "$1$$RmyPVMlhpXjJj8iv4w.Ul."
      # manage_dhcp和manage_dns默认都是false,保持不变;
      manage_rsync: true
      next_server: 192.168.0.129 # 本机地址
      server: 192.168.0.129 # 本机地址
      # 其他保持默认即可
      
  3. 启动服务

    1. sudo systemctl enable cobblerd apache2 tftp rsyncd
      sudo systemctl start cobblerd apache2 tftp rsyncd
      # 小bug修理一下;因为这个目录UG都是root用户,所以apache用户创建不成功。
      6月 20 16:18:58 pxe touch[3702]: /usr/bin/touch: 无法创建 '/usr/share/cobbler/web/cobbler.wsgi': 没有那个文件或目录
      sudo mkdir /usr/share/cobbler/web
      sudo systemctl restart cobblerd
      
      # 查看服务状态是否有错误
      sudo systemctl status cobblerd apache2 tftp rsyncd
      
  4. 防火墙还是同上,只是没有安装web,少个https而已

    1. firewall-cmd --add-service=http --per
      firewall-cmd --add-service=tftp --per
      firewall-cmd --add-port=873/tcp --per
      firewall-cmd --reload
      
  5. 导入镜像;操作也是同上

    1. sudo mount CentOS-7-x86_64-Minimal-1908.iso /mnt/
      
  6. 检查配置

    1. sudo cobbler check
      # 就剩一条提醒,一些网络启动的可能需要额外的引导文件等等。忽略
      
  7. 同步配置

    1. sudo cobbler sync
      # 重启一下全部的服务
      sudo systemctl restart cobblerd tftp rsyncd
      # 确认状态
      sudo systemctl status cobblerd tftp rsyncd
      

前置部署就到这了,剩下就是分离DHCP部分了。

分离部署

爱快

ikuai-dhcp-option

爱快的DHCP增加了不少额外的选项来覆盖更多的应用场景;但这里并不好用,因为没有达到我的预期;没有对应的官方文档对这些有说明;去论坛搜索,也没有对应的答案;

在iana组织当中,找到了DHCP字段的全部描述Dynamic Host Configuration Protocol (DHCP) and Bootstrap Protocol (BOOTP) Parameters (iana.org)

next_server字段是必须的;填写的是TFTP的地址;所以像一些家用路由器中的DHCP就没戏了;

option66和67的描述是下图,都用16进制填写

dhcp-66and67

192.168.0.126转为16进制是:C0A80081

pxelinux.0转为16进制是:7078656c696e75782e30

但是这样不行,填写别的值无法保存,提示无效;这样会导致在启动引导的时候,提示pxe-t01 file not found linux

使用爱快以失败告终。

pfSense

使用pfSense只需要正常填写,即可成功引导。还支持UEFI的引导。

pfsense-dhcp-option

后记

最终通过探索,完成了我的预期,但这只是个起点,还有一些优化配置、自定义ks文件、安装deb包系的路要进一步走下去。

在搜索中看到WDS也是可以支持Linux引导的;看来cobbler并非唯一的选择;对于企业内部有AD或者Windows服务器多于Linux的话,将是个好的选择。