這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
【編者的話】本次主要分享Git 多分支 pull request 工作方式配合 Docker 在持續整合方面的應用。
首先介紹我們公司和團隊的情況,kingdee 雲之家,主要是做企業社交,其中包括 im,微博等,我們的服務主要包括免費的公用雲端服務,和各個企業的私人雲端部署,其中萬科、海爾都是我們的客戶。
再看看我們現在的系統和技術棧的情況:
- 現在的系統中存在 449 項目。
- 開發使用的技術棧有Java(標準容器項目使用 Jetty、Play 項目)、Node.js、PHP等百花齊放。
- 兩條產品線,將近 100 來號開發人員。
- 我們還有很多企業的私人雲端部署需求。
在如此多項目和人員情況下,產品迭代又非常快,這就要求我們能夠支援開發部門。下面我們說說在如此情況下我們遇到的一些實際問題:
開發工程師說:
- 誰又收走了我 MQ 中的資料?
- 誰改動了 API 的代碼,導致我的程式碼報錯?
- 本地程式修改部署,其中出現個以上問題,一上午就過去了。
- ……
測試工程師說:
- dev 環境老是在部署,導致沒有辦法測試。
- 測試一個 bug 時,別人提交了代碼,導致另外的 bug。
產品經理說:
- realease 分支的代碼合并導致了將其他沒有完成的功能發版正式環境。
- 由於相互依賴導致自己開發好的功能必須等其他人。
- 以上問題導致功能進度不能如期。
上面的各個角色都有自己的痛點,我們來分析下上面的情況造成的原因,其實大部分的情況是由於各個環境的隔離不夠造成的,知道原因後我們來看看我們的應對策略:
- 劃分好各個角色的邊界;
- 採用 Pull-Request 的做法。
那我們先來看看我們的基礎設施和角色:
- 開發工程師
- 測試工程師
- 產品
- 其他
然後我們再來劃分下各個角色的邊界:
- 開發工程師應該只用關注 GIt 上的代碼和 JIRA 上的 bug 和 new feature。
- 測試工程師只關注 JIRA 的 bug 和 new feature 的測試。
- 產品和其他人只關注 JIRA 提交的 bug 和 new feature的解決。
角色的劃分,和我們的基礎設施看完了,來看看現在 Git 上的分支視圖,假設我們現在有兩個主分支
- master:代表的開發部分穩定分支
- release:代表線上穩定分支
我們的角色邊界和基本涉及到的設施夠看完了,現在看看開發工程師如何工作的:
- 第一步:根據 jira 上 bug 或者 new feature 從 master 上 fork 一個對應的分支 iss001。
- 第二步:開發工程師,在 fork 的分支上提交代碼,git hook 會通知 jenkins build 相應的 image。
- 第三步:jenkins 會把相應的 image 部署到伺服器叢集中,開發人員就可以通過
iss001.kingdee這個網域名稱訪問剛剛對應分支的服務了,iss001 對應的 fork 分支的名稱,我們要求唯一。
我們來看看測試工程師是如何工作的:
- 第一步:測試工程師經過驗證後,這個 bug 或者 new feature 的功能完成,會把代碼 merge 進入 master分支,在這分支上做效能測試和煙霧測試 (Smoke Test)。
- 第二步:經過效能測試和煙霧測試 (Smoke Test)後,就可以通過 cherry pick 挑選要發布的功能。
- 第三步:經過發版後的,測試工程師關閉 JIRA,我們通過 web hook 通知後端Kubernetes叢集刪除對應分支分配的資源。
這就完成了整個系統的流程,這其中每一個分支都可以分配資源部署環境測試和開發。
Q&A
Q:開發每提交一個bugfix,都會觸發jinkens去構建鏡像,那麼多的開發人員,豈不是要構建很多鏡像?
A:沒有錯,我們是每次都觸發構建 image,由於 image是分層的,底層已經存在的父物件,是不用儲存,只儲存變化的部分所以再用的磁碟空間很低,在系統開始初,我做過統計,1000 個 image 也不到 9G,這其中還有很多基礎鏡像。
Q:想問一個叢集相關的,像Docker部署這部是直接調用Docker部署容器,還是通過Ansible或其他工具?
A:有了 Kubernetes 管理叢集後,發布的工作就比較簡單了,用不上 Ansible。但是 Ansible 還是有它的用處的,比如清理叢集中過時的
image,和已經退出的 Container等。
Q:你好,以前也做過類似的服務“第三步:Jenkins 會把相應的 image 部署到伺服器叢集中,開發人員就可以通過 iss001.kingdee這個網域名稱訪問剛剛對應分支的服務了”,單獨一個分支解決了對應的bug,但實際生產中非常容易修改一個bug引起其他的bug,你們是怎麼去把控整體的穩定性?如何提高這種單個bug分支單個測試環境的意義?
A:這個 pull-request 的工作方式是應對功能開發的,如像長期開發某個 new feature,你剛剛說的一個 bug 產生另外一個 bug,我們的做法是有迴歸測試,我們有一個 smoke 分支,持續不斷的對其做功能迴歸測試,只有通過的才能 cherry pick 到 release 上。
Q:測試環境依賴的redis/MQ之類的外部服務如何做的隔離?每次測試單獨拉起來一套外部依賴的服務嗎?
A:我們通過多個手段來實現共用資料:master、smoke、release 分支測試都有自己獨立的中介軟體,要是不用訪問共用的資料,可以部署如 MQ image,代碼層面的,如 MQ key 的名稱加上機器的 IP。
Q:有沒有用到Mesos?是否容易遇到問題?這方面的文檔好像並不多。
A:Mesos 是個二級調度,適用於像存在多套叢集的情況,來均衡資源,如:部署了 Hadoop 和 storm ,一般會使用 storm 來處理即時的請求,Hadoop 做離線工作。晚上和白天就存在一種可能就是 Hadoop 閑置,但是 storm 可能很忙,這時 Mesos 這樣的二級調度就可以平衡資源,節約成本,我們暫時沒有這樣的需求。至於文檔方面我也沒有深入研究,建議看官方文檔。
以上內容根據2015年12月22日晚群分享內容整理。分享人:
胡世,kingdee 雲之家工程師,主要負責架構和效能調優方面的工作,比較熟悉 Java、JVM 相關的技術, 關注 Liunx kernel,對於 Docker 技術棧有濃厚的興趣,目前研究 Docker 和 Kubernetes 在實際生產環境中的應用。 DockOne每周都會組織定向的技術分享,歡迎感興趣的同學加:liyingjiesx,進群參與,您有想聽的話題可以給我們留言。