最近使用兩天使用吃奶的力氣在處理 舊版(CentOS-5) / 新版(Ubuntu-1604/CentOS7) 在 log forwarder 的相容性,前陣子有提到 elastic 現代化的 ELK/EFK Log 架構大補帖 在 Node 上可以用 filebeat / logstash 來收
問題來了 … 用來當中介 filter 的 logstash input (6.x) 如果和 Node 的版本 output (1.x) 差太多的話會有不相容的狀況發生 (NoMethodError),如果要和 6.x 的 logstash 相容至少要上到 5.x later … 索性先放棄 logstash 當 log forwarder。
在 elastic 的支援清單看到 filebeat 全面不支援 CentOS 5 瞬間想哭,後來有高手同事建議可以用 rpmbuild 來嘗試在 CentOS 來 build 看看,結果真的可以動!!
這篇就是要講怎麼用 rpmbuild 來 build 出可用的 rpm,範本當然就是 filebeat!!
話先講在前面,如果很懶得 build 也提供給各位 rpm 下載:MEGA
CentOS 5 用 rpmbuild filebeat 6.x
環境:
- OS:CentOS 5.x x86_64
這個方案 x86_64 / i686 都適用,只是 x86_64 build 出來的只能給 x86_64 的機器裝,不能混用。
Step.1 yum 安裝 rpmbuild
$ sudo yum install rpm-build redhat-rpm-config -y
Step.2 建立 build 資料夾結構
$ mkdir -p ~/rpmbuild/{BUILD,RPMS,SOURCES,SPECS,SRPMS} $ cat <<EOF >~/.rpmmacros %_topdir %(echo $HOME)/rpmbuild %_tmppath %{_topdir}/tmp EOF
- BUILD:RPM 安裝內容自動建立的位置
- RPMS:Build 出來的 RPM Package
- SOURCES:包好的 source code (example.tar.gz)
- SPECS:RPM 建立的規格檔 (build spec)
- SRPMS:Source RPM
.rpmmacros 則是定義在使用 rpmbuild 時預設的路徑。
Step.3 下載最新版的 filebeat (6.2.4)。
$ curl -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-6.2.4-linux-x86_64.tar.gz $ tar zxvf filebeat-6.2.4-linux-x86_64.tar.gz && mv filebeat-6.2.4-linux-x86_64 filebeat-6.2.4_x86_64_el5-acme
Step.4 filebeat 裡面的 source code 沒有 init 啟動服務的 script,所以把這部份加進去
$ mkdir filebeat-6.2.4_x86_64_el5-acme/init.d $ tee filebeat-6.2.4_x86_64_el5-acme/init.d/filebeat <<EOF #!/bin/bash PATH=/usr/bin:/sbin:/bin:/usr/sbin export PATH [ -f /etc/sysconfig/filebeat ] && . /etc/sysconfig/filebeat pidfile=${PIDFILE-/var/run/filebeat.pid} agent=${BEATS_AGENT-/usr/share/filebeat/bin/filebeat} args="-c /etc/filebeat/filebeat.yml -path.home /usr/share/filebeat -path.config /etc/filebeat -path.data /var/lib/filebeat -path.logs /var/log/filebeat" RETVAL=0 # Source function library. . /etc/rc.d/init.d/functions if status | grep -q -- '-p' 2>/dev/null; then daemonopts="--pidfile $pidfile" pidopts="-p $pidfile" fi test() { $agent test config -c /etc/filebeat/filebeat.yml > /dev/null } start() { echo -n $"Starting filebeat: " test if [ $? -ne 0 ]; then echo exit 1 fi if ps a | pgrep -f $agent > /dev/null; then failure echo; exit 1 fi $agent $args & RETVAL=$? if [ $RETVAL -eq 0 ]; then success echo $! > $pidfile fi echo return $RETVAL } stop() { echo -n $"Stopping filebeat: " killproc $agent RETVAL=$? echo [ $RETVAL = 0 ] && rm -f ${pidfile} } restart() { test if [ $? -ne 0 ]; then return 1 fi stop start } rh_status() { status $pidopts $agent RETVAL=$? return $RETVAL } rh_status_q() { rh_status >/dev/null 2>&1 } case "$1" in start) start ;; stop) stop ;; restart) restart ;; condrestart|try-restart) rh_status_q || exit 0 restart ;; status) rh_status ;; *) echo $"Usage: $0 {start|stop|status|restart|condrestart}" exit 1 esac exit $RETVAL EOF
啟動 script 有土炮一些作法,因為原本 filebeat 是用 filebeat-god 來管理服務,但是 source code 沒有,也懶得再 build filebeat-god ….
Step.5 打包丟到 rpmbuild/SOURCES
$ tar zcvf filebeat-6.2.4_x86_64_el5-acme.tar.gz filebeat-6.2.4_x86_64_el5-acme $ mv filebeat-6.2.4_x86_64_el5-acme.tar.gz rpmbuild/SOURCES/
Step.6 再來是寫 spec 定義怎麼 build 和安裝
$ tee rpmbuild/SPECS/filebeat-6.2.4_x86_64_el5-acme.spec <<EOF # Don't try fancy stuff like debuginfo, which is useless on binary-only # packages. Don't strip binary too # Be sure buildpolicy set to do nothing %define __spec_install_post %{nil} %define debug_package %{nil} %define __os_install_post %{_dbpath}/brp-compress Summary: Custom Filebeat log transfer system service Name: filebeat Version: 6.2.4_x86_64_el5 Release: acme License: Apache-2.0 Group: System/Monitoring Source: %{name}-%{version}-%{release}.tar.gz Url: https://www.elastic.co/products/beats/filebeat BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root Requires: logrotate %description %{summary} %prep %setup -q -n %{name}-%{version}-%{release} %build # Empty section. %install ## Add Filebeat binary to /usr/bin %{__install} -d -m 755 %{buildroot}%{_bindir} %{__install} -m 755 filebeat %{buildroot}%{_bindir}/%{name} ## Add Filebeat binary to /usr/share %{__install} -d -m 755 %{buildroot}/usr/share/%{name}/ %{__install} -d -m 755 %{buildroot}/usr/share/%{name}/bin %{__install} -m 755 filebeat %{buildroot}/usr/share/%{name}/bin/ ## Add Filebeat modules cp -rp module %{buildroot}/usr/share/%{name}/ ## etc %{__install} -d -m 755 %{buildroot}%{_sysconfdir}/%{name}/ %{__install} -m 644 *.yml %{buildroot}%{_sysconfdir}/%{name}/ cp -rp modules.d %{buildroot}%{_sysconfdir}/%{name}/ %{__install} -d -m 755 %{buildroot}%{_sysconfdir}/%{name}/conf.d %{__install} -d -m 755 %{buildroot}%{_sysconfdir}/init.d %{__install} -m 755 init.d/filebeat %{buildroot}%{_sysconfdir}/init.d/ ## var %{__install} -d -m 755 %{buildroot}/var/lib/%{name}/ %files %defattr(-,root,root) /* %exclude %dir /etc/init.d %changelog * Sat Jun 3 2018 Scott Liao <scott.liao@104.com.tw> 6.2.4_x86_64_el5-acme - build x86_64 for CentOS 5. EOF
先定義 Summary, Name, Version 必要資訊
直接跳過看 %install 的部份,其實就是把需要的檔案搬到 %buildroot 這邊去,按照想要安裝的目錄結構放在以 %buildroot 為起始的位置
舉例這段 %{__install} -m 755 init.d/filebeat %{buildroot}%{_sysconfdir}/init.d/
其實就是把 init.d/filebeat 丟到 rpmbuild/tmp/etc/init.d/filebeat,而實際 rpm 安裝後會放在 /etc/init.d/filebeat 這邊。
%files 這段就是在打包檔案,%defattr 用來定義權限,%exclude 可以排除要打包的位置,( 如果不排除 /etc/init.d 安裝 rpm 時會跟 chkconfig 打架,exclude 後還是會把啟動 script 丟過去 /etc/init.d/filebeat )
最後就是 %changelog,這麼辛苦弄好,做個記錄吧!
Step.7 用 rpmbuild 打包成 rpm
$ rpmbuild -ba ~/rpmbuild/SPECS/filebeat-6.2.4_x86_64_el5-acme.spec
成功後可以在 ~rpmbuild/RPMS/x86_64
找到打包好的 filebeat-6.2.4_x86_64_el5-acme.x86_64.rpm
試試把 rpm 拿來安裝吧 !!
$ sudo rpm -ivh filebeat-6.2.4_x86_64_el5-acme.x86_64.rpm
Reference:
使用 RPM Build ,在Linux 打包 Package
Creating RPM package of Elastic Filebeat