最熱門文章:
(今天這個是純IT題材,不懂的人現在逃走還來得及😄😄😄)
錘子兩年前登陸墨爾本時,完全是DevOps小白。面試REA的時候,被問到什麼是Continuous Delivery(持續交付),錘子誠懇地表示「不知道」。面試官不依不饒,「不知道不要緊,你想想怎麼樣才能做到Continuous Delivery?」 錘子回顧了一下自己維護項目時的噩夢,斟酌著用詞說:「這需要好多自動化的工具支持,怎麼測試,怎麼接入不同的網絡,怎麼部署不同的環境,還有資料庫的data migration和回滾,個頂個的都是痛點。」
之前錘子所做過的系統都是Monolith(單體)架構,所以,每次需要重啟生產環境時,真得一而再,再而三地確認。所以當我們Squad(REA引入了Spotify模式[1])的同事給我講解我們的微服務架構[2],和怎麼做Continuous Delivery時,我問:「那最壞的情況就是重啟系統了?」這個同事說:「不,重啟系統是正常情況。」由此,錘子開始慢慢了解REA強大的DevOps。
什麼是 DevOps?
DevOps 集文化理念、實踐和工具於一身,可以提高組織高速交付應用程式和服務的能力,與使用傳統軟體開發和基礎設施管理流程相比,能夠幫助組織更快地發展和改進產品。這種速度使組織能夠更好地服務其客戶,並在市場上更高效地參與競爭。[3]
這幅圖片[3] 可以看到發布生產線。
如果我們想更好的解釋DevOps,最好的方法是像解釋Agile一樣,把不同人的意見映射到不同的級別 如下所示[4]。
DevOps價值觀:敏捷宣言有效體現了DevOps的基本價值觀 —— 需要稍微修改一點,改成關注發布給客戶的業務或者軟體的整體,而不是簡單的「可工作的軟體」。
DevOps原則:(來源於John Willis的 "CAMS"[5])
文化(Culture): 人和過程優先。
自動化(Automation): 一旦開始理解文化,這是可以開始的一個點。
度量(Measurement):成功的DevOps實現需要儘可能多的度量其能度量的所有東西。
共享(Sharing):共享似的CAMS形成迴路。
DevOps實踐:實現上述的概念和過程用到的特別的技術。
DevOps工具:DevOps原則落地使用到的工具。
接下來讓我們看看REA的DevOps是怎樣契合這些不同的方面。
REA DevOpsREA 價值觀REA採用了Spotify模式[1] ,你可以通過 The values we live by[6]了解REA的價值觀。
Do it as one team
Do it with heart
Keep it real
inspire it
Own it
Re-imagine it
基於這些價值觀,REA的所有IT小夥伴們一起合作,把最有價值的產品和功能發布給客戶,這一切由分層協作框架支持。
REA DevOps的分層協作REA DevOps的分層協作框架下,不同層面的問題由不同的組負責,如下圖。
每個Squads使用DevOps工具鏈開發和維護自己的微服務。詳情會在下面一節進行介紹。
Delivery Engineering團隊,顧名思義,就是為了讓程序猿們更快更好地發布應用,主要職責是工具的開發和管理。包括創建Docker Registry,準備好已經安裝了必要庫的baked Docker image[7],有了這些基準的Docker Images,開發團隊在為自己的微服務構建Docker Image的時可以有效節省時間,還能夠規避各種庫版本不一致的問題。Delivery Engineering還需要為不同部門配置Buildkite,Buildkite的Agents部署在AWS的EC2中,根據連接環境的不同,多個Agents分布在不同的VPC中。
Global Infrastructure & Architecture 團隊負責基礎設施建設,管理維護並開發相應的工具,包括網絡、數據中心、AWS帳號的管理、Splunk的集成等。比如,去年雪梨下大雨,Amazon的機房被水淹了,澳洲大批網站受到影響,也包括我們公司的一小部分,當時苦了GIA team的人了。
所有這些分層協作關注在怎樣自動化整個發布流水線,解決其中的痛點。比如怎麼樣自動化所有流程?怎樣為REA超過40個組管理AWS的帳號?怎麼為AWS裡的測試環境和生產環境配置VPC?怎樣把微服務部署到不同的環境?監控的策略怎麼樣實施,怎麼樣在不同的組之間協調?所有的幾百個微服務,某些微服出了問題怎麼辦等等。想要解決這些問題,就必須有切切實實落地的工具鏈。
所以全工具鏈的配置和開發是Global Infrastructure & Architecture 和Delivery Engineering的職責,而作為程序猿的錘子,則是工具鏈的使用者。
那麼REA的DevOps工具鏈到底是什麼樣的?
REA DevOps全工具鏈REA實際使用到的全工具鏈包括:
代碼倉庫:github企業版。
構建和部署工具:Buildkite和Jenkins,還有一些老的項目依然在使用Bamboo。
容器平臺:微服務用Docker進行打包,Docker的引入讓公司內部微服務的部署流程一致化。
環境:目前絕大部分的service部署在AWS(Amazon Web Services)中,開發環境和測試環境使用同一套IAM,生產環境使用另一套IAM,三套環境通過Virtual Private Cloud (VPC)的設置進行隔離。不同部門的不同的組在IAM下擁有不同角色和訪問權限。部署採用AWS Cloudformation服務,避免手動創建和更新使用到的AWS的業務。
日誌管理:splunk。Docker已經提供對Splunk的支持,所以所有微服務的日誌都能夠通過Splunk Agent發送到集中的Splunk伺服器,以方便程序猿trouble shooting。完全避免了登陸到不同的機器收集log的窘境。
監控:使用AWS Cloudwatch監控AWS的服務,比如某個SQS對應的dead-letter queue裡是不是收到了消息,或者AWS Lamda執行是不是有錯誤等;NewRelic用來監控網絡和設備的性能;Nagios提供服務可用性監控,可以直接使用REA內部的rea-health-check庫,提供心跳API供Nagios的主動模式使用;通過設置接收相應的消息格式,Nagios也可以使用被動模式監控微服務。一旦無法ping通某個微服務或者在一定時間內沒有收到微服務的消息,那麼會馬上產生一個PagerDuty告警來通知相關人員。
告警:PagerDuty。前面提到的監控工具都可以配置相應的條件來產生告警,產生的告警都會通過PagerDuty用郵件,Slack,電話和簡訊的方式通知給當時的值日人員。PageDuty雖然是全天24小時運行,也只有極少部分高優先級的告警才會在非工作時間發出。還有一個告警的來源是Zendesk Ticket,這種信息通常直接來自於客戶。就我們組而言,基本上都是一些數據錯誤,需要個別修正。
協同工作:Leankit。
終於可以講講作為工具鏈使用者的程序猿錘子,日常工作是怎樣的了。
程序猿DevOps日常1. Coding前面提到過代碼庫使用github企業版,採用github flow[8]。
開發業務的過程中,大部分squad採用微服務的方式。
微服務
微服務有時被人詬病違背了DRY原則,但是Monolith架構下各種服務間的強耦合對於擴展部署都很痛苦,所以Don’t repeat yourself 誠然不錯,微服務架構下,定義好邊界之後(APIs),每個微服務獨立存在,獨立部署且可擴展,即使有一些簡單的複製粘貼,其帶來的靈活性也是Monolith架構不具備的。
在REA內部,為了保證某種程度的一致性,我們的微服務都需要遵循12 Factor[9]:
不過不管微服務設計得如何精良,當一個「小而美」的團隊(5-6名開發人員)需要同時開發維護生產環境中10個以上的微服務時,服務運行和管理上的額外複雜性使得全自動構建和部署變得不可或缺。DevOps的工具鏈恰恰提供了發布流水線自動化的功能。
微服務需要的部署腳本和AWS Cloudformation的信息,提供給不同監控工具的接口,fried Docker image[7] 定義等,也都是代碼的一部分,需要開發人員完成。
2. 構建和部署
構建和部署就以Buildkite為例子,這是一個微服務的buildkite腳本。
構建這個流程裡代碼檢查和單元測試自動化起來很容易,那麼怎麼做整合測試?REA基於Ian Robinson提出的用消費者驅動的契約進行面向服務開發的模式[10]開發了 開源的Pact 測試框架[11],用輕量級的契約測試來代替厚重的集成測試。Pact在消費端用單元測試的形式(更輕)來生成 pact 契約,服務端通過驗證契約來保證兩者穩定集成。一旦有一端契約未經協商發生改變,那麼Pact測試就會失敗。
構建成功之後,會把微服務打包成Docker Image然後上傳到Docker Registry。我們會選擇在Delivery Engineering提供的基準Docker Image之上來打包,這是一個微服務的Dockerfile的例子:
用這種方式,在buildkite上打包並上傳到Docker Registry的時間小於三分鐘。
部署開始進行部署時,部署腳本會調用Delivery Engineering開發的rea-shipper [12]。
不同的環境下,Buildkite會選擇不同的Agent進行部署:Test 環境的non-prod-corp:default和Prod環境的prod-corp:default。部署的時間通常10分鐘以內,下面是一個微服務部署到test(6分1秒)和prod(5分43秒)的時間,圖中能夠看到Cloudformation更新的步驟。
部署是全自動的,不過考慮到生產環境的重要性,我們還是選擇謹慎地Block,需要某個開發人員手動觸發。觸發的時間沒有特別的規定,不過在我們的kanban裡面,deploy是最後一步,所以只有真正部署到生產環境,這個卡片才算完成。如果部署過程中出現失敗,rea-shipper不會切換運行中的ASG(Auto Scalling Group),所以並不影響業務。如果部署的新版本發現某個bug,需要緊急回滾,因為所有的docker image都有版本信息,可以很容易的找到之前版本的docker image進行部署。
3. 運維日常的運維如下圖所示:
需要處理的問題一般有兩種:
我們Tribe有5個Squad,除了有超過30個microservice之外,還有跟不同系統的接口,如果不能組織好,開發人員每天必定會被各種問題打擾。所以如圖所示,Tribe級別有Dingo(工作時間)或者Owl(非工作時間)作為接口人,負責處理和分發問題到Squad級別的Squid。Dingo,Owl和Squid都是有團隊的開發人員輪崗。
總結本文介紹了REA DevOps的實踐,包括工具鏈,工具鏈的分層協作以及使用中的流程。再來對比一下Gene Kim的3個方法:流程,反饋和持續學習,這3個方法是DevOps的主要部分,提供一種路標來理解和執行DevOps[14]。錘子能夠看到的是在REA DevOps實踐中,每個開發人員都參與到流程的不斷優化中,讓流程變得更順暢和快速;通過不同方式可視化監控和反饋,以達到更快的反饋路徑;開放全代碼庫給所有開發人員,鼓勵程序猿持續學習和改進等等。
以上種種,推薦閱讀我們公司同事的文章來更深入的了解REA的文化。Scaling On-Call: from 10 Ops to 100 Devs[15],講述了怎麼從這樣的狀態:
到達下面的狀態:
這種變化並不是技術改進帶來的,而是源於持續學習的企業文化。而這,正是DevOps最需要的。
封面圖片來源:https://www.technolava.com/education/
參考文獻:
[1] https://labs.spotify.com/2014/03/27/spotify-engineering-culture-part-1/
[2] https://martinfowler.com/articles/microservices.html
[3] https://aws.amazon.com/cn/devops/what-is-devops/
[4] https://theagileadmin.com/what-is-devops/
[5] https://theagileadmin.com/2010/10/15/a-devops-manifesto/
[6] http://careers.realestate.com.au/rea-culture/the-values-we-live-by/
[7] http://www.capitalone.io/blog/baked-vs-fried-whos-hungry-on-the-cloud/
[8] https://guides.github.com/introduction/flow/
[9] https://12factor.net/zh_cn/
[10] https://martinfowler.com/articles/consumerDrivenContracts.html
[11] https://github.com/realestate-com-au/pact
[12] https://speakerdeck.com/mdub/rea-shipper-at-infracoders
[13] http://multithreaded.stitchfix.com/blog/2016/09/08/EmbracingImmutableServerPatternDeploymentonAWS/
[14] http://www.yunweipai.com/archives/11859.html
[15] http://rea.tech/scaling-on-call-from-10-ops-to-100-devs/
廣告時間
下面推薦的兩個公眾號,都跟少兒英語學習有關。TripleZ是🔨的朋友自己運營,關注雙語教育(沒辦法,誰讓她有三個加拿大籍的Z開頭名字的女兒們呢,知道TripleZ的來歷了把);Locokids是錘子的同學的創業項目——一對一的少兒英語外教(想報名,找錘子,有親友折扣喲)。家中有娃兒,想把雙語教育進行的更好的小夥伴們猛擊關注吧。
iOS用戶打賞渠道, 別不好意思嘛。。