linux之使用rpmbuild打rpm包
linux之使用rpmbuild打rpm包
前言:
已从事linux运维工作数年,感觉自己还是个小菜鸟,没有大神那么的钻研的精神。只是单纯热爱,喜欢对着黑色的屏幕敲击命令,喜欢这种感觉。为什么要做RPM包呢?因为之前公司使用的是开源软件环境,nginx,tomcat,java,等等等等,安装时流程:编译->标准化目录->标准化参数->部署代码。这样纯手操作的话需要一套部署文档,当然根据个人理解和个人功力的不同,部署出来效果都千奇百怪。 所以通过一个星期的学习,大概掌握了写spec,并且总结了自己的方法,虽然比较low,但是目前还算是有效。
原理:
其实rpm是针对centos和redhat,这两种系统服务器份额占有率比较高,目前线上最常用的是 cetnos(redhat)6-x86_64和7,红帽公司为了解决编译繁琐目录不规范的问题才使用的rpm方案,说白了就是把文件封装起来,类似压缩,并将执行的脚本和依赖封装到rpm中, 加上yum源的机制,大幅缩减安装软件的难度和速度。
记住一点就好了,"一切皆文件!"
制作原理:
这里有5个文件夹,按照做菜原理可以理解为
SPEC:核心配置文件,菜谱
SOURCES:源文件存放,原料
BUILD,/var/tmp/foo-root/:生成编译文件,模拟系统环境,炒锅
RPMS:封装完成的rpm包 ,装盘

规划:
其实作为运维都知道,解决问题不算本事,能避免问题,把复杂的事做的简单才是水平。你若想制作属于自己的RPM,而且在本公司推下去一定回遵循以下几点:
1、标准化, 软件安装目录,输出文件统一路径,配置文件规范,你不可能软件东一个,西一个,日志输出的到处都是吧,万一哪天磁盘空间满了,还得担责任是不?
2、完整,尽量使功能完整,但不可把程序做的太死 比如一套Tomcat代码,我就分成了3个包,环境包、代码包、java包。
以下是lnmp架构的规划目录:

干货:
重点就是SPEC的编辑,这里我用了不同的方法,没有使用rpmbuild的“锅”,因为安装软件也只是生成文件罢了,只要自己在测试环境可以编译安装成功那为什么还要扔给”锅”再炒一下,笔者写过多个spec也查过很多资料,在安装某些文件特别多的软件时,rpmbuild就会读取失败 而且还不报错,所以自己判断 它真的是一个”锅”,不能背!
所以很佩服红帽官方的大神,不知道他们怎么实现的,也不想为此投入太多精力, 其实完全可以先在自己的测试环境把软件装好,打包成tar.gz格式,再加上一些软件的配置文件 打包到rpm内,在安装端解压释放执行,就完成了!
实例:
测试环境:
centos6_x86-64
php5.6
163.repo
1、rpmbuild打包环境准备
yum install -y rpm-build rpmdevtools redhat-rpm-config
#安装打包环境
useradd dabao
#创建工作用户,不建议使用root因为root有无限大权限,封包时会可能会影响自身系统
vim .rpmmacros
%_topdir /home/dabao/rpmbuild
#设置%_topdir宏,这个宏是定义打包目录的路径,默认是在/usr/src/redhat
mkdir -p rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS}
#创建工作目录
2、在测试机中安装php
yum install zlib-devel libxml2-devel libjpeg-devel libjpeg-turbo-devel freetype-devel libpng-devel gd-devel libcurl-devel libxslt-devel libxslt-devel libmcrypt-devel mhash mcrypt openssl-devel bzip2-devel #php依赖要记下一会要写到spec中 mkdir -p /data/app/ tar xf libiconv-1.14.tar.gz cd libiconv-1.14 ./configure --prefix=/data/app/libiconv11 make && make install #安装 ./configure \ --prefix=/data/app/php53 \ --with-config-file-path=/data/app/php53/etc \ --with-config-file-scan-dir=/data/app/php53/etc/php.d \ --with-mysql=mysqlnd \ --with-iconv-dir=/data/app/libiconv11 \ --with-freetype-dir \ --with-jpeg-dir \ --with-png-dir \ --with-zlib \ --with-bz2 \ --with-libxml-dir=/usr \ --enable-xml \ --disable-rpath \ --enable-safe-mode \ --enable-bcmath \ --enable-shmop \ --enable-sysvsem \ --enable-inline-optimization \ --with-curl \ --with-curlwrappers \ --enable-mbregex \ --enable-fpm \ --enable-mbstring \ --with-mcrypt \ --with-gd \ --enable-gd-native-ttf \ --with-openssl \ --with-mhash \ --enable-pcntl \ --enable-sockets \ --with-xmlrpc \ --enable-zip \ --enable-soap \ --enable-short-tags \ --enable-zend-multibyte \ --enable-static \ --with-xsl \ --with-fpm-user=www \ --with-fpm-group=www \ --enable-ftp make make install useradd www -s /sbin/nologin -M mkdir -p /data/logs/ #创建php用户及log目录
软件调优,可根据环境调试:
#配置文件
cp /root/tools/php-5.5.29/php.ini-production /etc/php.ini
sed -i '910s#;date.timezone = #date.timezone = "Asia/Shanghai"#g' /etc/php.ini
#901行修改 date.timezone = "Asia/Shanghai"
cp /data/app/php55/etc/php-fpm.conf.default /data/app/php55/etc/php-fpm.conf
sed -i '32s#;error_log = log/php-fpm.log#error_log = /data/logs/php-fpm56.log#g' /data/app/php56/etc/php-fpm.conf
sed -i '50s#;log_level = notice#log_level = error#g' /data/app/php56/etc/php-fpm.conf
sed -i '458s#;rlimit_files = 1024#rlimit_files = 32768#g' /data/app/php56/etc/php-fpm.conf
sed -i '164s#listen = 127.0.0.1:9000#listen = 127.0.0.1:9056#g' /data/app/php56/etc/php-fpm.conf
sed -i '235s#pm.max_children = 5#pm.max_children = 1024#g' /data/app/php56/etc/php-fpm.conf
sed -i '240s#pm.start_servers = 2#pm.start_servers = 16#g' /data/app/php56/etc/php-fpm.conf
sed -i '245s#pm.min_spare_servers = 1#pm.min_spare_servers = 5#g' /data/app/php56/etc/php-fpm.conf
sed -i '250s#pm.max_spare_servers = 3#pm.max_spare_servers = 20#g' /data/app/php56/etc/php-fpm.conf
sed -i '255s#;pm.process_idle_timeout = 10s;#pm.process_idle_timeout = 15s;#g' /data/app/php56/etc/php-fpm.conf
sed -i '261s#;pm.max_requests = 500#pm.max_requests = 2048#g' /data/app/php56/etc/php-fpm.conf
sed -i '441s#;slowlog = log/$pool.log.slow#slowlog = /data/logs/$pool56.log.slow#g' /data/app/php56/etc/php-fpm.conf
#启动文件
cat /etc/init.d/php-fpm56
#! /bin/sh
### BEGIN INIT INFO
# Provides: php-fpm
# Required-Start: $remote_fs $network
# Required-Stop: $remote_fs $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: starts php-fpm
# Description: starts the PHP FastCGI Process Manager daemon
### END INIT INFO
prefix=/data/app/php56
exec_prefix=${prefix}
php_fpm_BIN=${exec_prefix}/sbin/php-fpm
php_fpm_CONF=${prefix}/etc/php-fpm.conf
php_fpm_PID=${prefix}/var/run/php-fpm.pid
php_opts="--fpm-config $php_fpm_CONF --pid $php_fpm_PID"
wait_for_pid () {
try=0
while test $try -lt 35 ; do
case "$1" in
'created')
if [ -f "$2" ] ; then
try=''
break
fi
;;
'removed')
if [ ! -f "$2" ] ; then
try=''
break
fi
;;
esac
echo -n .
try=`expr $try + 1`
sleep 1
done
}
case "$1" in
start)
echo -n "Starting php-fpm "
$php_fpm_BIN --daemonize $php_opts
if [ "$?" != 0 ] ; then
echo " failed"
exit 1
fi
wait_for_pid created $php_fpm_PID
if [ -n "$try" ] ; then
echo " failed"
exit 1
else
echo " done"
fi
;;
stop)
echo -n "Gracefully shutting down php-fpm "
if [ ! -r $php_fpm_PID ] ; then
echo "warning, no pid file found - php-fpm is not running ?"
exit 1
fi
kill -QUIT `cat $php_fpm_PID`
wait_for_pid removed $php_fpm_PID
if [ -n "$try" ] ; then
echo " failed. Use force-quit"
exit 1
else
echo " done"
fi
;;
status)
if [ ! -r $php_fpm_PID ] ; then
echo "php-fpm is stopped"
exit 0
fi
PID=`cat $php_fpm_PID`
if ps -p $PID | grep -q $PID; then
echo "php-fpm (pid $PID) is running..."
else
echo "php-fpm dead but pid file exists"
fi
;;
force-quit)
echo -n "Terminating php-fpm "
if [ ! -r $php_fpm_PID ] ; then
echo "warning, no pid file found - php-fpm is not running ?"
exit 1
fi
kill -TERM `cat $php_fpm_PID`
wait_for_pid removed $php_fpm_PID
if [ -n "$try" ] ; then
echo " failed"
exit 1
else
echo " done"
fi
;;
restart)
$0 stop
$0 start
;;
reload)
echo -n "Reload service php-fpm "
if [ ! -r $php_fpm_PID ] ; then
echo "warning, no pid file found - php-fpm is not running ?"
exit 1
fi
kill -USR2 `cat $php_fpm_PID`
echo " done"
;;
*)
echo "Usage: $0 {start|stop|force-quit|restart|reload|status}"
exit 1
;;
esac
完成之后你就可以启动下你的php试试了,启动测试成功后,请关闭服务正式开始我们打RPM包
2、开始制作rpm包
cd /data/app tar zcvf php56.tar.gz php56 tar zcvf libiconv11.tar.gz libiconv11 cp php56.tar.gz /home/dabao/rpmbuild/SOURCES cp libiconv11.tar.gz /home/dabao/rpmbuild/SOURCES cp /etc/init.d/php-fpm56 /home/dabao/rpmbuild/SOURCES #把原料准备好
编写spec文件
vim /home/dabao/rpmbuid/SPECS/php56.spec
%define name t-php
%define version 5.6.30
%define _prefile /app
Summary: t-php
Name: %{name}
Version: %{version}
Release: 2
Group: System Environment/Daemons
License: GPL
URL: www.php.org
Packager: tajZhang
Vendor: tajZhang
Source0: php56.tar.gz
Source1: php-fpm56
Source2: libiconv11.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-root
#BuildRequires:
Requires: zlib-devel libxml2-devel libjpeg-devel libjpeg-turbo-devel freetype-devel libpng-devel gd-devel libcurl-devel libxslt-devel libxslt-devel libmcrypt-devel mhash mcrypt open
ssl-devel bzip2-devel
%description
php5.6.30 copy install.
basedir /data/app/php56 /data/app/php56/etc
%prep
#%setup -q
%build
#mkdir -p %{buildroot}/usr/java/jdk1.6.0_22
#cp -r * /usr/java/jdk1.6.0_22
%install
rm -rf %{buildroot}
mkdir -p %{buildroot}/data/app
mkdir -p %{buildroot}/etc/init.d
cp -i %{SOURCE0} %{buildroot}/data/app
cp -i %{SOURCE2} %{buildroot}/data/app
cp -i %{SOURCE1} %{buildroot}/etc/init.d
#cp -i %{SOURCE1} %{buildroot}/etc/init.d/ && chmod +x %{buildroot}/etc/init.d/mysqld
#cp -i %{SOURCE2} %{buildroot}/etc/
%pre
#if [ $1 == 1 ];then
#fi
%post
if [ $1 == 1 ];then
tar xf /data/app/php56.tar.gz -C /data/app/
tar xf /data/app/libiconv11.tar.gz -C /data/app/
rm -f /data/app/php56.tar.gz /data/app/libiconv11.tar.gz
mkdir -p /data/logs
useradd www -s /sbin/nologin -M
chmod +x /etc/init.d/php-fpm56
/etc/init.d/php-fpm56 start
chkconfig php-fpm56 on
echo "install over"
fi
%preun
if [ $1 == 0 ];then
/etc/init.d/php-fpm56 stop
rm -rf /data/app/php56
rm -f /etc/init.d/php-fpm56
echo "remove over"
fi
%postun
%clean
rm -rf "%{buildroot}"
rm -rf %_topdir/BUILD/%{name}-%{version}
%files
%defattr (-,root,root,0755)
/etc/init.d/php-fpm56
/data/app/php56.tar.gz
/data/app/libiconv11.tar.gz
执行打包命令
rpmbuild -ba php56.spec #到SPECS目录下执行,如果没有报错会在RPMS/x86_64/目录下生成你打好的包 cd /home/dabao/rpmbuild/RPMS/x86_64/ t-php-5.6.30-2.x86_64.rpm
到此你的第一个rpm包制作完成,拿到测试机上装下试试吧!
分析:
什么?稀里糊涂的根本不懂SPEC里写的什么,其实它只是个模板,摘录一段各位看了一目了然:
----------------------------------分割线---------------------------------------------------------------------------------
总结与启发:
各位看到php的spec根本就没有经过解压与编译,而是直接将tar.gz复制到系统中,执行安装完成后命令。
执行结束后为什么执行一次echo呢?因为这样才能让if的$?返回0,如果最后一条不是成功执行的命令,rpm就会安装报错。
rpm机制是在系统子bsah下执行,不是当前bash,设置系统环境变量的重新登录才生效。
%file段至关重要,因为这里记录了你要装盘的文件。
通过rpm的学习,觉得它可以做很多事,可以让小弟不在为安装文档抓头,而且可以配合yum机制定制自己的软件仓库,实现快速部署。甚至可以用rpm做代码包版本控制,当足够了解自己公司的业务也可以将程序打在一套软件组内,这样是不是更像docker呢?

浙公网安备 33010602011771号