自定义iso镜像
最近公司有需求, 在centos基础镜像上添加自己的服务, 方便部署
一. 主要流程概览
- 准备基础环境
- 挂载并提取原始 CentOS 7.6 ISO 文件内容
- 编写或修改 Kickstart 自动安装脚本
- 添加额外的软件包或初始化脚本
- 重新生成 ISO 镜像(可引导)
- 验证 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 文件
🔧 步骤一:创建本地仓库结构
- 把你的 MySQL rpm 包复制过去:
mkdir -p /root/custom/extra/
cp /path/to/rpms/*.rpm /root/custom/extra/
- 生成 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到新系统)
- 直接在新系统的根目录下操作
- 可以访问新系统的所有已安装软件和服务
- 此时网络通常已配置完成
典型用途:
- 运行配置脚本
- 设置服务开机自启
- 创建用户账户
- 修改系统配置文件
为什么需要两个阶段?
-
文件复制需求:
- 第一个
%post --nochroot
用于将文件从ISO复制到新系统 - 第二个
%post
用于在新系统中配置这些文件
- 第一个
-
环境差异:
- 安装环境有完整的工具集(如
rsync
,curl
等) - 新系统可能只安装了最小化软件包
- 安装环境有完整的工具集(如
-
执行时机:
- 某些操作必须在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
注意事项
- 如果不需要访问安装介质,通常只需要一个
%post
(不带--nochroot
) --nochroot
阶段的路径需要特别注意(新系统在/mnt/sysimage
下)- 两个阶段的日志文件最好分开(如示例中的不同日志路径)
- 错误处理要分别考虑,一个阶段的失败不会自动终止另一个阶段
六. 示例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
主要功能说明:
- 系统基础配置:设置了语言、键盘、时区、网络等基础配置
- 磁盘分区:创建了/boot分区和根分区
- 软件包选择:安装了最小化系统加上开发工具、监控工具、数据库等
- 文件部署:
- 在
--nochroot
阶段从安装介质复制文件到新系统 - 在
%post
阶段将文件移动到最终位置并设置权限
- 在
- 服务配置:设置了MySQL、Redis、kernel、manage-admin等服务开机自启
- 用户创建:创建了developer和redis用户
- 编译安装:自动编译安装了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
初学linux,每学到一点东西就写一点,如有不对的地方,恳请包涵!