运维工作纵向来看主要分为三个方向:
-
1.BootStraping:主要做的是操作系统的安装与配置,包括Bare Metal(pxe,cobbler)和Virtual Machine(image files)。
-
2.Configuration:主要使用运维工具如puppet(rubby研发)、saltstack(python研发)、ansible、chef、cfengine等自动化运维工具做应用程序做批量部署与配置。
-
3.Command and Conrol:主要使用自动化运维工具发送命令或指令实现对操作系统或者应用程序操纵或者控制。
我们今天主要探讨下第一个方向,通过PXE,结合DHCP,以及TFTP等技术实现自动化的Bootstraping。
一、简介
1.1 什么是PXE
PXE(Pre-boot Execution Environment,预启动执行环境)是由Intel公司开发的最新技术,工作于Client/Server的网络模式,支持工作站通过网络从远端服务器下载映像,并由此支持通过网络启动操作系统,在启动过程中,终端要求服务器分配IP地址,再用TFTP(trivial file transfer protocol)或MTFTP(multicast trivial file transfer protocol)协议下载一个启动软件包到本机内存中执行,由这个启动软件包完成终端基本软件设置,从而引导预先安装在服务器中的终端操作系统。
严格来说,PXE 并不是一种安装方式,而是一种引导方式。进行 PXE 安装的必要条件是在要安装的计算机中必须包含一个 PXE 支持的网卡(NIC),即网卡中必须要有 PXE Client。PXE 协议可以使计算机通过网络启动。此协议分为 Client端和 Server 端,而PXE Client则在网卡的 ROM 中。当计算机引导时,BIOS 把 PXE Client 调入内存中执行,然后由 PXE Client 将放置在远端的文件通过网络下载到本地运行。运行 PXE 协议需要设置 DHCP 服务器和 TFTP 服务器。DHCP 服务器会给 PXE Client(将要安装系统的主机)分配一个 IP 地址,由于是给 PXE Client 分配 IP 地址,所以在配置 DHCP 服务器时需要增加相应的 PXE 设置。此外,在 PXE Client 的 ROM 中,已经存在了 TFTP Client,那么它就可以通过 TFTP 协议到 TFTP Server 上下载所需的文件了。
PXE的工作过程:
-
PXE Client 从自己的PXE网卡启动,向本网络中的DHCP服务器索取IP;
-
DHCP 服务器返回分配给客户机的IP 以及PXE文件的放置位置(该文件一般是放在一台TFTP服务器上) ;
-
PXE Client 向本网络中的TFTP服务器索取pxelinux.0 文件;
-
PXE Client 取得pxelinux.0 文件后之执行该文件;
-
根据pxelinux.0 的执行结果,通过TFTP服务器加载内核和文件系统 ;
-
进入安装画面, 此时可以通过选择HTTP、FTP、NFS 方式之一进行安装;
详细工作流程,请参考下面这幅图:
1.2 什么是Kickstart
Kickstart是一种无人值守的安装方式。它的工作原理是在安装过程中记录典型的需要人工干预填写的各种参数,并生成一个名为ks.cfg的文件。如果在安装过程中(不只局限于生成Kickstart安装文件的机器)出现要填写参数的情况,安装程序首先会去查找Kickstart生成的文件,如果找到合适的参数,就采用所找到的参数;如果没有找到合适的参数,便需要安装者手工干预了。所以,如果Kickstart文件涵盖了安装过程中可能出现的所有需要填写的参数,那么安装者完全可以只告诉安装程序从何处取ks.cfg文件,然后就去忙自己的事情。等安装完毕,安装程序会根据ks.cfg中的设置重启系统,并结束安装。
PXE+Kickstart 无人值守安装操作系统完整过程如下:
1.3 什么是DHCP
动态主机设置协议(Dynamic Host Configuration Protocol,DHCP)是一个局域网的网络协议,使用UDP协议工作,主要有两个用途:
用于内部网络或网络服务供应商自动分配IP地址给用户 用于内部网络管理员作为对所有电脑作中央管理的手段
DHCP工作原理:
一、DHCP客户机初始化:
1. 寻找DHCP Server。
当DHCP客户机第一次登录网络的时候(也就是客户机上没有任何IP地址数据时),它会通过UDP 67端口向网络上发出一个DHCPDISCOVER数据包(包中包含客户机的MAC地址和计算机名等信息)。因为客户机还不知道自己属于哪一个网络,所以封包的源地址为0.0.0.0,目标地址为255.255.255.255,然后再附上DHCP discover的信息,向网络进行广播。DHCP discover的等待时间预设为1秒,也就是当客户机将第一个DHCP discover封包送出去之后,在1秒之内没有得到回应的话,就会进行第二次DHCP discover广播。若一直没有得到回应,客户机会将这一广播包重新发送四次(以2,4,8,16秒为间隔,加上1-1000毫秒之间随机长度的时间)。如果都没有得到DHCP Server的回应,客户机会从169.254.0.0/16这个自动保留的私有IP地址中选用一个IP地址。并且每隔5分钟重新广播一次,如果收到某个服务器的响应,则继续IP租用过程。
2. 提供IP地址租用
当DHCP Server监听到客户机发出的DHCP discover广播后,它会从那些还没有租出去的地址中,选择最前面的空置IP,连同其它TCP/IP设定,通过UDP 68端口响应给客户机一个DHCP OFFER数据包(包中包含IP地址、子网掩码、地址租期等信息)。此时还是使用广播进行通讯,源IP地址为DHCP Server的IP地址,目标地址255.255.255.255。同时,DHCP Server为此客户保留它提供的IP地址,从而不会为其他DHCP客户分配此IP地址。由于客户机在开始的时候还没有IP地址,所以在其DHCP discover封包内会带有其MAC地址信息,并且有一个XID编号来辨别该封包,DHCP Server响应的DHCP OFFER封包则会根据这些资料传递给要求租约的客户。
3. 接受IP租约
如果客户机收到网络上多台DHCP服务器的响应,只会挑选其中一个DHCP OFFER(一般是最先到达的那个),并且会向网络发送一个DHCP REQUEST广播数据包(包中包含客户端的MAC地址、接受的租约中的IP地址、提供此租约的DHCP服务器地址等),告诉所有DHCP Server它将接受哪一台服务器提供的IP地址,所有其他的DHCP服务器撤销它们的提供以便将IP地址提供给下一次IP租用请求。此时,由于还没有得到DHCP Server的最后确认,客户端仍然使用0.0.0.0为源IP地址255.255.255.255为目标地址进行广播。事实上,并不是所有DHCP客户机都会无条件接受DHCP Server的OFFER,特别是如果这些主机上安装有其它TCP/IP相关的客户机软件。客户机也可以用DHCP REQUEST向服务器提出DHCP选择,这些选择会以不同的号码填写在DHCP Option Field里面。客户机可以保留自己的一些TCP/IP设定。
4. 租约确认
当DHCP Server接收到客户机的DHCP REQUEST之后,会广播返回给客户机一个DHCP ACK消息包,表已经接受客户机的选择,并将这一IP地址的合法租用以及其他的配置信息都放入该广播包发给客户机。客户机在接收到DHCP ACK广播后,会向网络发送三个针对此IP地址的ARP解析请求以执行冲突检测,查询网络上有没有其它机器使用该IP地址;如果发现该IP地址已经被使用,客户机会发出一个DHCP DECLINE数据包给DHCP Server,拒绝此IP地址租约,并重新发送DHCP discover信息。此时,在DHCP服务器管理控制台中,会显示此IP地址为BAD_ADDRESS。如果网络上没有其它主机使用此IP地址,则客户机TCP/IP使用租约中提供的IP地址完成初始化,从而可以和其他网络中的主机进行通讯。
二、DHCP客户机租期���约:
客户机会在租期过去50%的时候,直接向为其提供IP地址的DHCP Server发送DHCP REQUEST消息包。如果客户机接收到该服务器回应的DHCP ACK消息包,客户机就根据包中所提供的新的租期以及其它已经更新的TCP/IP参数,更新自己的配置,IP租用更新完成。如果没有收到该服务器的回复,则客户机继续使用现有的IP地址,因为当前租期还有50%。如果在租期过去50%的时候没有更新,则客户机将在租期过去87.5%的时候再次向为其提供IP地址的DHCP联系。如果还不成功,到租约的100%时候,客户机必须放弃这个IP地址,重新申请。如果此时无DHCP可用,客户机会使用169.254.0.0/16中随机的一个地址,并且每隔5分钟再进行尝试。
Schema of a typical DHCP session:
1.4 什么是TFTP
目的:
TFTP是一个传输文件的简单协议,通常使用UDP(监听在UDP/69端口)协议而实现,但tftp并没有要求实现的具体协议,在特殊需求的场合可以同tcp实现。此协议设计的时候是进行小文件传输的。因此它不具备通常的FTP的许多功能,它只能从文件服务器上获得或写入文件,不能列出目录,不进行认证,它传输8位数据。传输中有三种模式:netascii,这是8位的ASCII码形式,另一种是octet,这是8位源数据类型;最后一种mail已经不再支持,它将返回的数据直接返回给用户而不是保存为文件。
概况:
任何传输起自一个读取或写入文件的请求,这个请求也是连接请求。如果服务器批准此请求,则服务器打开连接,数据以定长512字节传输。每个数据包包括一块数据,服务器发出下一个数据包以前必须得到客户对上一个数据包的确认。如果一个数据包的大小小于512字节,则表示传输结构。如果数据包在传输过程中丢失,发出方会在超时后重新传输最后一个未被确认的数据包。通信的双方都是数据的发出者与接收者,一方传输数据接收应答,另一方发出应答接收数据。大部分的错误会导致连接中断,错误由一个错误的数据包引起。这个包不会被确认,也不会被重新发送,因此另一方无法接收到。如果错误包丢失,则使用超时机制。错误主要是由下面三种情况引起的:不能满足请求,收到的数据包内容错误,而这种错误不能由延时或重发解释,对需要资源的访问丢失(如硬盘满)。TFTP只在一种情况下不中断连接,这种情况是源端口不正确,在这种情况下,指示错误的包会被发送到源机。这个协议限制很多,这是都是为了实现起来比较方便而进行的。通过下边的图片来了解tftp协议的通信流程:
二、系统环境
实验环境:VMware Workstation 12
网络模式:桥接模式(桥接主机无线网卡)
DHCP / TFTP IP:192.168.1.2
HTTP / FTP / NFS IP:192.168.1.2
防火墙已关闭/iptables: Firewall is not running.
SELINUX=disabled
三、准备工作
生成ks.cfg 文件需要system-config-kickstart 工具,而此工具依赖于X Windows,所以我们需要安装X Windows 和Desktop 并重启系统,操作如下:
[root@young ~]# yum groupinstall "X window System" [root@young ~]# yum groupinstall Desktop [root@young ~]# reboot
四、安装并配置DHCP
[root@young ~]# yum -y install dhcp [root@young ~]# cp /usr/share/doc/dhcp-4.2.5/dhcpd.conf.example /etc/dhcp/dhcpd.conf [root@young ~]# vim /etc/dhcp/dhcpd.conf .... option domain-name "young.com"; option domain-name-servers 8.8.8.8; default-lease-time 43200; max-lease-time 86400; log-facility local7; subnet 192.168.1.0 netmask 255.255.255.0 { range 192.168.1.230 192.168.1.240; filename "pxelinux.0"; next-server 192.168.1.2; option routers 192.168.1.1; option broadcast-address 192.168.1.255; } ... [root@young ~]# systemctl start dhcpd.service [root@young ~]# ss -unl ... UNCONN 0 0 *:67 *:* ...
dhcp程序环境说明:
dhcp server:
dhcp主程序: /usr/sbin/dhcpd IPV4网络: /etc/dhcp/dhcpd.conf /usr/lib/systemd/system/dhcpd.service IPV6网络: /etc/dhcp/dhcpd6.conf /usr/lib/systemd/system/dhcpd6.service dhcrelay: /usr/sbin/dhcrelay /usr/lib/systemd/system/dhcrelay.service 监听的地址和端口: Server: 67/udp Client: 68/udp 配置文件:/etc/dhcp/dhcpd.conf 配置指令: option选项:配置给客户端的相信息 指令:定义dhcp server的工作特性 配置有级别之分: 全局配置 子网配置 主机配置 常用的配置: default-lease-time 600; max-lease-time 7200; option domain-name "search_domain.tld"; option domain-name-servers DNS_SERVER1, DNS_SERVER2, DNS_SERVER3; option routers GW1, GW2, ...; option broadcast-address BROADCAST_ADDRESS; subnet NETWORK netmask MASK { range START_IP END_IP; } 定义网络作用域,即一个子网,主要用于指明地址池; host passacaglia { hardware ethernet 0:0:c0:5d:bd:95; fixed-address IP_ADDR; } 其它指令: filename:指明引导文件名称; next-server:指明引导文件所在的服务器的主机IP; filename “pxelinux.0"; next-server 192.168.1.2; #tftp server
五、安装并配置FTP
[root@young ~]# yum -y install vsftpd #安装服务 [root@young ~]# mkdir -pv /var/ftp/pub/centos/7/x86_64/ #创建目录 [root@young ~]# mount -r /dev/sr0 /mnt #挂在系统光盘 [root@young ~]# cp -r /mnt/* /var/ftp/pub/centos/7/x86_64/ #复制光盘仓库,要全部复制会用到其他文件 [root@young ~]# systemctl start vsftpd.service [root@young ~]# ss -tnl ... LISTEN 0 32 :::21 :::* ... [root@young ~]# lftp 192.168.1.2 #查看ftp工作状态是否正常 lftp 192.168.1.2:~> exit [root@young ~]# lftp 192.168.1.2/pub cd ok, cwd=/pub lftp 192.168.1.2:/pub> cd centos/7/x86_64/ lftp 192.168.1.2:/pub/centos/7/x86_64> ls drwxr-xr-x 2 0 0 200704 Dec 24 11:02 Packages dr-xr-xr-x 2 0 0 4096 Dec 24 10:58 repodata
注:dhclient -d 可以查看dhcp服务器的详细输出
六、配置TFTP
[root@young ~]# yum -y install tftp-server tftp #安装tftp服务端与客户端 CentOS 7: [root@young ~]# systemctl enable tftp.socket #设为开机启动 [root@young ~]# systemctl start tftp.socket #启动服务 CentOS 6: [root@young ~]# chkconfig tftp on [root@young ~]# service xinetd restart [root@young ~]# ss -unl #监听在UDP/69端口 ... UNCONN 0 0 :::69 :::* ...
七、安装syslinux
[root@young ~]# yum -y install syslinux
说明:syslinux是一个功能强大的引导加载程序,而且兼容各种介质。更加确切地说:SYSLINUX是一个小型的Linux操作系统,它的目的是简化首次安装Linux的时间,并建立修护或其它特殊用途的启动盘。
八、配置支持PXE的启动程序
centos 7:
[root@young ~]# cp /usr/share/syslinux/{pxelinux.0,mboot.c32,memdisk,menu.c32,chain.c32} /var/lib/tftpboot/ #复制启动所需的引导文件 [root@young ~]# cp /mnt/images/pxeboot/{initrd.img,vmlinuz} /var/lib/tftpboot/ #复制系统光盘中虚拟文件系统以及内核文件至tftp服务器 [root@young ~]# mkdir /var/lib/tftpboot/pxelinux.cfg #创建配置文件夹 [root@young ~]# vim /var/lib/tftpboot/pxelinux.cfg/default #创建启动配置文件 default menu.c32 #prompt 5 #显示 'boot: ' 提示符。为 '0' 时则不提示,将会直接启动 'default' 参数中指定的内容。 timeout 60 #在用户输入之前的超时时间,单位为 1/10 秒。 MENU TITLE CentOS 7 PXE Menu LABEL linux #'label' 指定你在 'boot:' 提示符下输入的关键字,比如boot: linux[ENTER],这个会启动'label linux' 下标记的kernel 和initrd.img 文件。 MENU LABEL Install CentOS 7 x86_64 KERNEL vmlinuz #kernel 参数指定要启动的内核。 APPEND initrd=initrd.img inst.repo=ftp://192.168.1.2/pub/centos/7/x86_64 #append 指定追加给内核的参数,能够在grub 里使用的追加给内核的参数,在这里也都可以使用。 LABEL linux_autoinst MENU LABEL Install CentOS 7 x86_64 auto KERNEL vmlinuz APPEND initrd=initrd.img inst.repo=ftp://192.168.1.2/pub/centos/7/x86_64 ks=ftp://192.168.1.2/pub/kickstarts/centos7.cfg #告诉系统,yum仓库在哪里,从哪里获取ks.cfg文件
CentOS 6:
[root@young ~]#yum -y install syslinux [root@young ~]#cp /usr/share/syslinux/pxelinux.0 /var/lib/tftpboot/ [root@young ~]#cp /media/cdrom/images/pxeboot/{vmlinuz,initrd.img} /var/lib/tftpboot/ [root@young ~]#cp /media/cdrom/isolinux/{boot.msg,vesamenu.c32,splash.jpg} /var/lib/tftpboot/ [root@young ~]#mkdir /var/lib/tftpboot/pxelinux.cfg/ [root@young ~]#cp /media/cdrom/isolinux/isolinux.cfg /var/lib/tftpboot/pxelinux.cfg/default [root@young ~]# vim /var/lib/tftp/pxelinux.cfg/default #修改如下 default vesamenu.c32 #prompt 1 timeout 600 display boot.msg menu background splash.jpg menu title Welcome to CentOS 6.8 young! menu color border 0 #ffffffff #00000000 menu color sel 7 #ffffffff #ff000000 menu color title 0 #ffffffff #00000000 menu color tabmsg 0 #ffffffff #00000000 menu color unsel 0 #ffffffff #00000000 menu color hotsel 0 #ff000000 #ffffffff menu color hotkey 7 #ffffffff #ff000000 menu color scrollbar 0 #ffffffff #00000000 label autoinst menu label ^Auto Install CentOS menu default kernel vmlinuz append initrd=initrd.img ks=ftp://192.168.1.2/pub/centos6.cfg label linux menu label ^Install or upgrade an existing system kernel vmlinuz append initrd=initrd.img label vesa menu label Install system with ^basic video driver kernel vmlinuz append initrd=initrd.img nomodeset label rescue menu label ^Rescue installed system kernel vmlinuz append initrd=initrd.img rescue label local menu label Boot from ^local drive localboot 0xffff label memtest86 menu label ^Memory test kernel memtest append -