如何批量部署Linux工作站实例

RHEL安装系统anaconda分析与讨论

Posted by Bob Guo on September 7, 2022

众所周知,由于一些个人原因,我在这段时间开始接触RedHat的生态和服务,其中就包括了Red Hat Enterprise Linux。有一说一,作为Arch Linux的重度用户,我个人一直对以RHEL(和CentOS)为代表的企业级发行版的软件管理策略嗤之以鼻,而且我个人的网络服务器在RHEL9中确实出现了NetworkManager无法启动PPP连接的问题(在Arch Linux上没有发生,因为Arch linux上的软件包版本更新),但RHEL focus on workload而非Linux本身的技术策略配合十年的生命周期与完善的软件服务对使用企业级用户的吸引力也确实是可以理解的。因此,接下来我可能会撰写一些文章讨论Red Hat系发行版的技术内容,权当复习。这篇的主题,就是Red Hat系发行版(包括但不限于RHEL、CentOS、Fedora)所使用的安装器-Anaconda。

何谓Anaconda

Anaconda这个单词对技术人来说应该不陌生,毕竟有一个著名的科学计算平台也使用了这个名字。这个词的本意是水蚺,也可以是柯尔特公司的一款左轮手枪。不过本文所讨论的Anaconda,是一个面向RH系发行版的、基于Python与C构建的安装管理程序。
当然,单纯一个安装管理程序并不值得开篇文章,这篇文章真正关心的,是基于Anaconda的自动化部署,以及它能够为需要部署大量节点的管理员带来多少方便。在数据中心级的部署中,为了减少出现兼容性问题的可能性(以及方便甩锅),Sysadmin需要尽可能保证每个系统的软件配置都尽量一致,但对大批量的节点手动安装不仅折磨人,还容易出现输入错误等进一步拖累服务上线的时间,可以说除了KPI没有任何亮点。Anaconda的自动化部署能够有效的节省这些事件,只需要启动安装程序、指定对应的配置文件就行,减少了出错的概率,也节约了Sysadmin的劳动力。

Anaconda的自动化安装配置

Anaconda的自动化,确切的说,Kickstart Installation,是基于配置文件完成的。这个配置文件有三种生成的方法,下面就进行介绍。

已安装节点

在使用传统图形界面或命令行界面安装完成后,RHEL的root用户目录下会出现一个文件:anaconda-ks.cfg。这个文件的内容就是你现在这台节点的装机配置。以我用于测试的虚拟机为例,我的文件内容如下:

#version=RHEL8  
# Use graphical install
graphical

repo --name="AppStream" --baseurl=file:///run/install/sources/mount-0000-cdrom/AppStream

%packages
@^workstation-product-environment
@development
@graphical-admin-tools
@rpm-development-tools
kexec-tools

%end

# Keyboard layouts
keyboard --xlayouts='us'
# System language
lang en_US.UTF-8

# Network information
network  --bootproto=dhcp --device=ens160 --ipv6=auto --activate
network  --hostname=PegionFishRHEL8VM

# Use CDROM installation media
cdrom

# Run the Setup Agent on first boot
firstboot --enable

ignoredisk --only-use=nvme0n1
autopart
# Partition clearing information
clearpart --none --initlabel

# System timezone
timezone Asia/Shanghai --isUtc

# Root password
rootpw --iscrypted [REDACTED]
user --groups=wheel --name=bob --password=[REDACTED] --iscrypted --gecos="PegionFish"

%addon com_redhat_kdump --enable --reserve-mb='auto'

%end

%anaconda
pwpolicy root --minlen=6 --minquality=1 --notstrict --nochanges --notempty
pwpolicy user --minlen=6 --minquality=1 --notstrict --nochanges --emptyok
pwpolicy luks --minlen=6 --minquality=1 --notstrict --nochanges --notempty
%end

手动编辑

如果你想在这个自动生成的配置文件基础上进行进一步的自定义,或者想从零开始重构一个Kickstart配置文件,在CentOS文档的Advanced Installation Options-Kickstart Installations下的Kickstart Syntax Refrence一节有专门的指南,列出了所有配置文件文件中需要用的参数。由于这份文档将所有的指令与参数以字母表排列,建议勤用Ctrl+F。除此之外,Kickstart配置文件也有明确的规范:

  • 每个区块需要按顺序排列,但区块内部的内容可以混搭。区块顺序应当是:
    1. 指令(即前面提到的安装时的配置),anaconda使用的扩展(%addon)也需要放在这一区域
    2. 需要安装的软件包列表(%packages)
    3. 安装前、安装后与debug脚本(%pre、%post与%onerror)
      • 上文所有带%的分区都需要以%end结尾
  • 可以忽略非必要的内容,但如果忘记写必要的条目就需要手动进行干预(提供参数或指令),如果接下来还有这种情况就需要继续手动干预(所以在部署之前double check配置文件的完整性)
  • #开头的部分会被视作注释

其实从上面机器记录的配置文件就可以得知这台虚拟机是如何被配置的。因为我的虚拟机是通过Anaconda的图形界面安装配置的,所以在指令一块只写了一个简单的graphical,并定义了安装时的软件源来自安装盘。之后是安装的四个软件组和一个软件包,分别是@^workstation-product-environment(工作站环境预设)、@development(开发工具组)、@graphical-admin-tools(图形界面管理工具)、@rpm-development-tools(RPM开发工具)与内核工具kexec-tools。这些应用都是默认的预设和可选项,但如果你有额外想要安装的软件(譬如在自建源或EPEL这样的第三方源上的软件),就可以在这里添加指令。除了安装的应用之外,可以看出我的键盘键位设置和语言设置选的都是标准的en-US,但时区选择的是上海,且启用了UTC。网络采用了DHCP模式获取IP,hosname也被设置成PegionFishRHEL8VM。系统会对nvme0n1这个唯一的虚拟NVMe固态进行自动分区,设置root密码,生成一个名称为bob的系统管理员账户并设置它的密码,启动kdump(内核转储,可用于debug与分析),并对密码策略进行了一些设置。最后,关于是否同意EULA和一些GNOME的配置将会在重启之后由使用者手动配置。

RHEL生成器

RHEL Kickstart Generator 对于RHEL的订阅用户来说(包括付费订阅用户与开发者订阅用户),除了采用前述的两种方式创建配置文件之外,还可以直接通过Red Hat提供的Kickstart Generator生成所需要的配置文件。需要注意的是,一些古早的技术文件可能会指出有一个带有图形界面的Kickstart Configurator,但在RHEL8的官方软件包列表已经找不到这个包,根据CentOS官方文档说明是因为该软件包无法处理RHEL6-7之间的技术迭代因而被弃用。

执行编辑好的自动化安装配置文件

在编辑完配置文件之后,自然就需要开始安装。在安装介质方面,任何能够用于给定发行版的安装介质都可以用作Kickstart的安装介质。(说人话就是你用啥装的就继续用)不过,由于正常情况下启动安装介质上的Linux系统会自动进入Anaconda安装器页面,sysadmin需要对安装介质进行一定的修改以调用kickstart。这种修改有两种实现方式:

  1. 将编辑好的配置文件命名为ks.cfg,并存放在一个卷标为OEMDRV的目录里,然后正常运行安装介质即可。系统会自动检测到这个cfg文件,并基于此开始Kickstart部署。
  2. 在GRUB里编辑内核配置文件,加入inst.ks=并指向对应的文件。如果配置的文件不在本地,你还需要用ip=inst.repo=额外指定IP地址与repo地址来定义安装源。如果使用PXE进行基于网络的安装,也可以通过修改PXE的配置文件来进行Kickstart安装。

在按照上文两种中任意一种方式部署好Kickstart安装配置后,只需从对应的安装介质启动,系统就可以自动进行安装部署。理论上,只要你的配置文件写的足够好,就可以自动完成所有的部署和配置环节,直接投入生产。

还有什么需要注意的?

只支持RHEL

Kickstart目前仅有对RHEL系的支持。根据Ubuntu的Wiki,在Ubuntu 5.04 LTS(Hoary Hedgehog)之后,Ubuntu就停止了对Kickstart的支持。事实上,目前对Kickstart这种自动安装方式提供官方支持的只有各RHEL系发行版,另外几个在企业市场较有影响力的发行版(Debian、Ubuntu、SUSE这些)都有其他或官方或第三方的方案(例如FAI),并不需要使用Kickstart。

缺乏硬件感知能力

回看上面的配置文件,你会发现网络设备和硬盘都是以“ens160”、”nvme0n1”这样的形式hardwire进脚本的。硬盘可以通过by-path或by-id的方式手动指定,网卡可以设置不绑定设备,但显然安装器仍然无法灵活感知硬件变动,所有的修改都需要去hardwire,one way or other。对于配置给定的服务器来说也许不是什么大问题,但对于批量配置硬件规格不同的硬件设备来说还是免不了一番折腾。好吧,严格意义上说这个问题带来的麻烦可能并不是特别的大,但在撰写脚本时仍然需要注意。