在過去幾年的DevOps的浪潮中,自動化、持續集成這兩個概念早已深刻人心(互聯網技術人)。比爾蓋茨先生曾經都說過:「任何技術在一個業務中使用的第一條規則就是,將自動化應用到一個高效的操做上將會放大高效。第二條就是自動化應用到一個低效操做上,則放大了低效率。」php
自動化部署也逐漸成爲各中小型企業追求的方向,那麼,今天民工哥就自動化部署的概述、自動化部署的工具、自動化部署的流程、自動化部署實踐等4個方面,與你們一同來討論、交流一下關於中小企業自動部署的問題。前端
一句簡單的話歸納:部署的過程當中全部的操做所有自動化,無需人工手工干預。java
傳統的部署方式以下:linux
運維人員手工使用Scp、Xftp等方式來傳輸數據git
手工登陸服務器執行git pull 、svn update等命令進行更新代碼的操做web
開發人員手工編譯打包,而後經過內網傳輸給運維人員shell
看似很是簡單,也不是很麻煩,可是一旦項目多,部署頻繁,這種狀況下就會大大下降工做效率。民工哥以前工做中就有這類體驗,公司的活動類項目高達100+,不少都是須要快速上線及下線、或者更新的,手工部署真的累。後端
傳統的部署方式有如下的缺點:centos
整個過程都須要人員參與,佔用大量的時間,效率低下api
上線、更新、回滾速度慢
因此,自動化部署的優點就經過這種對比顯現出來了!!
有自動動部署的概念,就須要自動化部署的工具,今天來介紹下一些這方面的工具給你們,怎麼用?如何用?你們根據實際需求來定,一切不以需求來定的工具、流程、方法等都是耍流氓。
Jenkins是一個開源軟件項目,是基於Java開發的一種持續集成工具,用於監控持續重複的工做,旨在提供一個開放易用的軟件平臺,使軟件的持續集成變成可能。Jenkins應該說是目前最好用的持續集成工具之一,它的插件很是多,安裝也很方便,功能至關的強大、靈活,最大的缺點就是學習成本較高。
ElectricFlow 是一個發佈自動化工具,提供免費的社區版本,你能夠在VirtualBox上運行。ElecticFlow支持大量插件和基於Groovy的 DSL,CLI,APIs。
微軟DevOps產品的基礎之一是 Visual Studio。 Visual Studio容許用戶定義版本定義,自動化運行,跟蹤版本等等。
Octopus Deploy建立目的是爲了.NET應用的自動化部署。你能夠在一臺服務器安裝或在Azure裏作成實例。
2013年被IBM公司收購,UrbanCode 自動化部署到本地或雲環境。
Amazon的自動化部署工具CodeDeploy,有着使人印象深入的客戶名單、平臺與語言無關。
DeployBot 能夠連接任何Git存儲庫,而且容許手動或自動部署到多種環境。DeployBot提供大量集成,包括經過Slack部署的能力。
Shippable 規定了它們本身的「DevOps支柱」和它們本身的CI平臺,運行依靠稱爲minions的基於Docker的容器。
TeamCity 是一個來自Jet Brains的CI服務器。TeamCity 有智能的配置功能和擁有官方Docker鏡像服務器和代理。
Bamboo Server 是CI,由來自在Atlassian的人們提供,他們是Jira和Confluence的製造者。Bamboo公佈「integrations that matter」並提供一個「small teams」包,捐贈給 Room to Read慈善事業。
Codar 是一個HP的持續部署解決方案。部署使用Jenkins觸發。
CircleCI 是一個CI解決方案,強調靈活性、可靠性和速度。CircleCI提供從資源到建立到部署的解決方案,而且支持大量的語言和應用。
Gradle 是一個被一些業內最有名的例如LinkedIn, Netflix, 和Adobe所使用的建立工具。Gradle使用Groovy建立腳本,按慣例構建框架,並認爲構建工具同時做爲Apache的Ant的通用工具。
Automic 試圖應用DevOps原理給一些後端應用,容許他們從已經在過去幾年裏許多前端、基於web的應用相同的實踐上受益。
Distelli 專門在任何地方部署Kubernetes集羣,除了能夠在任何雲或物理服務器上使用。根據TechCrunch這篇文章,Distelli 在2015年12月得到了280萬美圓的資金,是由前AWS員工Rahul Singh創立的。
XL Deploy 是一個來自XebiaLabs的應用發佈自動化工具,支持大量插件和環境,使用無代理架構。
Codeship是服務器託管CI解決方案,經過原生Docker支持定製。
一個CD服務器,強調可視化工做流,GoCD 是一個開源項目,由ThoughtWorks公司贊助開發。
Capistrano 是一個開源部署工具,使用Ruby開發。Capistrano 文檔具備腳本語言和「理智的,富有表現力的API。」
Travis CI 能夠同步到你的GitHub帳戶,容許自動化測試和部署。Travis CI是一個免費的開源項目。
BuildBot 是一個開源的基於Python的持續集框架,自稱爲「內含有電池的框架」。BuildBot是面向罐裝的解決方案用例,目前還不夠靈活。
大概的流程步驟以下:
獲取代碼
編譯打包
移除目標服務器
解壓文件到目標目錄
拷貝差別化文件
重啓服務
測試
從新加入集羣
若是在測試時出現問題,則須要回滾到上一次穩定版本。
通常能夠將須要回滾的版本先列出來,而後將現有的軟連接文件刪除,從新將上一個版本的源文件生成一個軟連接至目標目錄,而後從新啓動服務,進行自動化測試,最終加入集羣。
說完了一堆的理論東東,接下來就是須要實踐操做了,我以前也寫過一個自動化的腳本,以下圖:
這裏列舉兩個實例,這兩個實例是由網友西門飛冰投稿提供,具體的實例以下:
腳本使用環境:
一、操做系統:centos 6.5 64位
二、代碼使用gitlab進行管理
三、代碼每次上線經過tag控制
四、前端使用haproxy實現負載均衡,使用haproxy socat實現RS的平滑上下線
五、WEB container使用tomcat實現
六、項目構建使用maven
使用腳本注意事項:
一、 發佈機器須要可以解析web服務器主機名,而且配置ssh通訊
二、 變量中的目錄以及用戶等信息須要本身建立,腳本沒有作判斷本身建立。我這裏web服務器是使用ansible進行部署的,相關目錄和用戶都會自動建立。
三、代碼的部署使用tag,可是代碼的更新使用軟鏈接來控制,回滾則切換到上一個軟鏈接
四、因爲java是編譯型語言,咱們使用maven來進行編譯,因此須要安裝maven環境。
五、關於環境配置文件:配置文件爲本身手動維護,每次都是刪除git倉庫拉取下來的配置文件,把對應環境的代碼文件複製進編譯目錄進行編譯。
腳本代碼大概的步驟以下:
#!/bin/bash # 設置時間變量 CTIME=$(date "+%Y-%m-%d-%H-%M") # 項目名稱,建議和gitlab倉庫名稱一致 project= # 本地代碼目錄(gitlab拉取代碼後存放目錄) CODE_DIR=/data/gitlab/"$project" # 臨時代碼目錄,用來修改配置文件和編譯打包代碼 TMP_DIR=/data/tmp/"$project" # 用來存放war包 WAR_DIR=/data/war/"$project" # 對應環境配置文件 deploy_conf=/data/conf/pro/"$project"/* # 代碼中的配置文件路徑 local_conf=$TMP_DIR/src/main/resources/config # 遠程主機名稱 REMOTE_HOST="tomcat-01 tomcat-02" # 遠程主機代碼目錄 REMOTE_CODE_DIR=/data/webapps/"$project" # 遠程主機用戶 REMOTE_USER=root # 遠程主機war包存放目錄 REMOTE_WAR_DIR=/data/war/ # 代碼臨時目錄 CODE_TMP=/data/code_tmp/ # 上線日誌 DEPKOY_LOG=/data/log/pro_log.log # 腳本使用幫助 usage(){ echo $"Usage: $0 [deploy tag | rollback_list | rollback_pro ver]" } # 拉取代碼 git_pro(){ if [ $# -lt 1 ];then echo "請傳入tag" exit 1 fi tag=$1 cd $CODE_DIR && git checkout master && git pull && git checkout $1 if [ $? != 0 ];then echo "拉取代碼失敗" exit 10 fi cd $CODE_DIR && git pull 2>/dev/null >/dev/null # 推送代碼到臨時目錄 rsync -avz --delete $CODE_DIR/ $TMP_DIR/ 2>/dev/null >/dev/null } # 設置代碼的配置文件 config_pro(){ echo "設置代碼配置文件" rm -f $local_conf/config.properties ......... } # 打包代碼 tar_pro(){ echo "本地打包代碼" cd $TMP_DIR && /usr/local/maven/bin/mvn clean compile war:war && cp target/"$project".war "$WAR_DIR"/"$project"_"$tag"_"$CTIME".war } # 推送war包到遠端服務器 rsync_pro(){ echo "推送war包到遠端服務器" for host in $REMOTE_HOST;do scp "$WAR_DIR"/"$project"_"$tag"_"$CTIME".war $REMOTE_USER@$host:$REMOTE_WAR_DIR done } # 解壓代碼包 solution_pro(){ echo "解壓代碼包" for host in $REMOTE_HOST;do ssh $REMOTE_USER@$host "unzip "$REMOTE_WAR_DIR""$project"_"$tag"_"$CTIME".war -d "$CODE_TMP""$project"_"$tag"_"$CTIME"" 2>/dev/null >/dev/null done } # api測試 test_pro(){ # 運行api測試腳本,若是api測試有問題,則退出部署 if [ $? != 0 ];then echo "API測試存在問題,退出部署" exit 10 fi } # 部署代碼 deploy_pro(){ echo "部署代碼" ................... sleep 3 # 執行api測試 test_pro ssh haproxy "echo "enable server $project/$host" | /usr/bin/socat /var/lib/haproxy/stats stdio" done } # 列出能夠回滾的版本 rollback_list(){ echo "------------可回滾版本-------------" ssh $REMOTE_USER@$REMOTE_HOST "ls -r "$CODE_TMP" | grep -o $project.*" } # 回滾代碼 rollback_pro(){ echo "回滾中" for host in $REMOTE_HOST;do ............................. sleep 3 ssh haproxy "echo "enable server $project/$host" | /usr/bin/socat /var/lib/haproxy/stats stdio" done } # 記錄日誌 record_log(){ echo "$CTIME 主機:$REMOTE_HOST 項目:$project tag:$1" >> $DEPKOY_LOG } # 代碼執行選項設置 main(){ case $1 in deploy) git_pro $2; config_pro; tar_pro; rsync_pro; solution_pro; deploy_pro; record_log $2; ;; rollback_list) rollback_list; ;; rollback_pro) rollback_pro $2; record_log; ;; *) usage; esac } main $1 $2
腳本適應環境:
一、操做系統:centos 6.5 64位
二、代碼使用gitlab進行管理
三、代碼每次上線和回滾經過tag控制
補充:若是須要在你的企業使用個人這種部署方式,還須要有相應環境規範以及git分支管理規範。
一、 發佈機器須要可以解析web服務器主機名,而且配置ssh通訊
二、 變量中的目錄以及用戶等信息須要本身建立,腳本沒有作判斷本身建立。我這裏web服務器是使用ansible進行部署的,相關目錄和用戶都會自動建立。
三、代碼的部署使用tag,回滾原則爲回滾到上個tag版本,因此部署腳本自己沒有備份代碼。
四、若是須要過濾一些臨時目錄或者日誌目錄,能夠在rsync推送代碼的時候使用–exclude選項進行過濾,示例腳本中過濾了.git目錄和config.php文件是不會部署的。
#!/bin/bash # 設置時間相關變量 CTIME=$(date "+%Y-%m-%d-%H-%M") # 項目名稱,建議和gitlab倉庫名稱一致 project=test # 本地代碼目錄(gitlab拉取代碼後存放目錄) CODE_DIR=/data/gitlab/pro/$project/ # 遠程主機 REMOTE_HOST="LNMP-01.fblinux.com LNMP-02.fblinux.com" # 遠程主機代碼目錄 REMOTE_DIR=/data/www/fblinux/ # 遠程主機用戶 REMOTE_USER=root # 遠程主機代碼執行用戶 CODE_USER=php # 上線日誌 DEPKOY_LOG=/data/log/pro_log.log #腳本使用幫助 usage(){ echo $"Usage: $0 [deploy tag]" } #拉取代碼 git_pro(){ if [ $# -lt 1 ];then echo "請傳入tag" exit 1 fi echo "拉取代碼" cd $CODE_DIR && git checkout master && git pull && git checkout $1 if [ $? != 0 ];then echo "拉取代碼失敗" exit 10 fi cd $CODE_DIR && git pull } #推送代碼服務器 rsync_pro(){ for host in $REMOTE_HOST;do echo "推送代碼到服務器$host" rsync -rPv -P --delete --exclude="config.php" --exclude=".git" $CODE_DIR -e 'ssh -p 22' $REMOTE_USER@$host:$REMOTE_DIR if [ $? != 0 ];then echo "推送代碼失敗" exit 10 fi echo "代碼受權" ssh $REMOTE_USER@$host "chown -R $CODE_USER $REMOTE_DIR" if [ $? != 0 ];then echo "代碼受權失敗" exit 10 fi done } #記錄日誌 record_log(){ echo "$CTIME 主機:$REMOTE_HOST 項目:$project tag:$1" >> $DEPKOY_LOG } main(){ case $1 in deploy) git_pro $2; rsync_pro; record_log $2; ;; *) usage; esac } main $1 $2
以上就是兩個實際的生產部署實例的配置環境、注意事項及代碼等講解。
讀者若是須要上述兩個實例的完整代碼請在 民工哥技術之路 公衆號後臺回覆 「自動化部署」來獲取腳本完整代碼的下載地址。
參考資料以下:
https://dzone.com/articles/21-automated-deployment-tools-you-should-know