自定义iso镜像

最近公司有需求, 在centos基础镜像上添加自己的服务, 方便部署


一. 主要流程概览

  1. 准备基础环境
  2. 挂载并提取原始 CentOS 7.6 ISO 文件内容
  3. 编写或修改 Kickstart 自动安装脚本
  4. 添加额外的软件包或初始化脚本
  5. 重新生成 ISO 镜像(可引导)
  6. 验证 ISO 是否可用(如使用虚拟机测试)

二. 具体操作步骤(以 Linux 环境为例)

1. 安装必要工具

yum install -y createrepo genisoimage isomd5sum syslinux

2. 下载并挂载 CentOS 7.6 原始 ISO

mkdir -p /mnt/iso
mount -o loop CentOS-7-x86_64-DVD-1804.iso /mnt/iso

3. 拷贝 ISO 内容到工作目录

mkdir -p /root/custom
cp -r /mnt/iso/. /root/custom/
umount /mnt/iso

4. 编写或修改 Kickstart 文件(可自动分区、设置主机名等)

比如创建 /root/custom/ks.cfg

#version=RHEL7
install
cdrom
lang en_US.UTF-8
keyboard us
timezone Asia/Shanghai --isUtc
rootpw 123456
authconfig --useshadow --passalgo=sha512
firewall --disabled
selinux --disabled
network --bootproto=dhcp --device=eth0 --onboot=on
reboot

clearpart --all --initlabel
autopart

%packages
@core
wget
vim
net-tools
%end

%post
echo "custom init script running..." >> /root/init.log
%end

5. 修改启动引导配置

编辑 isolinux/isolinux.cfg 添加 ks=cdrom:/ks.cfg 启动参数:

net.ifnames=0 biosdevname=0 这个配置是让centos禁用“可预测网卡命名”方式, 网卡名称会以ethxx方式命名, ks.cfgz中的网卡名称就可以指定成eth0了

label auto
  menu label ^Auto Install CentOS 7
  kernel vmlinuz
  append initrd=initrd.img inst.ks=cdrom:/ks.cfg net.ifnames=0 biosdevname=0

6. 添加 ks.cfg 到根目录

cp /root/ks.cfg /root/custom/

7. 重新生成 ISO 镜像

cd /root/centos7-custom
mkisofs -o /root/CentOS-7.6-Custom.iso \
  -b isolinux/isolinux.bin -c isolinux/boot.cat \
  -no-emul-boot -boot-load-size 4 -boot-info-table \
  -R -J -v -T .

8. 可选:为 ISO 添加校验码(推荐)

isomd5sum /root/CentOS-7.6-Custom.iso > /root/CentOS-7.6-Custom.iso.md5

三. 测试

用虚拟机加载该自定义 ISO 镜像,验证是否能自动安装并执行初始化操作。


四. 添加自定义添加其他镜像

可以把其他的 RPM 包和系统镜像一起打包进 ISO,并作为一个本地 repo 使用,这样安装时就不依赖网络了。
下面是详细操作流程:


📁 假设目录结构如下:

/root/custom/
├── isolinux/
├── Packages/              # CentOS 原始包
├── repodata/              # CentOS 原始 repo 元数据
├── extra/                 # 你准备的 其他 所有 RPM 包
└── ks.cfg                 # Kickstart 文件

🔧 步骤一:创建本地仓库结构

  1. 把你的 MySQL rpm 包复制过去:
mkdir -p /root/custom/extra/
cp /path/to/rpms/*.rpm /root/custom/extra/
  1. 生成 repo 元数据:
cd /root/custom/extra/
createrepo .

🧠 步骤二:在 Kickstart 文件中添加这个本地 repo

%packages 前加入(路径从 CDROM 里挂载):

repo --name=local --baseurl=file:///run/install/repo/extra/

这样安装时就会把 /extra 当作一个独立的仓库读取。


🧾 步骤三:在 %packages 添加包名, 以MySQL openresty为例

%packages
@core
mysql-community-server
mysql-community-client
mysql-community-common
mysql-community-libs
openresty
....xxxx
%end

你可以使用 rpm -qpl 包名.rpm 来查每个 .rpm 里的软件名。


🛠️ 步骤四:修改 mkisofs 命令重新打包 ISO

你需要重新生成 ISO:

cd /root/custom

mkisofs -o /root/CentOS-7.6-Custom.iso \
  -b isolinux/isolinux.bin -c isolinux/boot.cat \
  -no-emul-boot -boot-load-size 4 -boot-info-table \
  -R -J -v -T .

五. 自定义脚本安装部署

在Kickstart文件中使用两个%post部分(一个带有--nochroot,一个不带)是为了在不同的执行环境中运行安装后脚本,这是Kickstart的一个特性设计。我来详细解释它们的区别和用途:

两个%post阶段的区别

1. %post --nochroot

%post --nochroot --log=/mnt/sysimage/root/ks-post.log

特点:

  • 安装环境中执行(尚未chroot到新系统)
  • 可以访问安装介质(如ISO/CD)的内容
  • 可以访问新系统的文件系统(通过/mnt/sysimage
  • 此时新系统尚未完全配置(如网络可能不可用)

典型用途:

  • 从安装介质复制文件到新系统
  • 在新系统挂载前进行磁盘操作
  • 访问安装时需要的网络资源

2. %post(不带--nochroot

%post --log=/root/ks-post.log

特点:

  • 新系统环境中执行(已chroot到新系统)
  • 直接在新系统的根目录下操作
  • 可以访问新系统的所有已安装软件和服务
  • 此时网络通常已配置完成

典型用途:

  • 运行配置脚本
  • 设置服务开机自启
  • 创建用户账户
  • 修改系统配置文件

为什么需要两个阶段?

  1. 文件复制需求

    • 第一个%post --nochroot用于将文件从ISO复制到新系统
    • 第二个%post用于在新系统中配置这些文件
  2. 环境差异

    • 安装环境有完整的工具集(如rsync, curl等)
    • 新系统可能只安装了最小化软件包
  3. 执行时机

    • 某些操作必须在chroot前完成(如复制大文件)
    • 某些操作必须在chroot后才能完成(如服务注册)

实际应用示例

假设您要部署一个web应用:

%post --nochroot
# 从ISO复制应用文件到新系统
cp -r /run/install/repo/webapp /mnt/sysimage/opt/
%end

%post
# 在新系统中配置应用
chown -R apache:apache /opt/webapp
cp /opt/webapp/config/httpd.conf /etc/httpd/conf.d/
systemctl enable httpd
%end

注意事项

  1. 如果不需要访问安装介质,通常只需要一个%post(不带--nochroot
  2. --nochroot阶段的路径需要特别注意(新系统在/mnt/sysimage下)
  3. 两个阶段的日志文件最好分开(如示例中的不同日志路径)
  4. 错误处理要分别考虑,一个阶段的失败不会自动终止另一个阶段

六. 示例ks.cfg

# 安装模式设置
install          # 表示这是一个安装操作
cdrom           # 指定从CD/DVD安装

# 软件仓库配置
repo --name=base --baseurl=file:///run/install/repo/         # 主仓库路径
repo --name=extra --baseurl=file:///run/install/repo/extra/  # 额外仓库路径

# 系统认证配置
auth --enableshadow --passalgo=sha512  # 启用shadow密码,使用SHA512加密

# 安装界面设置
graphical        # 使用图形界面安装
firstboot --enable  # 首次启动时运行设置向导

# 磁盘设置
ignoredisk --only-use=sda  # 只使用sda磁盘

# 区域设置
keyboard --vckeymap=cn --xlayouts='cn'  # 设置键盘布局为中国
lang zh_CN.UTF-8                        # 设置系统语言为中文UTF-8

# 网络配置
network  --bootproto=dhcp --device=eth0 --onboot=on --activate  # 配置eth0网卡使用DHCP
network  --hostname=localhost.localdomain  # 设置主机名

# 根密码设置(加密密码)
rootpw --iscrypted $6$cad7VYFPmMX5A/jh$1cP7mqOQY1qW2npFViqa.FJ1mkWLN8i9KbrDzB50Vi6D6dnljlfWkhcNCv/DAKXbHmDb4hyyZIH15AlPaXcoT.

# 系统服务
services --enabled="chronyd"  # 启用chronyd时间同步服务

# 时区设置
timezone Asia/Shanghai --isUtc  # 设置时区为上海(使用UTC)

# 引导加载器配置
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda  # 安装引导到sda的MBR

# 分区设置
clearpart --all --initlabel  # 清除所有分区并初始化磁盘标签
part /boot --fstype=ext4 --asprimary --size=1024  # 创建1GB的/boot分区
part /     --fstype=ext4 --asprimary --size=1 --grow  # 创建根分区,使用剩余所有空间

# 安全设置
firewall --disabled  # 禁用防火墙
selinux --disabled   # 禁用SELinux

# 软件包选择部分
%packages
@^minimal  # 最小化安装
@core      # 核心组件
chrony     # 时间同步工具
net-tools  # 网络工具
lrzsz      # rz/sz文件传输工具
kexec-tools  # 内核工具
unzip      # 解压工具
sysstat    # 系统监控工具
wget       # 下载工具
screen     # 终端复用工具
lsof       # 列出打开文件工具
tcpdump    # 网络抓包工具
nc         # netcat网络工具
mtr        # 网络诊断工具
openssl-devel  # SSL开发库
vim        # 文本编辑器
bash-completion  # bash自动补全
nmap       # 网络扫描工具
telnet     # 远程登录工具
tree       # 目录树显示工具
ntpdate    # 时间同步工具
gcc        # C编译器
patch      # 补丁工具
libffi-devel  # 外部函数接口库
python-devel  # Python开发包
zlib-devel    # 压缩库开发包
bzip2-devel   # bzip2开发包
ncurses-devel # 终端处理库
sqlite-devel  # SQLite数据库开发包
readline-devel # 命令行编辑库
tk-devel      # Tk GUI工具包
gdbm-devel    # GNU数据库管理库
xz-devel      # xz压缩库
openssl       # SSL工具包
bitmap-fonts-cjk  # CJK点阵字体
libaio        # 异步IO库
openresty     # OpenResty web平台
mysql-community-server    # MySQL服务器
mysql-community-client    # MySQL客户端
mysql-community-common    # MySQL公共文件
mysql-community-libs      # MySQL库文件
%end

# 安装后脚本(在安装环境中执行)
%post --nochroot --log=/mnt/sysimage/root/ks-post.log
exec > /mnt/sysimage/root/ks-post.log  # 重定向输出到日志文件
set -x  # 开启调试模式,显示执行的命令

# 列出安装介质中的files目录内容
ls -l /run/install/repo/files/

# 从安装介质复制各种文件到新系统的/opt目录
cp -r /run/install/repo/files/mysql /mnt/sysimage/opt/
cp -r /run/install/repo/files/redis /mnt/sysimage/opt/
cp -r /run/install/repo/files/kernel /mnt/sysimage/opt/
cp -r /run/install/repo/files/manage-admin /mnt/sysimage/opt/
cp -r /run/install/repo/files/java /mnt/sysimage/opt/
cp -r /run/install/repo/files/java13 /mnt/sysimage/opt/
cp -r /run/install/repo/files/openresty /mnt/sysimage/opt/
cp /run/install/repo/files/my.cnf /mnt/sysimage/opt/
cp /run/install/repo/files/redis-5.0.9.tar.gz /mnt/sysimage/opt/
cp /run/install/repo/files/kernel.service /mnt/sysimage/opt/
cp /run/install/repo/files/manage-admin.service /mnt/sysimage/opt/
cp /run/install/repo/files/redis.service /mnt/sysimage/opt/
cp /run/install/repo/files/java.sh /mnt/sysimage/opt/
%end

# 安装后脚本(在新系统中执行)
%post
# 重定向输出到日志文件
exec > /root/post-install.log 2>&1
set -x  # 开启调试模式

# 列出/opt目录内容
ls -l /opt/

# 创建系统用户
useradd developer  # 添加developer用户
useradd redis      # 添加redis用户

# 创建数据目录
mkdir /data/

# 移动并组织各种文件到正确位置
mv /opt/mysql /data/
mv /opt/redis /data/
mv /opt/kernel /data/
mv /opt/manage-admin /data/
mv /opt/java /usr/local/
mv /opt/java13 /usr/local/
mv /opt/java.sh /etc/profile.d/
mv /opt/redis.service /etc/systemd/system/
mv /opt/kernel.service /etc/systemd/system/
mv /opt/manage-admin.service /etc/systemd/system/

# 设置java.sh可执行权限
chmod +x /etc/profile.d/java.sh

# 设置目录所有者
chown -R developer:developer /data/kernel /data/manage-admin
chown -R mysql:mysql /data/mysql
chown -R redis:redis /data/redis

# 替换MySQL配置文件
rm /etc/my.cnf
mv /opt/my.cnf /etc/

# 安装OpenResty
rm -rf /usr/local/openresty
mv /opt/openresty /usr/local/

# 启用各种服务
systemctl enable mysqld
systemctl enable redis
systemctl enable kernel
systemctl enable manage-admin
systemctl enable openresty

# 编译安装Redis
cd /opt/ && tar xf redis-5.0.9.tar.gz && cd redis-5.0.9 && make && make install
%end

# kdump配置(内核崩溃转储)
%addon com_redhat_kdump --enable --reserve-mb='auto'
%end

# Anaconda密码策略设置
%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

# 安装完成后重启系统
reboot

主要功能说明:

  1. 系统基础配置:设置了语言、键盘、时区、网络等基础配置
  2. 磁盘分区:创建了/boot分区和根分区
  3. 软件包选择:安装了最小化系统加上开发工具、监控工具、数据库等
  4. 文件部署
    • --nochroot阶段从安装介质复制文件到新系统
    • %post阶段将文件移动到最终位置并设置权限
  5. 服务配置:设置了MySQL、Redis、kernel、manage-admin等服务开机自启
  6. 用户创建:创建了developer和redis用户
  7. 编译安装:自动编译安装了Redis 5.0.9

这个kickstart文件实现了一个完整的自动化安装过程,包括系统安装、软件部署、服务配置等所有步骤。

在220上

[root@localhost ~]# cat /var/www/html/ks.cfg
install
url --url=http://192.168.1.3/centos/
#version=DEVEL
# System authorization information
auth --enableshadow --passalgo=sha512
# Use graphical install
graphical
# Run the Setup Agent on first boot
firstboot --enable
ignoredisk --only-use=sda
# Keyboard layouts
keyboard --vckeymap=cn --xlayouts='cn'
# System language
lang zh_CN.UTF-8

# Network information
network  --bootproto=dhcp --device=ens192 --onboot=on
network  --hostname=localhost.localdomain

# Root password
rootpw --iscrypted $6$cad7VYFPmMX5A/jh$1cP7mqOQY1qW2npFViqa.FJ1mkWLN8i9KbrDzB50Vi6D6dnljlfWkhcNCv/DAKXbHmDb4hyyZIH15AlPaXcoT.
# System services
services --enabled="chronyd"
# System timezone
timezone Asia/Shanghai --isUtc
# System bootloader configuration
bootloader --append=" crashkernel=auto" --location=mbr --boot-drive=sda
# Partition clearing information
clearpart --all --initlabel
# Disk partitioning information
part /boot --fstype=ext4 --asprimary --size=1024
part /     --fstype=ext4 --asprimary --size=1 --grow

firewall --disabled
selinux --disabled

%packages
@^minimal
@core
chrony 
net-tools
lrzsz
kexec-tools
unzip 
sysstat 
wget 
net-tools 
screen 
lsof
tcpdump 
nc 
mtr 
openssl-devel 
vim 
bash-completion 
nmap 
telnet 
tree 
ntpdate 
gcc 
patch 
libffi-devel 
python-devel  
zlib-devel 
bzip2-devel  
ncurses-devel 
sqlite-devel 
readline-devel 
tk-devel 
gdbm-devel 
xz-devel 
openssl 
bitmap-fonts-cjk
%end

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

%post
echo "*  soft nofile 65535" >> /etc/security/limits.conf
echo "*  hard nofile 65535" >> /etc/security/limits.conf
echo "*  soft nproc 65535" >> /etc/security/limits.conf
echo "*  hard nproc 65535" >> /etc/security/limits.conf
echo "*  soft memlock unlimited" >> /etc/security/limits.conf
echo "*  hard memlock unlimited" >> /etc/security/limits.conf
echo "net.core.somaxconn=65535" >> /etc/sysctl.conf
echo "net.ipv4.tcp_max_syn_backlog=65535" >> /etc/sysctl.conf
echo "vm.swappiness=10" >> /etc/sysctl.conf
echo "export HISTSIZE=10000" >> /etc/profile
echo 'export HISTTIMEFORMAT="%F %T `whoami` "' >> /etc/profile
echo '
alias ns="netstat -tnlp"
alias sst="systemctl start"
alias ssp="systemctl stop"
alias srt="systemctl restart"
alias sss="systemctl status"
alias see="systemctl enable"
alias sde="systemctl disable"
alias scat="systemctl cat"
' >> /etc/profile

mkdir /etc/yum.repos.d/back
mv /etc/yum.repos.d/*repo /etc/yum.repos.d/back
cat <<EOF > /etc/yum.repos.d/local-centos.repo
[local-centos]
name=Local CentOS Repository
baseurl=http://192.168.1.3/centos
enabled=1
gpgcheck=0
EOF

%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

reboot
posted @ 2025-04-10 10:55  ForLivetoLearn  阅读(256)  评论(0)    收藏  举报