来,搭建一个DHCP服务器和PXE吧

DHCP服务器建立起来特别简单啦, 就当放松心情来搭建一个吧! 另外 这一次顺便来看看神奇的网络引导究竟是怎么实现的~

DHCP

都到这个时候了, DHCP都在熟悉不过了, 不过还是简单的说一说吧, 以后自己看的时候也能顺便回忆一波~

DHCP的全称是Dynamic Host Configure Protocol. 即为动态主机配置协议. 我们不可能手动配置局域网内每一台机器的网络属性, 所以, 这里就需要一个专门的东西来分发这些.

需要特别说一下的是, DHCP绝对不是为主机分配IP地址的协议, 他分配的是网络属性, 最重要的几个属性是:

  • IP/Netmask
  • Gateway
  • DNS Server

除此之外还有很多, 但一般使用到的就是上面这些.

那么DHCP是如何工作的呢?

DHCP协议的前身是Bootp协议, 也就是bootstrap protocol. 这些协议存在很久远了, 那个时候硬盘较小且昂贵, 所以不能为每一个工作站都配置上一块硬盘, 也就是说没有操作系统 这个时候, 就会有一台网络上的主机(服务器). 这个服务器为每一个工作站提供一个共享的磁盘空间. 也就是说这些主机的操作系统都安装在他们自己的共享空间中. 像这样是存在问题的. 你能想到吗?

对了, 没有操作系统, 怎么会有IP地址? 没有地址, 如何通信?

我们没有IP地址, 但是我们有MAC地址啊. 这个场景中就需要RARP协议的援助(当然现在RARP已经淘汰了), 在本地主机开机启动时, 我们的网卡就会发送一个RARP协议的广播报文, 当请求发送到服务器时, bootp协议就会开始工作. 他会根据MAC地址, 从自己维护的一个特定范围的地址池中取一个交给本地主机. 从而获得IP地址, 得以通信. 接着就会加载操作系统了.

但是这样, 就又会存在一个问题了. 那就是每当我分配了一个IP地址, 这个IP地址就只能给这一台主机使用了, 为什么? 因为操作系统啊, 自己只能使用自己的操作系统啊. 所以这个IP是和操作系统绑定的.

后来硬盘变得越来越廉价, 所以这些都成为历史. 现在无盘工作站已经越来越少了.

不仅如此, 我们局域网中的机器也越来越多了, 有的时候总数量会超过我们可分配的地址范围, 那怎么办? 没关系, 只要保证在同一时间不会出现所有主机上线的情况就可以了. 这样bootp协议进行了升级, 也就是现在的DHCP协议.

DHCP协议无非就是引入了一个新的租期(租约)的概念. 主机被分配的地址是有使用期限的. 一般是2Hours, 而每次经过50%的时间, 客户端就会进行续租操作 也就是1hour的时候, 重新变成了2hours.

DHCP的流程也是很简单了, 我就以一个wireshark的包来做个展示吧:

dhcptest

过程共有4步, 从抓包的结果来看, 似乎每一次都是广播报文.

接下来再说一个有用的技术, 叫做DHCP中继. 因为我们已经知道, 每一个DHCP报文都是广播报文, 但是路由器偏偏又是隔离广播域的一道天然屏障, 这样就没法跨路由器访问DHCP服务器了.

所以为了能够访问到另一网络的DHCP服务器, 我们需要路由器将我们的广播请求转换成为单播.

就是这样, 接下来看看我们的Linux时候怎么成为一台DHCP服务器的吧, 需要的软件就是dhcp这个名字了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
[root@localhost ~]# yum info dhcp
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
* base: mirrors.cn99.com
* extras: mirrors.cn99.com
* updates: mirrors.cn99.com
Available Packages
Name : dhcp
Arch : x86_64
Epoch : 12
Version : 4.1.1
Release : 53.P1.el6.centos.1
Size : 823 k
Repo : updates
Summary : Dynamic host configuration protocol software
URL : http://isc.org/products/DHCP/
License : ISC
Description : DHCP (Dynamic Host Configuration Protocol) is a protocol which allows
: individual devices on an IP network to get their own network
: configuration information (IP address, subnetmask, broadcast address,
: etc.) from a DHCP server. The overall purpose of DHCP is to make it
: easier to administer a large network. The dhcp package includes the
: ISC DHCP service and relay agent.
:
: To use DHCP on your network, install a DHCP service (or relay agent),
: and on clients run a DHCP client daemon. The dhcp package provides
: the ISC DHCP service and relay agent.

我们把它安装一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[root@localhost ~]# rpm -ql dhcp
/etc/dhcp
/etc/dhcp/dhcpd.conf
/etc/dhcp/dhcpd6.conf
/etc/openldap/schema/dhcp.schema
/etc/portreserve/dhcpd
/etc/rc.d/init.d/dhcpd
/etc/rc.d/init.d/dhcpd6
/etc/rc.d/init.d/dhcrelay
/etc/rc.d/init.d/dhcrelay6
/etc/sysconfig/dhcpd
/etc/sysconfig/dhcpd6
/etc/sysconfig/dhcrelay
/etc/sysconfig/dhcrelay6
/usr/bin/omshell
/usr/sbin/dhcpd
/usr/sbin/dhcrelay
...(omitted)
/var/lib/dhcpd
/var/lib/dhcpd/dhcpd.leases
/var/lib/dhcpd/dhcpd6.leases

这是在CentOS6上的rpm包安装的文件, 显然存在两个daemon, 而且他们是不能同时启动的, 因为一个是做DHCP的, 一个是做DHCP中继的, 怎么可能同时跑呢.

而且DHCP对IPv4和IPv6都有不同的配置.

这个dhcp是一个重量级DHCP服务器程序, 而由一个非常轻量的程序也可以做到, 就是dnsmasq 听名字也可以看出来, 这个玩意还可以用来作为DNS服务器来搞, 配置很方便, 而且十分简单轻量. 但是这一次就先不说这个了, 还是来看看dhcp的使用.

配置文件默认是空的, 但是它提供了一个配置模板, 我们复制过来看一下吧:

1
2
[root@localhost ~]# cp -av /usr/share/doc/dhcp-4.1.1/dhcpd.conf.sample  /etc/dhcp/
`/usr/share/doc/dhcp-4.1.1/dhcpd.conf.sample' -> `/etc/dhcp/dhcpd.conf.sample'

不同版本的内核, 可能dhcp程序的版本也不一致.

1
2
option domain-name "example.org";
option domain-name-servers ns1.example.org, ns2.example.org;

这就是在声明搜索域和DNS服务器啦, 当然使用的时候我们要改成IP才行.

1
2
default-lease-time 600;
max-lease-time 7200;

这就是两个常用的关于租期的全局属性. 而一个内网的配置是这样的: (或者说作用域)

1
2
3
4
5
6
7
8
9
subnet 10.5.5.0 netmask 255.255.255.224 {
range 10.5.5.26 10.5.5.30;
option domain-name-servers ns1.internal.example.org;
option domain-name "internal.example.org";
option routers 10.5.5.1;
option broadcast-address 10.5.5.31;
default-lease-time 600;
max-lease-time 7200;
}

其中有很多option 这些都是可选项, 另外你发现在这个配置中还有之前说的关于租期的设置, 也就是说, 声明在外面的属性就对所有的subnet有效, 但是优先使用自己子网的配置项~

除了subnet, 还有一种叫做host, 这个可以看作是保留的地址, 粗暴的说就是VIP地址, 仅仅分配给一台特定的主机.

现在就来设置一下, 由于本机处于192.168.56.0/24网络中, 所以就这样写:

1
2
3
subnet 192.168.56.0 netmask 255.255.255.0 {
range 192.168.56.10 192.168.56.20;
}

这就行了. 后面全部注释掉:

1
:.,$s/^[^#]/#/

行了, 现在就开启服务吧.

1
2
3
4
[root@localhost ~]# netstat -anup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 0.0.0.0:67 0.0.0.0:* 1159/dhcpd

监听在UDP的67号端口上.

那么现在开启另外一台主机, 使用dhclient来强行通过这个来获得这个DHCP服务器分配的IP.

在DHCP服务器上可以查看到日志:

1
2
3
4
5
6
7
8
Oct  8 13:53:21 node1 dhcpd: DHCPDISCOVER from 00:0c:29:a7:00:c1 via eth0
Oct 8 13:53:21 node1 dhcpd: DHCPDISCOVER from 00:0c:29:a7:00:cb via eth0
Oct 8 13:53:22 node1 dhcpd: DHCPOFFER on 192.168.230.100 to 00:0c:29:a7:00:c1 via eth0
Oct 8 13:53:22 node1 dhcpd: DHCPOFFER on 192.168.230.135 to 00:0c:29:a7:00:cb via eth0
Oct 8 13:53:22 node1 dhcpd: DHCPREQUEST for 192.168.230.100 (192.168.230.133) from 00:0c:29:a7:00:c1 via eth0
Oct 8 13:53:22 node1 dhcpd: DHCPACK on 192.168.230.100 to 00:0c:29:a7:00:c1 via eth0
Oct 8 13:53:22 node1 dhcpd: DHCPREQUEST for 192.168.230.135 (192.168.230.133) from 00:0c:29:a7:00:cb via eth0
Oct 8 13:53:22 node1 dhcpd: DHCPACK on 192.168.230.135 to 00:0c:29:a7:00:cb via eth0

那么我怎么知道现在地址池分配的情况呢? 在/var/lib/dhcpd/dhcpd.leases. 这个文件中记录了当前租出去的IP情况, 例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
lease 192.168.230.100 {
starts 0 2017/10/08 05:53:22;
ends 0 2017/10/08 07:33:22;
cltt 0 2017/10/08 05:53:22;
binding state active;
next binding state free;
hardware ethernet 00:0c:29:a7:00:c1;
}
lease 192.168.230.135 {
starts 0 2017/10/08 05:53:22;
ends 0 2017/10/08 07:33:22;
cltt 0 2017/10/08 05:53:22;
binding state active;
next binding state free;
hardware ethernet 00:0c:29:a7:00:cb;
}

同时, 回到客户端, 我们会发现他的resolve.conf文件内容也是重新生成的:

1
2
3
4
5
[root@localhost ~]# cat /etc/resolv.conf 
# Generated by NetworkManager
domain example.org
search example.org
nameserver 192.168.230.132

OK, 现在我们就沿着dhcp来说说PXE网络引导的相关.

PXE

在dhcp的配置选项中, 有两个配置选项分别叫做:

  • filename: 指明引导文件的名称
  • next-server: 提供引导文件的服务器的IP地址.

通过配置这个就可以实现网络引导服务器的搭建, 除了这个, filename之所以说是名称而不说是路径, 是因为这个服务器同时是一台tftp服务器, 也就是说一般这个文件都放在tftp的根目录下. 所以才说是名称的.

tftp我们之前也说过的, 即 简单文件传输协议( Trivial File Transfer Protocol ). 我们来看一下介绍:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node1 ~]# yum info tftp-server
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
Available Packages
Name : tftp-server
Arch : x86_64
Version : 0.49
Release : 8.el6
Size : 39 k
Repo : base
Summary : The server for the Trivial File Transfer Protocol (TFTP)
URL : http://www.kernel.org/pub/software/network/tftp/
License : BSD
Description : The Trivial File Transfer Protocol (TFTP) is normally used only for
: booting diskless workstations. The tftp-server package provides the
: server for TFTP, which allows users to transfer files to and from a
: remote machine. TFTP provides very little security, and should not be
: enabled unless it is expressly needed. The TFTP server is run from
: /etc/xinetd.d/tftp, and is disabled by default.

安装完成了之后是这样的:

1
2
3
4
5
6
7
8
9
10
11
[root@node1 ~]# rpm -ql tftp-server
/etc/xinetd.d/tftp
/usr/sbin/in.tftpd
/usr/share/doc/tftp-server-0.49
/usr/share/doc/tftp-server-0.49/CHANGES
/usr/share/doc/tftp-server-0.49/README
/usr/share/doc/tftp-server-0.49/README.security
/usr/share/doc/tftp-server-0.49/README.security.tftpboot
/usr/share/man/man8/in.tftpd.8.gz
/usr/share/man/man8/tftpd.8.gz
/var/lib/tftpboot

很简单, 依靠xinetd来运行.

首先在配置文件中将disable改为no 接着启动xinetd服务即可:

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@node1 ~]# vim /etc/xinetd.d/tftp 
[root@node1 ~]# service xinetd restart
Stopping xinetd: [ OK ]
Starting xinetd: [ OK ]
[root@node1 ~]# netstat -anup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 192.168.230.133:39950 192.168.230.1:53 ESTABLISHED 1573/ManagementAgen
udp 0 0 0.0.0.0:67 0.0.0.0:* 2572/dhcpd
udp 0 0 0.0.0.0:68 0.0.0.0:* 1794/dhclient
udp 0 0 0.0.0.0:68 0.0.0.0:* 1796/dhclient
udp 0 0 0.0.0.0:69 0.0.0.0:* 3350/xinetd
...(omitted)

接下来找一台主机安装tftp就行了, 使用方法不需要说什么, 因为实在是太简单了.

有了这些铺垫, 我们就可以着手来搞一个PXE启动服务器了.

首先还是先从PXE说起, 什么是PXE呢, PXE的全称是Preboot eXecute Environment. 他需要之前说的DHCP, tftp以及一个file server(yum repo)的帮助.

首先为了能够达成引导的目的, 我们需要一个

这个在syslinux包中有提供:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@node1 ~]# yum info syslinux
Loaded plugins: fastestmirror, refresh-packagekit, security
Loading mirror speeds from cached hostfile
Installed Packages
Name : syslinux
Arch : x86_64
Version : 4.02
Release : 4.el6
Size : 2.0 M
Repo : installed
From repo : base
Summary : Simple kernel loader which boots from a FAT filesystem
URL : http://syslinux.zytor.com/wiki/index.php/The_Syslinux_Project
License : GPLv2+
Description : SYSLINUX is a suite of bootloaders, currently supporting DOS FAT
: filesystems, Linux ext2/ext3 filesystems (EXTLINUX), PXE network boots
: (PXELINUX), or ISO 9660 CD-ROMs (ISOLINUX). It also includes a tool,
: MEMDISK, which loads legacy operating systems from these media.

它包含了一大堆引导程序, 支持各种文件系统, 网络, 光盘等等. 这里面由一个叫做pxelinux.0的文件我们会用到:

1
/usr/share/syslinux/pxelinux.0

现在 就来配置一下我们的DHCP服务器吧:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@node1 ~]# cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
[root@node1 ~]# rm -rf /var/lib/tftpboot/fstab
[root@node1 ~]# mount /dev/cdrom1 /media/
mount: block device /dev/sr0 is write-protected, mounting read-only
[root@node1 ~]# cp -av /media/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/
`/media/images/pxeboot/vmlinuz' -> `/var/lib/tftpboot/vmlinuz'
`/media/images/pxeboot/initrd.img' -> `/var/lib/tftpboot/initrd.img'
[root@node1 ~]# cd /media/isolinux/
[root@node1 isolinux]# cp -av boot.cat vesamenu.c32 splash.jpg /var/lib/tftpboot/
`boot.cat' -> `/var/lib/tftpboot/boot.cat'
`vesamenu.c32' -> `/var/lib/tftpboot/vesamenu.c32'
`splash.jpg' -> `/var/lib/tftpboot/splash.jpg'
[root@node1 isolinux]# mkdir /var/lib/tftpboot/pxelinux.cfg
[root@node1 isolinux]# cp isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/default

接下来就可以修改DHCP配置文件了:

1
2
3
4
5
6
subnet 192.168.230.0 netmask 255.255.255.0 {
range 192.168.230.100 192.168.230.200;
option routers 192.168.230.1;
filename "pxelinux.0";
next-server 192.168.230.133;
}

这样重启服务之后, 新建一个虚拟机

确保使用同一网络之后, 就会看到激动人心的画面:

pxe

接着就神奇的进入了:
CentOS6

怎么样, 是不是很有趣. 等到加载完vmlinuz和initrd.img时候就可以进行安装了:
installC6

这是CentOS6的安装流程.

总结

过程总结如下:

1
2
3
4
5
6
7
8
CentOS 6 PXE: 
yum -y install syslinux tftp-server

cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
cp /media/cdrom/images/pxelinux/{vmlinuz,initrd.img} /var/lib/tftp/boot/
cp /media/cdrom/isolinux/{boot.cfg,vesamenu.c32,splash.png} /var/lib/tftp/boot/
mkdir /var/lib/tftpboot/pxelinux.cfg/
cp /media/cdrom/isolinux/isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/default/

如果是CentOS7, 过程和C6不太一样, 但大体相同:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
CentOS 7 PXE:
yum -y install syslinux tftp-server

cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/
cp /media/cdrom/images/pxelinux/{vmlinuz,initrd.img} /var/lib/tftp/boot/
cp /usr/share/syslinux/{chain.c32,mboot.c32,menu.c32,memdisk} /var/lib/tftpboot/
mkdir /var/lib/tftpboot/pxelinux.cfg/

创建/var/lib/tftpboot/pxelinux.cfg/default
内容类似如下:
default menu.c32
prompt 5
timeout 30
MENU TITLE CentOS 7 PXE Menu

LABEL linux
MENU LABEL Install CentOS 7 x86_64
KERNEL vmlinuz
APPEND initrd=initrd.img inst.repo=http://YUM_IP/centos7 ks=http://KS_IP/centos7.cfg

Cobbler的实现

我们在上面已经实现了一个简单的PXE网络引导环境, 那么现在说的Cobbler又是个什么东西呢? 实际上, 这是一个对PXE的更高级封装, 包括了KS, YUM等等一统之下的系统集中部署的环境.

这个玩意是使用Python实现的, 十分小巧. 我们来看一下他的架构和一些名词:

Cobbler_first.png

这里最重要的部分就是Profile了, 我们在上面都知道较完整的一个网络引导起码需要vmlinuz + initrd.img, YUM repo, KS文件等等. 而不同的发行版是需要不同的, 或者说对应版本的vmlinuz, initrd.img的, 我们不能将非对应版本的这些扔到一块去.

所以Cobbler就把他们集合在一起而组成了一个个Profile, 例如我们可以制定这样的Profile:

用于Web的CentOS6: (CentOS6的)vmlinuz+initrd.img+kickstart_web+CentOS6的yum repo

用于数据库的CentOS7: (CentOS7的)vmlinuz+initrd.img+kickstart_db+CentOS7的yum repo

等等.

所以我们还是关注Cobbler的三个核心组件:

  • repository
    • mirror: 指向一个yum源
    • import: 导入一个yum源
  • distribution: cobbler可以从上面的repo中, 根据你的dist自动的抽出需要的文件.
  • Profile: 用户编写产生

过程变得这么简单, 所以才说连修鞋匠都会使用. 接下来我们就来安装看一下:

1
2
3
4
5
6
7
8
9
10
[root@master ~]# yum list epel cobbler*
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.sohu.com
* epel: mirrors.ustc.edu.cn
* extras: mirrors.cn99.com
* updates: mirrors.cn99.com
Available Packages
cobbler.x86_64 2.6.11-1.el6 epel
cobbler-web.noarch 2.6.11-1.el6 epel

两个软件包, 其中第二个是他的GUI接口, cobbler所有的功能都可以在他的命令行接口上实现, 所以直接安装第一个就行了.

这样来执行安装步骤:

1
yum install cobbler pykickstart syslinux debmirror dhcp tftp-server

接着我们确保cobblerd服务启动, tftp-server服务启动, 为了防止出现问题, 我们事先把TFTProot中的文件删除到后者挪到别的地方. 而且把dhcp服务的配置文件中的next-server注释掉.

接着就可以开始启动服务了:

1
2
3
4
[root@master ~]# systemctl start httpd
[root@master ~]# systemctl start tftp
[root@master ~]# systemctl start dhcpd
[root@master ~]# systemctl start cobblerd

在cobbler的配置文件/etc/cobbler/settings中找到server这一行, 将他的地址改成是其他主机可以发现的IP地址, 接着重启服务, 来执行check子命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master ~]# cobbler check
The following are potential configuration items that you may want to fix:

1 : For PXE to be functional, the 'next_server' field in /etc/cobbler/settings must be set to something other than 127.0.0.1, and should match the IP of the boot server on the PXE network.
2 : SELinux is enabled. Please review the following wiki page for details on ensuring cobbler works correctly in your SELinux environment:
https://github.com/cobbler/cobbler/wiki/Selinux
3 : change 'disable' to 'no' in /etc/xinetd.d/tftp
4 : 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.
5 : enable and start rsyncd.service with systemctl
6 : comment out 'dists' on /etc/debmirror.conf for proper debian support
7 : comment out 'arches' on /etc/debmirror.conf for proper debian support
8 : The default password used by the sample templates for newly installed machines (default_password_crypted in /etc/cobbler/settings) is still set to 'cobbler' and should be changed, try: "openssl passwd -1 -salt 'random-phrase-here' 'your-password-here'" to generate new one
9 : 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.

我们就根据他的提示来一步一步的看吧! 首先第一个, 我们需要在配置文件中指定next_server的地址. 接着第二个可以忽略, 我们先把SELINUX关闭就行了. 下一个, 我们可以通过chkconfig来执行, 或者直接修改配置文件. 第4个, 我们已经安装好了syslinux, 所以也没关系了. 第5个, 直接就启动和设置开机启动rsync服务就可以了. 接着下面两个都是为提供Debian系的支持, 按照他说的注释掉就行了. 接着第8个, 我们重新生成一个密码放到setting中, 使用openssl来做就行. 最后一个由于我们不需要STONITH设备 所以暂时忽略掉.

你的check不一定和我的完全一样, 所以还是要根据具体的输出来执行和解决.

执行之后我们就可以进行同步操作了, 来执行一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[root@master ~]# cobbler sync
task started: 2017-12-11_201043_sync
task started (id=Sync, time=Mon Dec 11 20:10:43 2017)
running pre-sync triggers
cleaning trees
mkdir: /var/lib/tftpboot/pxelinux.cfg
mkdir: /var/lib/tftpboot/grub
mkdir: /var/lib/tftpboot/images
mkdir: /var/lib/tftpboot/s390x
mkdir: /var/lib/tftpboot/ppc
mkdir: /var/lib/tftpboot/etc
removing: /var/lib/tftpboot/grub/images
copying bootloaders
trying hardlink /usr/share/syslinux/pxelinux.0 -> /var/lib/tftpboot/pxelinux.0
trying hardlink /usr/share/syslinux/menu.c32 -> /var/lib/tftpboot/menu.c32
trying hardlink /usr/share/syslinux/memdisk -> /var/lib/tftpboot/memdisk
copying distros to tftpboot
copying images
generating PXE configuration files
generating PXE menu structure
rendering TFTPD files
generating /etc/xinetd.d/tftp
cleaning link caches
running post-sync triggers
running python triggers from /var/lib/cobbler/triggers/sync/post/*
running python trigger cobbler.modules.sync_post_restart_services
running shell triggers from /var/lib/cobbler/triggers/sync/post/*
running python triggers from /var/lib/cobbler/triggers/change/*
running python trigger cobbler.modules.scm_track
running shell triggers from /var/lib/cobbler/triggers/change/*
*** TASK COMPLETE ***
[root@master ~]# tree /var/lib/tftpboot/
/var/lib/tftpboot/
├── boot
│   └── grub
│   └── menu.lst
├── etc
├── grub
│   ├── efidefault
│   └── images -> ../images
├── images
├── memdisk
├── menu.c32
├── ppc
├── pxelinux.0
├── pxelinux.cfg
│   └── default
└── s390x
└── profile_list

9 directories, 7 files
[root@master ~]#

看吧, Cobbler已经帮助我们把文件丢进去了.

接下来, 我们就可以继续了, 创建一个repo. 这里我们选择导入(import)的方式, 通过挂载光盘来使得Cobbler自动建立文件树:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
[root@master ~]# cobbler import --name=CentOS7_x86_64 --path=/media/
task started: 2017-12-11_203518_import
task started (id=Media import, time=Mon Dec 11 20:35:18 2017)
Found a candidate signature: breed=redhat, version=rhel6
Found a candidate signature: breed=redhat, version=rhel7
Found a matching signature: breed=redhat, version=rhel7
Adding distros from path /var/www/cobbler/ks_mirror/CentOS7_x86_64:
creating new distro: CentOS7-x86_64
trying symlink: /var/www/cobbler/ks_mirror/CentOS7_x86_64 -> /var/www/cobbler/links/CentOS7-x86_64
creating new profile: CentOS7-x86_64
associating repos
checking for rsync repo(s)
checking for rhn repo(s)
checking for yum repo(s)
starting descent into /var/www/cobbler/ks_mirror/CentOS7_x86_64 for CentOS7-x86_64
processing repo at : /var/www/cobbler/ks_mirror/CentOS7_x86_64
need to process repo/comps: /var/www/cobbler/ks_mirror/CentOS7_x86_64
looking for /var/www/cobbler/ks_mirror/CentOS7_x86_64/repodata/*comps*.xml
Keeping repodata as-is :/var/www/cobbler/ks_mirror/CentOS7_x86_64/repodata
*** TASK COMPLETE ***
[root@master ~]# cd /var/www/
[root@master www]# ls
cgi-bin cobbler html
[root@master www]# cd /etc/httpd/conf.d/
[root@master conf.d]# ls
autoindex.conf cobbler.conf README userdir.conf welcome.conf
[root@master conf.d]# head cobbler.conf
# This configuration file allows cobbler data
# to be accessed over HTTP.

AliasMatch ^/cblr(?!/svc/)(.*)?$ "/var/www/cobbler$1"
AliasMatch ^/cobbler_track(.*)?$ "/var/www/cobbler$1"
#AliasMatch ^/cobbler(.*)?$ "/var/www/cobbler$1"
Alias /cobbler /var/www/cobbler
Alias /cobbler_webui_content /var/www/cobbler_webui_content

WSGIScriptAliasMatch ^/cblr/svc/([^/]*) /var/www/cobbler/svc/services.py

我们能看到, Cobbler已经构建了一个YUM源, 并且在httpd的配置文件中定制了别名, 我们现在已经可以访问到看看了.

ks_mirror.png

接着再次执行一次同步:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
[root@master ~]# cobbler sync
task started: 2017-12-11_203756_sync
task started (id=Sync, time=Mon Dec 11 20:37:56 2017)
running pre-sync triggers
cleaning trees
removing: /var/www/cobbler/images/CentOS7-x86_64
removing: /var/lib/tftpboot/pxelinux.cfg/default
removing: /var/lib/tftpboot/grub/images
removing: /var/lib/tftpboot/grub/efidefault
removing: /var/lib/tftpboot/images/CentOS7-x86_64
removing: /var/lib/tftpboot/s390x/profile_list
copying bootloaders
copying distros to tftpboot
copying files for distro: CentOS7-x86_64
trying hardlink /var/www/cobbler/ks_mirror/CentOS7_x86_64/images/pxeboot/vmlinuz -> /var/lib/tftpboot/images/CentOS7-x86_64/vmlinuz
trying hardlink /var/www/cobbler/ks_mirror/CentOS7_x86_64/images/pxeboot/initrd.img -> /var/lib/tftpboot/images/CentOS7-x86_64/initrd.img
copying images
generating PXE configuration files
generating PXE menu structure
copying files for distro: CentOS7-x86_64
trying hardlink /var/www/cobbler/ks_mirror/CentOS7_x86_64/images/pxeboot/vmlinuz -> /var/www/cobbler/images/CentOS7-x86_64/vmlinuz
trying hardlink /var/www/cobbler/ks_mirror/CentOS7_x86_64/images/pxeboot/initrd.img -> /var/www/cobbler/images/CentOS7-x86_64/initrd.img
Writing template files for CentOS7-x86_64
rendering TFTPD files
generating /etc/xinetd.d/tftp
processing boot_files for distro: CentOS7-x86_64
cleaning link caches
running post-sync triggers
running python triggers from /var/lib/cobbler/triggers/sync/post/*
running python trigger cobbler.modules.sync_post_restart_services
running shell triggers from /var/lib/cobbler/triggers/sync/post/*
running python triggers from /var/lib/cobbler/triggers/change/*
running python trigger cobbler.modules.scm_track
running shell triggers from /var/lib/cobbler/triggers/change/*
*** TASK COMPLETE ***

接着我们重新打开另外一台主机. 就可以看到下面的画面:

cobbler_first_run.png

但是这显然不够, 我们想要达成无人值守的自动化安装, 就需要kickstart文件的帮助.

脱坑指南, 如果说你在这个时候尝试进入安装的时候出现了故障:

dracut-initqueue: curl: (23) Failed writing body (11904 != 16384)
loop: module loaded
dracut-initqueue[579]: mount: wrong fs type, bad option, bad superblock on /dev/loop0
dracut-initqueue[579]: missing codepage or helper program, or other error
dracut-initqueue[579]: In some cases useful info is found in syslog - try
dracut-initqueue[579]: dmesg | tail or so.
dracut-initqueue[579]:Mumount: /run/initramfs/squashfs: not mounted
dracut-initqueue[579]: /sbin/dmsquash-lice-root: line 273: printf: write error: No space left on device

img

那么这个时候考虑升级内存, 起码要2G.

关于Kickstart文件的内容以及语法, 就参考红帽官方的文档就好: KICKSTART 语法参考

我给出的一个小样例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#version=DEVEL
firewall --disabled
# System authorization information
auth --enableshadow --passalgo=sha512
text
# Network installation
url --url="http://192.168.224.128/cobbler/ks_mirror/CentOS7_x86_64/"
# Keyboard layouts
keyboard --vckeymap=us --xlayouts='us'
# System language
lang en_US.UTF-8
# Root password
rootpw --iscrypted $6$VyQYHVcM4r7uDUwN$e1wqoecztBT05bXGiHE5p5rR4siqHstjlz6Hbpuav/xUG0NqzC8Hrn478skCplkCtL0KJhQgue4G0CgKDBSkW0

firstboot --disable
selinux --disable
zerombr
# System timezone
timezone Asia/Shanghai
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda

clearpart --all
# Partition
part /boot --fstype="ext4" --size=200
part / --fstype="xfs" --size=19456
logging --level=info

%packages
@^minimal
@core
net-tools
chrony
kexec-tools
%end

%post --interpreter=/bin/bash

/bin/hostname agent
/usr/bin/cat "HOSTNAME agent" >> /etc/sysconfig/network

%end

但是好像有问题…hostname的修改没有生效..

总之生成了这个文件之后我们就可以去改变profile的行为了,

1
2
cobbler profile edit --name=CentOS7-x86_64 --kickstart=%你的kickstart文件路径%
cobbler sync

接着我们重启机器就可以享受无人值守的PXE自动安装了