咱們今天的話題是中小企業如何實現自動化部署。那麼,爲何定位中小企業呢?html
由於每每中小企業面臨着運維人員有限,成本投入有限,可是版本更新快,並且服務器數量卻並很多的狀況。node
中小企業甚至,基本不會投入運維開發來開發自動化部署平臺。那麼,咱們今天就拿運維工程師都熟悉的Shell進行舉例,談談如何來進行一個自動化部署的設計。git
本次分享主要包括以下內容:web
中小企業自動化部署的設計算法
如何在資源有限時開發自動化部署平臺shell
部署的技巧與流程後端
FAQ(有彩蛋喲,不容錯過:)緩存
在開始以前咱們須要先統一認識,在IT管理裏面有三大核心要素,簡稱PPT,即:服務器
人員/組織架構(People);架構
流程(Process);
技術/工具(Tech/Tool)。
因此說設計一個自動化部署系統,並不簡單是上線幾個工具,寫幾個自動化腳本這麼簡單。不過本文咱們簡化流程,主要是聊聊生產環境的自動化部署系統。
同時經過這個「PPT」,咱們也認識到了,設計一個流程,除了流程自己要和咱們的組織架構、人員和技術掛鉤,也須要根據企業的實際狀況來作,不能好高騖遠,夢想着一上來就設計一個龐大的自動化部署平臺。這可能並不符合企業現狀,又浪費了資源。
同時還有一點就是流程思路很重要,具體的實現方法不少,看團隊的技術水平,可使用Python、Shell、PHP等來實現。
好的,咱們統一了認識,下面來肯定下目標。中小企業的部署現狀就是更新快,可能常常性的測試不到位(因此,就須要快速回滾)。單業務的集羣規模在基本上在100臺之內。那麼咱們的主要目標是:
一鍵上線
秒級回滾
本文的重點就是流程設計。上面說了,因爲篇幅有限咱們簡化流程。完整的上線流程,可能經歷開發環境、測試環境(功能測試、性能測試、預生產測試)、生產環境。
本次我就來談談生產環境如何自動化部署(假設如今新的功能已經在開發和測試環境就緒,Git或者svn倉庫已經存放了能夠上線的代碼)。
我相信有讀者目前的上線是使用管理工具,批量在全部服務器上執行svn update或者git pull。固然,我還見過每次上線執行rsync進行代碼部署的。
咱們下面的流程或許會完全改變你的思路。不要驚訝,本來上面的方法也沒有什麼錯,只要符合企業需求就能夠,可是咱們能夠作的更好。
直接上部署流程圖:
流程分析
我想,看到這樣的流程可能不少朋友在心中會有一些疑問,咱們慢慢來分別闡述下,這樣設計的思路、設計原則和目的。
這一步的疑問最少,咱們能夠經過svn或者git進行獲取,也能夠指定svn版本號或者git的tag,commit id,或者直接獲取最新代碼均可以。
注意,你須要在專用的部署服務器進行這樣的操做,而不是各個Web服務器。
這個是可選的,若是你是Java,則須要進行編譯,好比Ant或Maven就能夠方便的幫你完成,Python和PHP則不須要進行編譯操做,能夠忽略。
總之,最後你有了一個目錄,這個目錄裏面是準備上線的代碼。須要注意的細節是,包名(目錄名)的設計,能夠涉及到環境、包名、版本號和時間。以下面的名稱:
prod_web_xxxxx_2015-09-09-10:10
這樣,你這個部署系統(腳本)能夠支持多個環境。這裏有人會問配置文件不該該在代碼倉庫裏面嗎?
不是的!至少重要的和差別性的配置文件是須要單獨進行管理的,尤爲是涉及到支付、驗證類的配置。
最佳實踐是:最好給配置文件單獨作一個版本庫進行管理,同時能夠經過目錄來區分是測試仍是生產,只有相關的負責人才有權限進行更新和提交。這樣的話,你須要將配置文件copy到代碼目錄下。
直接使用tar czf 打一個包就能夠了。
如今能夠將須要部署的代碼包COPY到目標服務器,好比你可使用SCP。同時你能夠在打包的時候給這個包生成一個md5文件,scp完畢後可使用md5sum驗證一下包的完整性。
先舉一個反例,有些朋友可能這樣操做,在部署時,直接部署和重啓Web服務,讓負載均衡的健康檢查工做自動將節點踢出集羣?
想這麼搞的話的朋友,須要想想了,這作法也太暴力了。
咱們知道負載均衡的健康檢查也是有時間間隔、次數的,若是你直接重啓了後端Web服務,那麼在負載均衡作判斷後端主機是否下線的時間範圍內,用戶的請求可能就會失敗。
因此,咱們要提早將要部署的後端節點拿出集羣,好比Haproxy,你能夠經過socat和Haproxy Unix Socket進行通訊,實現部署節點的開啓和關閉,以下所示:
關閉節點: echo "disable server www_example_com/web-node1" | socat /usr/local/haproxy/haproxy.sock stdio 啓用節點: echo "enable server www_example_com/web-node1" | socat /usr/local/haproxy/haproxy.sock stdio
在目標服務器上解壓這個軟件包,不管你是用管理工具如Saltstack仍是SSH均可以輕鬆搞定。
好的,這就是咱們設計的重點了,咱們使用軟鏈接的方式來管理包的更新。好比咱們的Web根路徑是/var/www/html/webroot,咱們把全部的代碼都存放在/data目錄下,那麼webroot其實是一個軟鏈接,它連接到當前的版本,好比prod_web_xxxxx_2015-09-09-10-10。這樣的話,webroot實際是這樣
webroot -> /data/prod_web_xxxxx_2015-09-09-10-10/
我想,不少朋友,看到這裏就明白了,這回滾絕對是秒級啊,只須要從新建立一個軟鏈接便可。
同一個集羣中,存在不一樣的配置文件,這很常見,好比我須要在某個節點跑一些定時任務,好比Java可使用Quartz來實現,只須要一個crontab.xml便可,那麼咱們就須要把這個差別文件在這個時候scp進去。
這個是可選的,若是是Java,運行的Tomcat,就須要重啓Tomcat,別忘記清理相關的Tomcat緩存哦。
若是有的話,固然好了,你調用一個接口就能夠進行測試。而後等待測試完畢再繼續。若是沒有測試團隊提供這樣的接口,那麼curl能夠幫你輕鬆的實現,把重要的接口訪問一遍,判斷下返回碼或者返回內容便可。
好的,這個節點部署完畢了,把他加入集羣吧。還記得剛纔說的socat嗎。
說了這麼多,原來只是一個節點啊。那麼繼續吧,可能這個只是for循環中的一部分哦,是否是想到了shell該怎麼寫了。
這裏把實際使用的時候可能有用的小技巧分享下:
分組部署:
爲何要分組?上面的流程中,你會發現,每次部署都會在重啓和自動化測試那裏等待很久。
由於你要等待Web服務的重啓,好比Tomcat。那麼如何減小這個時間呢?
答案就是分組部署,將該業務的服務器進行分組,好比group一、group二、group3:
那麼部署group1到重啓那裏後,流程不往下走了,直接部署group2;
當group2部署完畢,停下來開始對group1進行自動化測試,測試完畢添加到集羣;而後繼續部署group3。
當group3部署完畢後,再來自動化測試group2,而後你懂的。
日誌記錄:
沒有日誌記錄功能的腳本就是耍流氓!你必須清楚的知道目前腳本在幹啥,幹到哪裏了,若是有報錯就能夠及時的定位問題。
部署服務器雙機:若是這臺部署服務器宕機會怎麼樣?因此這臺部署服務器必須是雙機的。包括部署腳本應該是使用svn或者git來作版本控制。應該有詳細的部署腳本的設計、使用文檔。別忘了,文檔化建設是流程設計必備的內容之一。
我想通過部署流程,你們很容易就想到了下面的流程,咱們主要能夠簡單的闡述下:
列出回滾版本:ls –l能夠了吧,只要列出能回滾的版本便可。
目標服務器移除集羣:同部署操做。
執行回滾:刪除舊的軟鏈接,建立到指定版本的軟鏈接
重啓:可選的
自動化測試:同部署操做
加入集羣:同部署操做
Next:繼續下一個節點
OK,這是一個回滾的流程。若是僅僅這樣是遠遠不夠的,別忘了咱們的定位是中小企業,每每我見到更多的狀況是回滾是遇到了沒有測試出來的比較大的bug。
那麼咱們就須要一個緊急的回滾流程。這種狀況下,暴力一點多是最佳選擇了。
執行回滾:對,不要列出來了,直接就用上一個版本便可。因此注意,部署的時候你須要記錄上一個版本是什麼。
重啓:可選。顧不了那麼多了,如今是和時間賽跑。那麼注意了,你的上一個版本須要是一個可用的版本,若是你沒法記錄,那麼可能須要把列出版本再加上了。
好的,咱們的流程設計結束了,先在腦子裏想明白,而後拿起Shell開始實現吧。會有不少小細節須要注意哦,我相信這難不倒你。
問:有沒有完整的自動化部署的流程圖能夠參考?
還真有,以前畫過一個,請你們參考。目前咱們IAAS這塊主要以Open Stack爲主,Mesos+Docker也正在研究中。
問:大家是否考慮使用Jenkins來實現自動化部署呢?
實際上,咱們測試環境的自動化部署是使用的Jenkins。開發能夠自助進行部署操做,同時也集成了代碼審查和代碼質量管理的流程。
可是咱們生產環境沒有使用Jenkins,主要是咱們自動化測試還跟不上,每每不少發佈須要人肉測試。整個流程沒法完美銜接,因此就分開了。因此咱們生產部署其實產品發起,測試審覈(測試),而後測試人員進行部署上線。
並且生產環境並非測試人員ssh到服務器執行咱們編寫的腳本(他們沒有權限),咱們基於SaltStack開發了Job管理平臺,測試人員在Job管理平臺上進行部署操做。
問:部署的一致性怎麼保證的,好比剛更新的服務器和集羣中的其它服務器版本不一致?
首先,平常的變更和更新是不會有這樣的問題,若是有大的變更,不推薦在運維部門來實現,更好的實現方法是:好比在SOA的各個服務之間,加入API版本號的實現,實現多個版本並存。
若是你發現有不一致的狀況,試試Nginx的ip_hash,或者Haproxy的source的負載均衡算法,讓某個用戶的請求一直落在某個節點,即實現了會話保持,也解決了你的疑慮。這樣作固然也有不少缺點,看你的選擇了。
問:咱們是否能夠將線上部署修改成本文設計的流程?
歡迎使用,並且咱們後期還會提供Shell腳本模板。
這個流程的設計背景是一個電商的架構,物理機+虛擬機,供300多臺的規模,使用了SOA。
可是,當時重構部署流程也經歷了很長一段的時間,並且須要運維頂着很大的壓力和責任,必定要充分測試,分批上線。