初創(chuàng)公司應該如何做好持續(xù)集成和部署?
作者介紹
裴雙才,Geekwolf,現(xiàn)MAKA運維負責人,博客: http://www.simlinux.com。《FastDFS分布式存儲實戰(zhàn)》作者,《Ansible中文手冊》譯者。RHCA/RHCVA,混跡各種開源社區(qū),專注高效運維、DevOps、性能優(yōu)化、Docker、MySQL等方向,熱衷技術(shù)分享,歡迎一起討論技術(shù),互相學習,共同進步。
前言
持續(xù)集成和部署是每一個互聯(lián)網(wǎng)開發(fā)團隊都必須要面對的問題,特別是在初創(chuàng)公司,由于業(yè)務(wù)和技術(shù)團隊快速增長,技術(shù)積累較弱,所以一個高效的,可持續(xù)的運維規(guī)范尤為重要。
最近一段時間,一直在梳理項目開發(fā)流程以及自動化測試和部署規(guī)范,作為一個總結(jié)和大家分享,希望有所幫助。
高效可持續(xù)的運維環(huán)境需要合理的規(guī)范作為支撐:
- 應用管理規(guī)范
- 權(quán)限管理規(guī)范
- 配置變更規(guī)范
- 發(fā)布策略規(guī)范
- 日志運維規(guī)范
持續(xù)集成部署實戰(zhàn)(該內(nèi)容將在后續(xù)文章中進行討論,本次不展開)
一、應用管理規(guī)范
1. 應用版本化
可以使用SVN、Git對代碼進行版本控制。
建議使用Git(如:GitLab),并使用Git Group命名規(guī)范:大原則為根據(jù)產(chǎn)品域名區(qū)分,或者根據(jù)前后端業(yè)務(wù)模塊進行分組(小寫字母命名,橫杠[-]作為連接字符)。
舉例:
MAKA官網(wǎng) http://www.maka.im 對應的Git倉庫Group為official,按照功能模塊分組,商城前端對應的Git倉庫Group為store。
項目名命名規(guī)范:
- 全部用小寫字母
- 橫杠[-]作為連接字符
- 命名規(guī)則:[產(chǎn)品名稱]-[項目類型]-[自定義名稱]
舉例:
official-store-customer。
實踐建議:在創(chuàng)建項目倉庫時就要權(quán)衡前后端或者大的功能模塊的拆分,保持低耦合度。
2.合理的分支策略
常用的Git工作流總結(jié)如下:
第一種:集中式工作流,很多公司使用SVN,對Git的使用并不熟悉。如果遷移至Git之后,可以考慮集中式工作流進行開發(fā),即代碼庫只有 master 一個分支,所有開發(fā)者只有本地 master 和遠端 master 分支。這種方式使用簡單,但無法充分發(fā)揮 git 的優(yōu)勢。
第二種:功能分支工作流, 與上一種不同的地方在于,除了 master 分支以外還有功能分支。日常開發(fā)在功能分支,提測集成時提交Merge Requests(在Bitbucket中是Pull Request)。
開發(fā)者可以在這個時候進行討論、審核代碼,同意后可以合并至 master 分支,未同意則可以讓開發(fā)者修改后重新提交或者選擇關(guān)閉該MR。
舉例: third-party-login-feature
第三種:Gitflow工作流,兩個主干分支 master(正式發(fā)布分支)和 develop(功能集成分支)。
開發(fā)者應基于 develop 分支創(chuàng)建 feature 功能分支,用于開發(fā),開發(fā)完成后提交merge requests請求合并進 develop 分支。
此時若到了發(fā)布窗口,基于此時的 develop 分支創(chuàng)建發(fā)布分支 release 用于測試 → 預發(fā)布 → 發(fā)布,以避免影響 develop 分支的正常集成、合并功能分支;release 分支不再有新的功能合并進來,一旦創(chuàng)建只用于 bug 修復并將修復 cherry-pick 到develop分支;發(fā)布完成后,release 分支合并進 master 并分配版本號、打tag,用于存放發(fā)布歷史。
Gitflow工作流方式適用于大型項目
第四種:Forking工作流,開發(fā)者 fork 官方的 repo 到自己的賬號空間,對于官方分支只有只讀權(quán)限,開發(fā)者通過pull request 提交給官方審核是否合并進代碼庫;開發(fā)者通過同步上游官方的 repo 來使用其他人的代碼,分支策略可參考上述三種工作流,適合開源項目。
針對創(chuàng)業(yè)公司參與同一個項目的開發(fā)者并不多,過于復雜的分支策略并不能帶來便利,可以參考 leancloud 的分支模式,根據(jù)團隊的使用情況進行調(diào)整。
介紹下我們當前使用的分支策略:
- master:主干分支,用作日常開發(fā)的基線;
- userA:開發(fā)者A日常開發(fā)所在分支;
- release-201603091106: master分支集成測試完成后,構(gòu)建到預發(fā)布環(huán)境時自動創(chuàng)建 release-201603091106 用于發(fā)布。
- hotfix-201603091106: 基于當前發(fā)布之后的 release-201603091106 分支用于修復bug,通過提交merge requests 方式合并進 release-201603091106,并將修復 cherry-pick 到master分支。
日常開發(fā)在 userA 分支操作,然后提交merge requests 請求合并至 master 分支,本地通過 git fetch origin master,然后在 userA 分支 git rebase origin/master 將 master 最新 commit 合并到本地 userA 分支從而形成閉環(huán)開發(fā)。
3.關(guān)于代碼審核
三劍客 GitLab + Jenkins + Gerrit。
Gerrit作為創(chuàng)業(yè)公司代碼審核工具略顯復雜,不足夠敏捷,建議使用GitLab的 Merge Requests 或者 Github 和 Bitbucket 中的 Pull Requests 作為代碼審核和討論的工具。
也可以選擇 Facebook 的 Phabricator (可同時作為代碼托管和評審,非常敏捷,由于 Phabricator 提供的工具集在 Windows 下使用起來不太友好,后來沒有選用,后期會分享 Phabricator 的使用思路和工作流)
4.目錄結(jié)構(gòu)
規(guī)范的目錄結(jié)構(gòu)不僅有利于開發(fā)者理解代碼結(jié)構(gòu),更有利于代碼的快速部署,以PHP為例,目錄結(jié)構(gòu)建議將代碼配置文件(如:數(shù)據(jù)庫,Redis,OSS Key,語言開關(guān),日志級別開關(guān)等)、日志文件,其他文件緩存等獨立于代碼庫之外存放。
前端項目 src 為源碼目錄,dist為前端經(jīng)過壓縮合并等最終生成的代碼目錄(發(fā)布時可忽略src)。
每個項目詳細寫 README.md 文件,詳細說明,各個環(huán)境對應的訪問路徑、目錄說明、構(gòu)建壓縮方式,Nginx配置等,代碼倉庫中包含額外的 test 目錄存放測試用例(本著誰開發(fā)誰寫測試用例的原則)。
二、權(quán)限管理規(guī)范
權(quán)限有兩類:一個是系統(tǒng)權(quán)限(包括服務(wù)器登陸,數(shù)據(jù)庫/Redis等),另外一個是服務(wù)運行時的權(quán)限。
1. 系統(tǒng)權(quán)限
統(tǒng)一入口,受限訪問IP,禁止空密碼弱口令,生產(chǎn)環(huán)境服務(wù)器需要先撥入vpn之后通過跳板機才能連接成功(當然我們使用的是開源當中最好的跳板機Jumpserver),任何人的操作都需要審計;
生產(chǎn)數(shù)據(jù)庫及Redis禁止了外網(wǎng)訪問,分別使用phpMyAdmin和RedisLive統(tǒng)一訪問入口,增加了多主機訪問及屏蔽了危險操作如DDL 數(shù)據(jù)的導入導出等。也需要先撥入vpn才能訪問。
開發(fā)測試環(huán)境權(quán)限控制相對寬松,DEV Leader 和 QA Leader同時具有開發(fā)和測試環(huán)境的服務(wù)器及數(shù)據(jù)庫權(quán)限,便于測試和Debug;
生產(chǎn)環(huán)境為了便于開發(fā)調(diào)試生產(chǎn)代碼,且不影響線上,增加了 Staging 節(jié)點,未在線,但環(huán)境代碼及后端均和生產(chǎn)一致;
2. 針對服務(wù)權(quán)限層面
以 Web 服務(wù)為例,Nginx 和 php-fpm 運行用戶和用戶組為:www-data;代碼目錄用戶為www。
這樣代碼目錄默認情況下web服務(wù)只讀,避免出現(xiàn)文件和目錄777權(quán)限的情況;
日志和緩存目錄用戶設(shè)置www-data,但要禁止訪問php等動態(tài)文件。
禁止危險函數(shù)phpinfo exec eval system 等,具體可參考:
http://www.sinacloud.com/doc/sae/php/runtime.html
禁止跨目錄訪問open_basedir,開啟前后的性能對比請參考:
http://www.simlinux.com/archives/1531.html
三、配置變更規(guī)范
1.系統(tǒng)部署
傳統(tǒng)IDC機房可以通過定制鏡像或者使用 Cobbler 定制安裝,運行的服務(wù)也可以定制在鏡像中,但建議安裝系統(tǒng)時注冊puppet/salt agent,再自動化部署相關(guān)服務(wù)。
公有云中可以在服務(wù)器上部署相應環(huán)境后創(chuàng)建系統(tǒng)快照,制作系統(tǒng)鏡像,彈性擴容時可選擇該鏡像自動化安裝。
2.日常變更
日常變更包括服務(wù)配置的變更和代碼配置的變更,這些操作我們是通過 Ansible,相比 puppet/salt 的好處就是簡單方便不用裝agent,后面會詳細介紹如何基于Ansible做發(fā)布回滾。變更的內(nèi)容使用git進行版本控制。
四、發(fā)布策略規(guī)范
1. 發(fā)布時間
注意:以上請根據(jù)自己業(yè)務(wù)做相應調(diào)整,避免在業(yè)務(wù)高峰期發(fā)布(除應急bug外)。
我們業(yè)務(wù)高峰期基本在18:00-23:30,低峰期基本在01:00-06:00。這也是微信分享閱讀的高峰和低峰時段。
無論應急Bug還是日常迭代都必須由QA測試通過和產(chǎn)品經(jīng)理審核通過后才能上線。
血的教訓:曾經(jīng)出現(xiàn)過開發(fā)為了修復線上很急的bug,開發(fā)修復后自主上線導致生產(chǎn)出現(xiàn)更嚴重的問題。
2. 發(fā)布工具的選擇
無論是自主開發(fā)發(fā)布系統(tǒng),亦或是使用開源的系統(tǒng)都要本著解決問題的原則,否則只能是重復造輪子,然并卵呀!
開源的持續(xù)集成和發(fā)布里面?zhèn)€人覺得比較好的如:Jenkins,Walle,Spinnaker,go,Gitlab-ci,Bamboo(收費)等,其他參考。
https://github.com/geekwolf/sa-scripts/blob/master/devops.md
下面介紹我們基于GitLab + Jenkins + Ansible(Flamingo自動化代碼發(fā)布工具)實現(xiàn)的自動化代碼部署平臺,流程如下:
Flamingo:(“火烈鳥”,https://github.com/geekwolf/flamingo)是基于Ansible的自動化代碼發(fā)布工具,目的是實現(xiàn)統(tǒng)一的代碼發(fā)布方式,思路基于Capistrano,并對Ansisrano進行了改造可以通過傳入語言環(huán)境,主機組(應用組/灰度機組等),項目代碼庫,分支名稱,項目名稱等參數(shù)來進行自動化打包發(fā)布,也可以將Flamingo工具二次打包使用。
Flamingo本著回滾即發(fā)布的原則,以簡化發(fā)布流程,回滾時傳入要回滾的分支即可,其他參數(shù)可參看defaults/main.yml進行了解;(注:依賴Git/rsync/ansible)
例子:
- ansible-playbook deploy.yml
- --extra-vars='flamingo_git_repo=git@github.com:geekwolf/flamingo.git flamingo_product_name=flamingo'
執(zhí)行后生成的目錄結(jié)構(gòu)如下圖(目錄定義請參考defaults/main.yml):
五、日志運維規(guī)范
毫無疑問,規(guī)范的日志對于運維和開發(fā)排查問題有非常大的幫助,例如PHP項目日志格式可以規(guī)范為時間,日志級別,日志內(nèi)容(比如對于連接多個DB時出現(xiàn)連接不上或超時應該把實例地址一同寫入日志),可以參考psr-3的標準:
http://www.php-config.org/psr/psr-3
通過ELK將業(yè)務(wù)日志,PHP自身錯誤日志/慢日志,Nginx慢日志等進行搜集統(tǒng)計并結(jié)合Zabbix實現(xiàn)報警,便于及早發(fā)現(xiàn)問題。
六、持續(xù)集成部署實戰(zhàn)
后續(xù)篇章會分享針對PHP/JAVA/前端以及Android/ios持續(xù)集成和部署實戰(zhàn),敬請關(guān)注。
總結(jié)
以上只是粗略對持續(xù)集成和部署過程中遇到的問題進行了總結(jié),并不完美,但對于初創(chuàng)公司應該有些幫助,歡迎一起學習討論!