Linux 運維中,為什麼現在很多人用源碼安裝而不用 RPM 安裝?

linux運維的軟體安裝中,網上的文章,80%以上都是源碼安裝,無論是安裝lamp,lnmp還是puppet,而且都是腳本的方式安裝,一般都會叫一鍵安裝XXX。一般運維書籍中也是如此,源碼安裝彷佛成為一個標準。那麼,究竟是什麼原因大家不去使用rpm包安裝呢?源碼安裝,本身就是一道很高的門檻,作為新手學習安裝軟體來說,可以作為了解,然而作為運維人員,還源碼安裝,這個效率問題,版本控制問題怎麼去解決,大家對這個問題是怎麼看待的?
++++++++++++++++++++++++++++++update 1++++++++++++++++++++++++++++++++
看到各位的回答,總結下幾種觀點:
1.系統自帶的rpm包軟體版本太舊,編譯參數不適合自己的業務,
2.對rpmbuild機制不了解,覺得rpm不如源碼編譯方便
3.網路資料書籍誤導,學習的人不假思考,盲目從眾

軟體安裝的版本控制,快速變更,最終需要一種機制來控制,而rpmbuild就是這麼一種機制。為什麼有成熟的方案不用呢?為什麼適合於自動化運維的技術而不去採用?
rpmbuild可以定製的,包括下面說的軟體版本問題,路徑問題,可操作問題,變更問題。
之所以說源碼編譯門檻很高:
第一個問題,是因為源碼編譯,機器得有gcc,c++,make等一系列軟體包依賴關係,
第二個問題,某些編譯的軟體包會導致系統原有的庫文件被破壞,導致新的軟體包無法正常安裝,存在著依賴關係,
第三個問題,每個人的編譯習慣和參數不同,就算是有統一的編譯參數,也難以保證都完全一致
第四個問題,版本控制,規模部署,源碼編譯的方式搞不定,沒有統一的基礎設施規範,自動化運維,批量部署很難著地。
這裡不是說排斥源碼編譯的方式,而是有好的解決方案,當然是選擇最適合的方式。
2013-11-04


從來我都是推薦使用系統默認包的(雖然我不用rpm,而是deb,道理是一樣的)。
我會用到源碼編譯,通常會是這麼一些情況:

1. 需要的軟體系統上游還沒有提供(通常比如Debian系的軟體都相對落後一定年限,其實AS系列可能更舊)
2. 系統提供的軟體包確實被證明發現了不可接受的缺陷或漏洞。

Redhat的沒太多發言權,Debian上面大部份軟體通過已經實現了很好的模塊化定製,可以增減自己不需要的模塊。

雖然在有些時候,編譯出來的內容,可能在精簡度或者性能方面相對系統提供的有一定提升,但是由於在編譯源碼方面,自由度相對比較高,可能破壞了生產環境的「生態圈」,這個有可能得不償失(當然了,這裡一定程度上是管理的問題)

所以,如果有位同學告訴我,需要用源碼裝個什麼,我第一反應通常會是,你確認編譯出來的內容能達到系統提供包達不到,且是你需要的效果?(給我個確實靠譜的理由)然後我會要求對方盡量參照操作系統默認包的提供方式,提供一個可維護的第三方包,而不是直接編譯丟到某個目錄(更惡劣的當然是連目錄都不指定了)


其實我想說,自己用源碼編譯跟用RPM安裝並沒有非彼即此的矛盾,可以自己打RPM包,便於分發和管理。
可以參考 How to create an RPM package/zh-cn


各種軟體、庫的小版本號和編譯選項之間存在不可忽視的差異(及不兼容性),因此發行版預編譯的二進位包派不上什麼用場

另:rpmbuild和configure + make本質上是一樣的,都是要找齊源代碼並指定編譯選項編譯,只不過前者追加了一個打包機制。使用configure --prefix + tar一樣可以打包,而且這種方式還保留了安裝路徑的自由度


  1. 除去ubuntu,大部分的linux的server發行版都比較保守,能用穩定的就用穩定的。但實際使用場景非常複雜,很多時候對於新功能和已知bug的處理是需要很快上線的,所以這個時候必須自己編譯。
  2. 一致性的問題,寫文檔首先保證的是可重複,rpm包以及deb包都有大量的三方鏡像,這個時候如果文檔只提一個yum install 或 apt-get那麼可能在源頭上就造成文檔信息的偏差。
  3. 個性化模塊的定製,眾所周知軟體所含模塊越少複雜度就越低,產生問題的概率就相應降低,明確自己的需求選擇適合自己的功能在生產系統上或許才是最好的,這個時候就需要自行編譯。
  4. bug彙報以及和開發人員溝通,大量的rpm包和deb包並非官方的開發小組開發,這個時候如果使用rpm包或deb包進行安裝,那麼出現了bug你也只能等待包維護人員的處理,bug的反饋和修復將是一個非常漫長的過程,但如果直接源碼編譯安裝的話,出現問題直接提交bug report,這個時候你將會和一線開發人員直接溝通,加快問題的解決時間。

有兩個原因:

  1. 確實需要定製自己需要的功能,這需要很多知識和經驗積累,負責的人會這麼做
  2. 按照網上的所謂「教程」照搬步驟,成功之後如獲至寶,習慣成自然

個人認為第二種居多。做什麼事情都需要思考,不想思考的自然就怎麼習慣怎麼來。


給你1000台機器,讓你升級機器中的某個軟體到特定版本號,你會怎麼做?

這才是運維要面對的問題。

這個時候軟體本身是RPM還是源碼編譯好的tar包,有區別嗎?


================= UPDATE

我覺得要說得更清楚一點以免帶來誤解。

從源碼編譯安裝不是門檻!如果你認為這是個很高的門檻…招你做運維的人是你親戚吧?

源碼編譯安裝的主要目的是『抹平』不同系統默認軟體包中軟體編譯參數的不同。
對比一下nginx在Debian Sid和nginx官方提供RPM包中的編譯參數:

Debian Sid

# nginx -V
nginx version: nginx/1.4.3
TLS SNI support enabled
configure arguments: --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-log-path=/var/log/nginx/access.log --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --with-pcre-jit --with-debug --with-http_addition_module --with-http_dav_module --with-http_geoip_module --with-http_gzip_static_module --with-http_image_filter_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-http_xslt_module --with-ipv6 --with-mail --with-mail_ssl_module --add-module=/tmp/buildd/nginx-1.4.3/debian/modules/nginx-auth-pam --add-module=/tmp/buildd/nginx-1.4.3/debian/modules/nginx-dav-ext-module --add-module=/tmp/buildd/nginx-1.4.3/debian/modules/nginx-echo --add-module=/tmp/buildd/nginx-1.4.3/debian/modules/nginx-upstream-fair --add-module=/tmp/buildd/nginx-1.4.3/debian/modules/ngx_http_substitutions_filter_module

From http://nginx.org/packages/rhel/6/SRPMS/nginx-1.0.10-1.el6.ngx.src.rpm

./configure
--prefix=%{_sysconfdir}/nginx/
--sbin-path=%{_sbindir}/nginx
--conf-path=%{_sysconfdir}/nginx/nginx.conf
--error-log-path=%{_localstatedir}/log/nginx/error.log
--http-log-path=%{_localstatedir}/log/nginx/access.log
--pid-path=%{_localstatedir}/run/nginx.pid
--lock-path=%{_localstatedir}/run/nginx.lock
--http-client-body-temp-path=%{_localstatedir}/cache/nginx/client_temp
--http-proxy-temp-path=%{_localstatedir}/cache/nginx/proxy_temp
--http-fastcgi-temp-path=%{_localstatedir}/cache/nginx/fastcgi_temp
--http-uwsgi-temp-path=%{_localstatedir}/cache/nginx/uwsgi_temp
--http-scgi-temp-path=%{_localstatedir}/cache/nginx/scgi_temp
--user=%{nginx_user}
--group=%{nginx_group}
--with-http_ssl_module
--with-http_realip_module
--with-http_addition_module
--with-http_sub_module
--with-http_dav_module
--with-http_flv_module
--with-http_mp4_module
--with-http_gzip_static_module
--with-http_random_index_module
--with-http_secure_link_module
--with-http_stub_status_module
--with-mail
--with-mail_ssl_module
--with-file-aio
--with-ipv6
--with-debug
--with-cc-opt="%{optflags} $(pcre-config --cflags)"
$*

還有其他零零散散的不同(鏈接的哪個版本的openssl?編譯用的CFLAGS甚至是編譯器版本號?是否關閉了不需要的某個特性),讓運維最終選擇:自己編譯安裝打個tar包。


源碼-&>二進位文件-&>rpm-&>安裝
1. 源碼編譯生成二進位文件
2. 二進位文件打包成rpm
3. rpm安裝到系統當中
使用別的做好的rpm包源碼的版本和編譯參數不可控


伺服器部署三個階段 看看你的公司到哪個階段了

1 rpm/deb
2 make make install
3 rpm/deb


用RPM包安裝的概率遠遠大於源碼安裝,大部分人在解決軟體依賴的時候肯定會使用YUM(僅談F和R系統),這個時候其實就是RPM的安裝方式。在部署軟體的時候可能會遇到特定版本中間件(如NGINX,PHP等),需要安裝定製的插件,需要制定需要的路徑,這個時候選用源碼安裝就顯得更容易勝任。但是如果成規模的管理伺服器比如1000以上,至少100以上,如果相同的環境,需要相同的軟體,源碼安裝就顯得有點捉襟見肘了。使用安裝腳本只能避免不會出現差異化的環境,在部署效率上會大大降低。至少你還需要在每台機器上安裝編譯環境,至少降低了系統的安全和穩定性。(擁有編譯環境的生產伺服器多少還是有一些危險),而RPM執行效率就體現出來了。別人打包的RPM,在部署上方式看似有點滿山放羊,但其實符合標準FHS,我個人認為便於進行良好的維護,良好的RPM包也幫你完成很多事情比如自動創建SYSTEMD腳本,而不像源碼需要人工干預(如NGINX需要手工創建)。當然如果你需要自己定製RPM包,搭建私有源,無疑增加了學習成本。但確是軟體標準化、統一化管理的良好開端


rpmbuild需要花一定的時間才能搞明白它並用它,但是源碼安裝簡單容易,而且方便參數調優。
你是願意把時間花在打包上,還是參數調優上呢,或者喝茶。。。


總結:在測試環境 -&> 源碼 -&> 二進位文件 -&> 製作成rpm-&> 自建 yum 源 -&> 安裝(saltstack、ansible..)


如果源里有而且可以滿足需求,那麼你一定不會想去編譯。
題外話,
見過太多的麻瓜運維編譯Redis 2.8至今還在0.0.0.0 listen 6379的。。雖然源安裝不更新也是白搭,但至少比你編譯方便很多,喜歡用那些一鍵腳本啥的,他的機器大概率會加入botnet


第一 是規範 根據項目需求編譯安裝好軟體再做成Rpm包 這樣能保證環境統一性!
第二 yum安裝的不一定在版本,參數,擴展方面符合要求。


注重安全的公司都會以源碼包的形式發布 即使是開源,


玩源碼得好好理解下文件系統標準, 二進位包的發行版是不建議搞源碼的, 非得要編譯也得打成deb/rpm包, 有編譯癖的話上hardened gentoo吧. 豆瓣以前不就是gentoo么, deb和rh系的就別折騰了. gcc那些優化對現在的伺服器提升不大了.


制定的版本rpm包找半天沒找到,來個源碼包編譯安裝簡單省事


大規模的應用場景都是使用源碼編譯(定製),然後做成rpm包,之後再使用puppet,ansible等工具自動化安裝。


1 能夠自定義定製 用什麼編譯哪個模塊 還能自定義路徑 方便維護 rpm相對來說無法自定義路徑 而且目錄結構相對分散 較編譯安裝不利於後期維護
2 想刪掉 直接rm -rf 目錄 無需擔心系統的依賴文件被刪除 rpm想卸載 需要找到依賴關係 否則只能強制刪除 不利於版本升級
3 作為運維人員編譯安裝 更加能夠了解系統的整體架構 提高自身段位 自己裝一次gentoo比看書更有效


加一條:提升bigger。


自建yum源
編譯
fpm打包


spec文件並不複雜,測試環境編譯,正式環境rpmbuild做版本控制。


這個問題,做久一點運維自己就有判斷了。
我喜歡先用編譯安裝在測試機上通過,整個安裝過程熟悉,然後使用salt部署到線上環境。當然這樣做會讓自己對系統更了解。


也就是自個手動安裝和別人打包的區別,或者你自己打個包。

我偶爾封裝下Windows系統,都是根據母盤,其實沒什麼技術可言,根據自己的個性來定製相關軟體,一個萬能驅動包,就那麼回事了。

另外LS諸位說的很對啊,我來湊個臉熟。


推薦閱讀:

為什麼 Linux 在桌面會失敗?
Linux 中 rc.local、init.d、rc.x、init 這幾個文件(夾)各有什麼作用?啟動執行的腳本應該均放在 rc.local 中嗎?
有哪些命令行的軟體堪稱神器?
Windows系統的註冊表有哪些缺陷?
Linode 里為什麼 Ubuntu 最火呢?

TAG:Linux | 系統架構 | 運維工程師 | Linux運維 |