全面解讀DevOps相關基礎概念與實踐
譯文【51CTO.com快譯】在本文中,我們將主要討論:什么是DevOps?它與敏捷有何不同?目前有哪些流行的DevOps工具?Docker、Kubernetes和Azure DevOps在DevOps中能起到何種作用?DevOps的重要指標與優秀實踐。
什么是DevOps?
與許多圍繞著軟件開發的流行詞匯一樣,DevOps并沒有公認的定義。有人可以用三言兩語簡單地對它進行定義,也有人需要通過一整本書進行完整復雜的詮釋。如下是兩種比較公認的定義:
- AWS:DevOps是各種文化理念、實踐和工具的組合,可以提高企業的適應力、并能夠快速地交付出各種應用和服務。
- L Leite的《DevOps概念和挑戰調查》:DevOps是組織內部的跨職能協作,它旨在確保新的軟件版本能夠在確保正確性和可靠性的前提下,實現自動化的持續交付。
在了解了DevOps定義之后,我們來看看軟件開發是如何演變成為DevOps的。
瀑布(Waterfall)模型
在軟件開發領域的前幾十年中,大家主要以瀑布模型為中心。就像建造一個橋梁那樣,瀑布模型通過多個階段來構建軟件。這些階段可能持續幾周到幾個月不等。
如上圖所示,大多數瀑布項目都需要幾個月的時間,才能讓應用程序的有效版本初見端倪。那么在瀑布模型發展的幾十年間,我們總結出了構建優秀軟件的如下關鍵要素:
- 溝通。
- 反饋。
- 自動化。
首先,由于軟件開發是一項涉及多種技能的跨職能任務,因此人與人之間的溝通對于軟件項目的成功是至關重要的。
雖然我們可以通過需求、設計、體系架構、以及與部署相關的上千頁文檔來進行書面交流。但是,在實際項目中,我們也需要通過內部溝通,來給團隊協作賦能,并通過多種技能的開展,來實現跨職能團隊(如上圖所示)的緊密協作。
其次,快速、盡早的獲得反饋,比起需要等待幾個月才能得到最終結果要重要得多。據此,我們可以及時獲悉應用是否滿足了構建業務的期望,以及將來部署到生產環境中,是否會出現問題。基于快速、及時的反饋,我們就能夠越早、越容易地解決問題。
再次,開發與部署人員都認識到,手動執行運營的速度不但慢而且容易出錯。因此在軟件開發和維護所涉及的各項活動中,我們需要引入如下圖所示的自動化方式。
敏捷(Agile)的產生
基于上述三項需求,業界慢慢出現了敏捷的相關概念。它是指通過加強團隊之間的溝通,及時獲取反饋,并引入自動化來予以實施。
通過敏捷的方式,我們可以將業務團隊和開發團隊整合到一起,致力于通過小型迭代(通常稱為Sprints)來構建出色的軟件。
過去我們在開發的每個階段上,都要花費幾周甚至幾個月的時間,而敏捷更關注幾天、甚至一天中的整個開發周期內的處理過程。我們稱之為用戶故事(user stories)的各項小需求,如下圖所示。
敏捷如何促進團隊之間的溝通?
如上文所示,敏捷使得業務和開發團隊聚集在一起。而業務代表(通常稱為產品所有者)會經常出現在團隊中,以確保團隊能夠清楚地了解業務目標。也就是說,當開發團隊對于需求的理解有誤時,產品所有者將協助糾正他們,以保證整個團隊交付出的最終產品滿足企業業務的目標。
此外,敏捷團隊的跨職能技能主要體現在:編碼技能(包括:前端、API和數據庫)、測試技能和業務技能上。通過人員之間的溝通,以及軟件設計、編碼、測試和打包等環節的協作,出色的軟件才能被構建出來。
敏捷與自動化
我們常常會碰到一些帶有原生缺陷的軟件產品,例如:產品本身帶有技術上的缺陷,而無法正常運行;或是存在著代碼質量的問題,且難以維護與修復。通常,敏捷團隊希望通過專注于自動化來盡早發現和解決此類問題。
通過自動化測試,敏捷團隊可以編寫出測試帶有各種方法和類的單元測試用例;能夠編寫出測試模塊和應用的集成測試用例。而通過使用諸如SONAR之類的工具,敏捷團隊還可以評估應用程序的代碼質量。
如上圖所示,提交版本的控制,各類測試,以及代碼質量的檢查,都可以通過持續集成管道來自動化執行。在敏捷的早期,最受歡迎的CI/CD工具便是Jenkins。
敏捷如何促進即時的反饋?
正如前文所述,有了敏捷的方式,企業無需再等待數月才能看到最終產品,而是在每次sprint結束時,目標產品的版本都能夠被演示給所有利益相關者,包括軟件架構師和業務團隊。在對下一次sprint的用戶故事進行優先級排序后,所有反饋都能夠被得到處置。這樣構建和交付出來的最終產品才是企業真正想要的東西。
由敏捷方式帶來的持續集成為即時反饋創造了有利的條件。假設我們將一段代碼提交到了版本控制系統中,那么在30分鐘內,如果該代碼會導致單元測試的失敗、或集成測試的失敗,我們就能得到及時的反饋;而如果該代碼不符合代碼質量標準、或者在單元測試中沒有足夠的代碼覆蓋率,那么我們同樣也能得到相應的反饋。
微服務架構的演變
隨著開發模式的演變,微服務的架構開始出現了。開發團隊趨向于構建許多小型的API,而不是那些大型的單體應用程序。與此同時,運營也變得更加重要。如下圖所示,我們每周都可能需要進行進行數百個小型微服務的發布,而不是積累到一個月后發布一個單體應用。因此,調試微服務中的問題,并了解微服務中發生情況也是非常重要的。
DevOps的出現
在軟件開發與產品交付的過程中,整個團隊時常會碰到如下兩個有關開發與運營團隊之間的溝通問題:
- 我們如何能夠使得部署更加容易?
- 我們如何能夠讓運營團隊的工作相對于開發團隊更具有可視性?
這時,DevOps就應運而生了。在許多成熟的企業中,開發和運營團隊往往是一個團隊。他們共享著相同的目標,也試圖了解另一個團隊所面臨的各種挑戰。因此,在DevOps的早期階段,運營團隊的代表可以直接參與Sprint的standups和retrospectives。
除了敏捷的核心領域(如:持續集成和測試自動化),DevOps團隊還應當致力于協助多個運營團隊活動的自動化,例如:配置服務器,在服務器上配置軟件,部署應用程序,以及監控生產環境等。在此,我們會時??吹礁鞣N關鍵術語,它們包括:持續部署、持續交付和基礎架構即代碼。
持續部署就是要在測試環境上持續部署新版本的軟件。在Google、Facebook這樣的成熟組織中,為了將軟件持續地部署到生產環境中,它們每天都可能有數百次生產環境的部署。
而基礎架構即代碼就是將基礎架構視為應用程序的代碼。您可以通過配置,以自動化的方式創建諸如:服務器、負載平衡器和數據庫等基礎架構。此外,通過對基礎架構進行版本控制,我們還可以跟蹤基礎架構在一段時間內的變化。
DevOps如何促進即時反饋?
前面我們已經提到了運營和開發團隊通過溝通與協作,共同應對如下問題:
- 任何運營問題都會得到開發人員的及時關注。
- 上線軟件時遇到的任何挑戰都會引起運營團隊的早期關注。
那么通過采用DevOps的方式,運營和開發團隊就能夠通過持續集成、持續交付和基礎架構作為代碼等領域,實現如下兩方面的及時反饋:
- 憑借著持續交付,如果代碼或配置的更改,可能破壞測試或暫存環境的話,那么我們會在幾個小時之內獲悉。
- 憑借著“基礎架構即代碼”,開發人員可以自行配置環境,部署代碼并自行查找問題,而無需運營團隊的任何幫助。
其實,大家可能也注意到了:敏捷和DevOps在目標上有著相似之處,都包括:
- 促進業務、開發和運營團隊之間的溝通和反饋。
- 通過自動化來緩解痛點。
實際上,在Netflix、Amazon和Google等創新型企業中,他們日復一日地發生著這樣的DevOps故事:
- 團隊中的開發人員登錄GitHub存儲庫,快速簽出某個項目。
- 快速地創建本地環境,并對代碼進行修改。
- 對修改部分進行自動化單元測試,并提交代碼。
- 以電子郵件形式告知已將該代碼部署到了質量檢查模塊。
- 在完成了自動化集成測試之后,質量檢查小組按需進行手動測試,并批準代碼的更新請求。
- 新的代碼在幾分鐘之內,被導入生產環境。
從字面上說,DevOps=開發+運營,它是開發的工具、框架、以及自動化的結合。DevOps主要專注于人員、流程和產品。其中“人員”是有關文化和樹立良好的思維模式。也就是說,它是一種促進開放式溝通,重視快速反饋,以及聚焦軟件質量的文化。
雖然前文的敏捷方式已經能夠彌合業務團隊與開發團隊之間的溝通鴻溝。開發團隊在了解業務優先級的基礎上,與業務團隊合作,提供有價值的“故事”。但是,開發團隊和運營團隊并不能保持一致,他們有著各自不同的目標:
- 開發團隊的目標是將盡可能多的新功能投入生產環境。
- 運營團隊的目標是保持生產環境盡可能地穩定。
可見,如果開發人員和運營人員無法保持一致,軟件產品就很難投入生產環境。而DevOps恰好旨在使兩個團隊實現共同認同的目標。它能夠使得開發團隊與運營團隊開展合作,以了解和解決運營的相關難題。而運營團隊則可以通過Scrum(譯者注:一種迭代式增量軟件開發過程,通常用于敏捷軟件的開發),來了解開發時所涉及的各項功能。也就是說,在那些成熟的DevOps企業中,開發與運營都屬于同一Scrum團隊,他們彼此分擔對方的部分責任。但是,如果您的企業處在DevOps的早期階段,那么如何才能使得開發與運營擁有共同的目標,并能“歡樂地玩耍”呢?通常,您可以采用如下方面的嘗試:
- 您可以在一開始便讓開發團隊去分擔運營團隊的部分職責。例如,讓開發團隊在部署到生產環境后的第一周內負責新版本的發布工作。這將有助于開發團隊了解在發布新版本時運營團隊所面臨的挑戰,進而共同尋找解決方案。
- 您也可以讓運營團隊的代表參與到Scrum的standups和retrospectives等活動中。
DevOps用例
上圖展示了Kubernetes和Docker,兩個簡單的DevOps工作流程,即:
- 使用Terraform和Azure DevOps,來配置Kubernetes集群的基礎架構即代碼。
- 使用Azure DevOps的持續部署微服務,構建Docker鏡像并部署到Kubernetes群集中。
讓我們首先來討論:使用Azure DevOps和Jenkins進行的DevOps持續部署。當開發人員將代碼提交到版本控制系統中之后,會立即執行如下步驟:
- 單元測試。
- 代碼質量檢查。
- 集成測試。
- 通過Maven、Gradle、以及Docker等工具,打包應用程序,以構建出應用程序可部署的版本。
- 應用程序的部署,即啟用新的應用程序,或是應用程序的新版本。
- 給測試團隊發送測試應用程序的電子郵件。
- 一旦獲得測試團隊的批準,該應用程序將立即被部署到下一個環境中(Next Environment)。
這就是持續部署。如果您是部署到生產環境的話,則稱為持續交付。目前最受歡迎的CI/CD工具是Azure DevOps和Jenkins。
下面我們再來看看使用Terraform將DevOps的基礎架構作為代碼。說道基礎架構即代碼(IaC),您需要理解的是:
- 基礎架構團隊能夠更專注于增值工作(而不是那些例行的工作)。
- 出現更少的錯誤,并可以從故障中快速地恢復。
- 具有服務器的一致性,避免了配置上的偏差(Configuration Drift)。
上圖展示了基礎架構即代碼的基本步驟,主要包括:通過模板來配置服務器(或啟用云端服務),安裝軟件,以及配置軟件等。通常,配置工具可用于準備和提供具有聯網功能的新服務器。目前,最受歡迎的基礎架構即代碼工具有Ansible和Terraform。
通過Terraform,您可以預配置服務器、負載平衡器、數據庫、以及網絡等基礎架構的其它部分。您可以使用Packer和Amazon Machine Image(AMI)等工具來為那些服務器預創建的鏡像。
目前,比較流行的配置管理工具有Chef、Puppet、Ansible和SaltStack,它們能夠在現有的服務器上安裝和管理各種軟件。
Docker和Kubernetes在DevOps中的作用
我們既可以使用Java,也可以使用Python,還可以使用JavaScript,來構建各種微服務。而不同的微服務針對不同的應用程序,也可能采用不同的方式被部署到服務器上。這些都給運營團隊的工作帶來了不小的困難。那么,我們該如何采用類似的方式來部署多種類型的應用呢?答案是:容器和Docker。如上圖所示,通過Docker,您可以擺脫語言和基礎架構的限制,以相同方式去構建和運行微服務的不同鏡像。這將大幅簡化運營的開銷。
同時,作為補充,Kubernetes通過協調不同類型的容器,實現了在集群上的部署。如下圖所示,Kubernetes還能夠提供:服務發現,負載均衡,以及集中配置等服務。
可見,Docker和Kubernetes能夠使DevOps變得更加容易實現。
重要的DevOps指標
下面是您需要在一段時間內持續跟蹤和改進的重要DevOps指標。
- 部署頻率 - 將應用程序部署到生產環境中的頻率是多久?
- 面市時間 - 從程序編碼到生產環境,大概需要花多長時間?
- 新版本的失敗率 - 有多少個版本失敗了?
- 修復用時 - 需要多長時間進行生產環境的修復,以及發布到生產環境需要多久時間?
- 平均恢復時間 - 從出現重大問題到恢復生產環境,需要花費多長時間?
DevOps的優秀實踐
簡單而言,DevOps的優秀實踐包括:
- 標準化
- 具有跨職能技能的團隊
- 關注團隊文化
- 自動化
- 恒定的基礎架構
- 開發和生產等價(Dev Prod Parity)
- 版本控制一切
- 自行配置(Self Provisioning)
DevOps的成熟度標志
那么我們該如何衡量DevOps實施的成熟度呢?請參考如下重要方面:
開發
- 每次提交都會觸發自動化測試和自動化代碼質量檢查嗎?
- 代碼是否能夠被持續交付到生產環境中?
- 使用到了結對編程(pair programming)嗎?
- 使用了測試驅動開發(TDD)和行為驅動開發(BDD)嗎?
- 可重復使用的模塊多嗎?
- 開發團隊可以自行配置環境嗎?
- 需要多長時間能夠快速修復生產環境?
測試
- 是否能夠通過高質量、類似生產環境的測試數據,來開展完全自動化的測試?
- 在自動化測試失敗時,構建也會失敗嗎?
- 測試周期短嗎?
- 有自動化的NFR測試嗎?
部署方式
- 是否具有開發和生產等價?
- 是否使用了A/B測試?
- 是否使用了金絲雀部署?
- 是否可以一鍵式部署?
- 是否可以一鍵式回滾?
- 是否可以一鍵式配置和發布基礎架構?
- 是否用到了基礎架構即代碼和版本控制?
監控
- 團隊是否使用了集中式監控系統?
- 是否可以一鍵式讓開發團隊訪問到日志?
- 如果在生產環境中出現了問題,團隊是否能夠收到自動警報?
團隊與流程
- 團隊是否能夠不斷地尋求改進?
- 團隊是否具備業務、開發和運營所需的全部技能?
- 團隊是否能夠跟蹤關鍵的DevOps指標,并對其進行改進?
- 是否營造了接受本地發現(Local Discoveries),并利用其進行全局改進(Global Improvements)的文化?
向DevOps轉換的優秀實踐
- 最重要的是領導愿意“買單(Buy-in)”
- 準備好各項前期成本(Upfront Costs)
- 設置專業知識中心(Center of Expertise,COE)以協助團隊
- 選擇合適的應用程序和團隊
- 從小處開始動手
- 通過實時通訊、溝通、以及COE等方式分享學習
- 以探索和自動化的思維方式鼓勵團隊
- 能夠真正認可DevOps團隊
彩蛋:免費知識拓展資料
- 十步學習Docker - https://links.in28minutes.com/in28minutes-10steps-docker。
- 十步學習Kubernetes - https://links.in28minutes.com/in28minutes-10steps-k8s。
- 十步學習AWS - https://links.in28minutes.com/in28minutes-10steps-aws-beanstalk。
【51CTO譯稿,合作站點轉載請注明原文譯者和出處為51CTO.com】