自定义centos镜像制作

实际工作中,总是会面对各种各样的需求,除了开发需求之外,还可能会有操作系统方面的自定义方面的需求,如果使用的是 centos 系统,需要对 centos 系统做一些特殊的自定义的操作,那么这篇文章希望能对你有所帮助。

自定义centos镜像制作

我的其他博客地址
https://juejin.cn/user/176366088104638
blog.wuzhenyu.com.cn

tutorial

自定义 centos 镜像的思路,利用的也是官方已有的镜像。从官网下载最小化安装的镜像,以此作为基础,在这个基础上可以添加或者删除该镜像中预装的 rpm 包,来达到自定义镜像的目的。

挂载镜像

将iso镜像添加到虚拟机上,挂载后的设备为 /dev/sr1,将其挂载到 /media 目录中

mount /dev/sr1 /media
lsblk

安装制作发行版的工具

yum -y install createrepo mkisofs isomd5sum rsync

同步光盘文件到制作ISO的目录

#同步/media下的文件到/ISO路径下,除了Packages和repodata文件夹
/usr/bin/rsync -a --exclude=Packages/ --exclude=repodata/ /media/ /ISO/
# 在/ISO/文件夹下新建Packages和repodata文件夹
mkdir -p /ISO/{Packages,repodata}

拷贝 rpm

生成install.log

rpm -qa >> /root/install.log

拷贝已安装rpm

awk '{print $0}'  /root/install.log |xargs -i cp /media/Packages/{}.rpm /ISO/Packages/

配置yum下载指定软件包列表(rpms_list.txt)的所有依赖包

将需要安装的包及其以来写入 rpms_list.txt

#!/bin/sh   
for line in `cat /root/rpms_list.txt`
    do
       echo "download file>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>and it's denpendies"$line
     yum install -y --downloadonly --downloaddir=/root/test/ $line
#或者先安装yum -y install yum-utils再yumdownloader $line
    done
#yum查找.so或者某个依赖在哪个rpm包中
yum provides {.so名或者依赖名字}
#拷贝包到指定目录
cp /root/test/* /ISO/Packages/

rpm 相关操作

yum list | grep XXX # 搜索
yum deplist XXX # 查看依赖
yum install --downloadonly --downloaddir=/packages XXX # 仅仅下载,不安装
yumdownloader --resolve --destdir /packages XXX # 下载

安装包的所有依赖必须齐全,否则安装系统时,会出错

修改 isolinux.cfg 文件

label linux
menu label ^Install CentOS 7
kernel vmlinuz
#这样是不自动安装
append initrd=initrd.img inst.stage2=hd:LABEL=CentOS7 quiet
#这样配置会自动安装
append initrd=initrd.img inst.stage2=hd:LABEL=CentOS7 inst.ks=hd:LABEL=CentOS7:/isolinux/ks.cfg quiet

inst.ks为ks.cfg文件位置;
inst.stage2为安装介质位置,hd:LABEL为介质标签,例如CentOS7。这个和后续生成ISO镜像文件的命令genisoimage的参数-V有关。
最好是把所有hd:LABEL后面的值都替换为一个后面会用到的字符串,如CentOS7

修改自动化安装配置文件

第一次手动安装系统完成后,安装程序中的所有选择都会保存到名为 anaconda-ks.cfg 的文件中,该文件位于所安装系统的 /root/ 目录下。然后可以复制这个文件,根据需要进行修改,并在以后的安装中使用得到的配置文件。

在%packages与%end中间加入需要自定义安装的包组

#安装所需要的软件包,把自定义的安装包添加进去即可在安装系统时自定义的软件
%packages
@^web-server-environment
@base
@core
@java-platform
@python-web
@web-server
kexec-tools
@{自定义包组的groupid}
%end

自定义包组的 groupid 就是定义在 /repodata/comps.xml 文件中的 group

制作修改comps文件

进入/ISO目录,将*-x86_64-comps.xml文件拷贝到/ISO/repodata路径下,并重命名成comps.xml。在该路径下只会存在一个该名称的xml文件。

cp /media/repodata/*-x86_64-comps.xml  /ISO/repodata/comps.xml

编辑comps文件

添加定制rpm包

<group>
    <id>{自定义包组的groupid}</id>
    <name>My Dependencies</name>
    <default>true</default>
    <uservisible>true</uservisible> # 这个值为true,在安装界面才能看到,否则不可见
    <packagelist>
        <packagereq type="default">python-webob</packagereq>
        ......
    </packagelist>
</group>

根据 rpms_list.txt 拼接packagereq

#!/bin/sh
for line in `cat rpms_list.txt`
do
    echo " <packagereq type=\"default\">"$line"</packagereq>" >> /root/package.txt
done

在指定的环境中添加定制的groupid

<environment>
        <id>web-server-environment</id>
        <name>Basic Web Server</name>
        <description>Server for serving static and dynamic internet content. </description>
        <display_order>30</display_order>
        <grouplist>
          <groupid>base</groupid>
          <groupid>core</groupid>
          <groupid>web-server</groupid>
          <groupid>{自定义包组的groupid}</groupid>
        </grouplist>
</environment>

如果不再指定环境中添加,也就是 environment 的节点中添加新定义的 groupid,在系统安装界面就会提示 group 未定义的错误。

生成新的 repodata 数据

切换到ISO/路径下,由comps.xml生成repodata包。注意当有新包加入,或者更新comps.xml文件,均需要重新生成repodata文件夹

createrepo -g repodata/comps.xml ./

制作ISO镜像

注意参数中的-V,和上面的isolinux.cfg文件有关

cd /ISO
genisoimage -joliet-long -V CentOS7 -o CentOS-7-2.iso -b isolinux/isolinux.bin -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 -boot-info-table -R -J -v -cache-inodes -T -eltorito-alt-boot -e images/efiboot.img -no-emul-boot /ISO

选项 -V CentOS7 就是上面提及的 inst.stage2=hd:LABEL=CentOS7,如果是带有空格的,那就加上双引号,比如 -V "CentOS 7 x86_64"

制作镜像MD5值

implantisomd5 /ISO/CentOS-7-2.iso

生成的 iso 镜像文件就可以直接用于安装系统了

rpm 包的制作

rpm 制作,需要 rpmbuild 工具,通过如下方式安装

yum install | grep rpm-build

如果 yum 源有问题,centos7 按照下面的方法配置 yum 源

# 备份
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup
# 下载
wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo

yum clean
yum makecache # 生成缓存

rpm 制作,需要准备后缀为 spec 的配置文件,rpmbuild 按照这个文件,找到源代码以及生成指令进行 rpm 的生成。以 audit 的 rpm 的制作为例,配置文件为 secsmart_platform_audit.spec

Name: secsmart_platform_audit
Version: 1.0
Release: 1
Summary: test for build rpm	

Group: Enterprise/Linux	
License: GPL	
URL: http://www.both.org	
Source0: secsmart_platform_audit-%{version}.tar.gz 

BuildRequires: bash
Requires: bash	

%description
install all in one

%prep
%setup -q

%build

%install
rm -rf $RPM_BUILD_ROOT
mkdir -p ${RPM_BUILD_ROOT}/data/all_in_one
install -m755 audit.tar.gz ${RPM_BUILD_ROOT}/data/all_in_one

%clean
rm -rf $RPM_BUILD_ROOT

%files
%defattr(-, root, root)
%attr(0744, root, root) /data/all_in_one/audit.tar.gz

%post

%changelog

执行

rpmbuild -ba secsmart_platform_audit.spec

会在当前用户的家目录下,生成 rpmbuild 的目录,目录结构如下

BUILD  BUILDROOT  RPMS  SOURCES  SPECS  SRPMS

这是 rpmbuild 工具的工作目录,所有的 spec 配置文件都必须放在 SPECS 目录中,源文件,也就是 audit.tar.gz 文件都必须放在 SOURCES 目录中,制作完成的 rpm 文件会存放在 RPMS 目录中。

SPEC 配置解析

  • Name - 名称
  • Version - 版本号
  • Release - 与 Version 类似,上面这三个配置项,是必须有的,不能为空
  • Summary - 可以为空,描述
  • Group
  • License
  • URL - 按照官方文档说明填写
  • Source0 - 这个表示的制作 rpm 的源文件,这个源文件的命名,必须带上版本号,所以,audit.tar.gz 会按照如下的方式命名

首先创建 secsmart_platform_audit-1.0 的文件夹,然后将 audit.tar.gz 移动到文件夹中,在将文件夹打包成secsmart_platform_audit-1.0.tar.gz,将这个文件放到 rpmbuild/SOURCES

  • BuildRequires - bash
  • Requires - bash,这两个表示的rpm包的依赖,我们自己制作的安装包,不需要依赖,唯一依赖的就是 bash,在shell 环境下执行安装脚本
  • build - 如果是源代码,通过这个配置,对源代码进行编译
  • install - 这个就是安装脚本
# 1. 在制作过程中,会将临时文件存放在这个目录中,首先清空目录
rm -rf $RPM_BUILD_ROOT # rpmbuild 

# 2. 创建目录,RPM_BUILD_ROOT 对应的就是 rpm 在安装的时候的 / 目录,也就是创建 /data/all_in_one 目录
mkdir -p ${RPM_BUILD_ROOT}/data/all_in_one

# 3. 将 audit.tar.gz 文件 install,也就是 copy 到 /data/all_in_one 目录中
install -m755 audit.tar.gz ${RPM_BUILD_ROOT}/data/all_in_one
  • files - 安装后的文件
# 安装完成之后的文件及其属性,也就说,audit 的rpm 安装完成后,在 /data/all_in_one/ 目录中,存在一个 audit.tar.gz 的文件
%attr(0744, root, root) /data/all_in_one/audit.tar.gz

rpmbuild 制作过程简述

按照上述的配置文件,rpmbuild 工具在制作 rpm 时,首先在 rpmbuild/SOURCES 文件中,找到 secsmart_platform_audit-1.0.tar.gz 这个文件,然后解压缩,进入 secsmart_platform_audit-1.0,找到 audit.tar.gz 文件,对这个文件进行一些检验,然后根据 install 的命令,制作成 secsmart_platform_audit-1.0-1.x86_64.rpm 文件。

对这个文件直接通过

rpm -i secsmart_platform_audit-1.0-1.x86_64.rpm

进行安装,就能在 /data/all_in_one 目录下看到 audit.tar.gz 文件,说明安装成功

镜像制作和安装问题汇总

1

postfix 安装时,出现错误
2:postfix-2.10.1-6.el7.x86_64 has missing requires of libmysqlclient.so.18()(64bit)
2:postfix-2.10.1-6.el7.x86_64 has missing requires of libmysqlclient.so.18(libmysqlclient_18)(64bit)

缺少Percona-XtraDB-Cluster-shared-55-5.5.37-25.10.756.el6.x86_64.rpm这个包

2

net-snmp-agent-libs 依赖 libmysqlclient.so.18,但是实际安装的时候,并不需要这个库

实际安装依赖
net-snmp-libs
net-snmp-agent-libs
lm_sensor-libs

问题1与问题2,都是因为 mysql 库与 mariadb 库的冲突导致。mysql 库 与 mariadb 库,名称都是 mysqlclient.so,这个库导致的冲突造成的。

3

kickstart 安装完系统后,将 iso 挂载,同时拷贝出里面的文件

系统安装完成之后,光盘挂载在/tmp/cdrom,它是处于non-chroot环境下的。

%post
# copy files from the rhel.iso image to system                                                                                      
if [ ! -b /tmp/cdrom ];then
  echo "make cdrom node using mknod" >> /root/ins.log
  # get the major number
  major=$(lsblk |grep rom | awk '{print $2}' |awk -F : '{print $1}')
  # get the minor number
  minor=$(lsblk |grep rom | awk '{print $2}' |awk -F : '{print $2}')
  echo "major=${major}  minor=${minor}" >> /root/ins.log
  # make sure we have what we need; create device node if so
  [ -n "$major" -a -n "$minor" ] && mknod /tmp/cdrom b ${major} ${minor}
fi

echo "mount the iso to /mnt/source" >> /root/ins.log
[ ! -d /mnt/source ] && mkdir -p /mnt/source
mount -t iso9660 -o ro /tmp/cdrom /mnt/source

# copy ...
%end

4 anaconda log path

不管怎样,%post %end 脚本,查看有没有起作用,可以在

系统安装完成之后,在

/var/log/anaconda/

目录下查看完整的日志

5 partition

kickstart 分区

# Partition clearing information
zerombr
clearpart --all --initlabel
#auto part --type=lvm
part /boot --fstype ext4 --size 256 # 创建 /boot 分区
part swap --recommended # 创建 swap 分区,推荐大小一般是内存的2倍大小
part pv.01 --size 19456 --grow # 创建名为 pv.01 的分区
volgroup centos pv.01 # 创建 volumn group ,取名为 centos
logvol / --vgname=centos --size 10240 --name=lv_root # 创建逻辑卷 /, 名为 lv_root
logvol /home --vgname=centos --size 9126 --name=lv_home

比如下面这个分区情况,

DEVICE        MOUNTPOINT       SIZE
 /dev/sda       (total)         500,000 MB
 /dev/sda1       /boot/           128 MB
 /dev/sda2       /            20,000 MB
 /dev/sda3       /var/log/        20,000 MB
 /dev/sda5       /home/         400,000 MB
 /dev/sda6       /opt/          51,680 MB
 /dev/sda7       swap           8,192 MB

可以在 kickstart 的 ks.cfg 配置中按照如下方式编写

 part /boot  --asprimary --size=128
 part /    --asprimary --size=20000
 part /var/log --asprimary --size=20000
 part /home         --size=400000
 part /opt         --size=51680
 part swap         --size=8192

还可以在kickstart中分区时,自动实现软raid的配置

clearpart --drives=hda,hdc
zerombr
# Raid 1 IDE config
part raid.11 --size 1000 --asprimary --ondrive=hda
part raid.12 --size 1000 --asprimary --ondrive=hda
part raid.13 --size 2000 --asprimary --ondrive=hda
part raid.14 --size 8000 --ondrive=hda
part raid.15 --size 16384 --grow --ondrive=hda
part raid.21 --size 1000 --asprimary --ondrive=hdc
part raid.22 --size 1000 --asprimary --ondrive=hdc
part raid.23 --size 2000 --asprimary --ondrive=hdc
part raid.24 --size 8000 --ondrive=hdc
part raid.25 --size 16384 --grow --ondrive=hdc

# You can add --spares=x
raid / --fstype xfs --device root --level=RAID1 raid.11 raid.21
raid /safe --fstype xfs --device safe --level=RAID1 raid.12 raid.22
raid swap --fstype swap --device swap --level=RAID1 raid.13 raid.23
raid /usr --fstype xfs --device usr --level=RAID1 raid.14 raid.24
raid pv.01 --fstype xfs --device pv.01 --level=RAID1 raid.15 raid.25

# LVM configuration so that we can resize /var and /usr/local later
volgroup sysvg pv.01
logvol /var --vgname=sysvg --size=8000 --name=var
logvol /usr/local --vgname=sysvg --size=1 --grow --name=usrlocal

这是在 raid 基础上进行了逻辑卷的配置管理。首先, clearpart 对 hda 和 hdc 进行数据清楚,zerombr 初始化未使用的分区表。然后,分别对这两块硬盘分成了5个分区,将两两对应的分区再次划分,创建成配置有 raid1 磁盘阵列的分区,此为格式化的实际使用的分区。最终,还能继续对这些分区进行逻辑卷划分,比如对 pv.01 ,创建逻辑管组 sysvg,在此基础上创建 /var 和 /usr/local 分区,–grow 选项,说明该分区的大小不固定,该分区可以使用 pv.01 剩余的空间

6 pre and post script

preinstall 脚本用 %pre 指示开头,脚本使用的语法和 RPM spec 文件中的类似。在安装之前这个阶段,preinstall 脚本只能做一些基本的操作,比如查找一些文件或者挂载NFS共享等等。

postintall 脚本则更有潜力,postinstall 脚本用 %post 指示开头。当OS安装已经完成以后,postinstall 脚本默认是在新安装好的系统上执行,新安装好的系统这个时候处于 chroot 环境,根目录其实是在/mnt/sysimage下。

可以使用 %post --nochroot 来执行一些非 chroot 环境下的命令。比如在 chroot 环境下,你是无法访问光驱中的安装光盘的,因为光盘挂载在/tmp/cdrom,它是处于 non-chroot 环境下的。

一般来说 postinstall 脚本以 #!/bin/sh 这样的自定义shell作为第一行,然后下边就是普通的shell脚本了。这样基本上你想做什么都可以了。

7 制作u盘安装镜像找不到u盘

dracut listqueue timeout

找不到u盘,在安装启动界面,按键 e 修改,将

inst.stage2

修改成

inst.stage2=hd:sdc4 inst.ks=hd:sdc4:/isolinux/ks.cfg

u盘是 /dev/sdc4

同时,在安装启动界面,在 quiet 前面加上 dd 命令,进入系统后会检测硬盘信息,检测出 u 盘的盘符,然后重启,进行上述修改即可

安装系统时,引导程序寻找安装镜像,比如上面

inst.stage2=hd:LABEL=CentOS7

将镜像写入 U 盘是,U盘的标签名将被命名为 CentOs7,引导程序通过 LABEL 的名称寻找到 U 盘,同时加载相应的程序进行安装。如果找不到,就采用上面那种指定 U 盘的方式进行安装。所以上面应该改成如下的方式即可自动化安装

inst.stage2=hd:LABEL=CentOS7 inst.ks=hd:LABEL=CentOS7:/isolinux/ks.cfg
上一篇:Centos7等保三级检查命令


下一篇:【DB笔试面试828】在Oracle中,什么是审计(Audit)?