從微服務開始(四):容器化微服務DevOps的基本原理

原文鏈接:https://blogs.oracle.com/developers/getting-started-with-microservices-part-four

到了結束“從微服務開始”這一系列文章的時候了。第一部分討論了一些微服務的主要優勢,並且接觸到一些在使用微服務時需要考慮的問題;第二部分考慮了容器與微服務結合;第三部分講到實施微服務的一些基本模式和最佳實踐。

在本文中,我們將探討通過容器化微服務使用DevOps原則和實踐的關鍵環節。

簡介

採用微服務架構最重要的一個原因是加快交付速度。爲了實現高速的交付,高效的DevOps流程非常重要。在微服務架構中有很多細節需要在實現DevOps流程時考慮。在本文中我們將涉及一些容器化微服務的模式和流程。很多內容都是我們在創建Oracle Cloud雲服務的時候與客戶一起獲得的經驗和教訓。

CI/CD和CD

可能你對於縮略詞CI/CD和CD還有一些困惑,所以在我們深入流程本身之前,我們先明確一下這些縮略詞的意思。表1描述了這些縮略詞。

表1: CI/CD和CD的定義

縮略詞

定義

CI——持續集成

通過自動化構建向共享代碼庫當中頻繁的進行代碼檢入。能夠幫助團隊在代碼開發的早期捕捉到潛在的集成問題。

CD——持續交付

確保代碼總是處於生產就緒狀態。這種就緒狀態通常是通過持續集成(CI)和高級測試(比如負載測試和/或壓力測試)來保證的。一旦聲明爲“就緒”,部署到生產系統中的過程就由DevOps人員來手工完成。

CD——持續部署

與持續交付相同,不同之處是部署到生產環境是由CI/CD系統自動化完成的。

DevOps流程

部署

DevOps流程是從開發人員開始的。當使用容器工作時,作爲開發人員,你會有多種選擇。我們不會在這方面涉及太多的細節,因爲它高度依賴於你的開發偏好和公司策略,但是列出最常用的選擇還是很有幫助的。表2提供了它們的概覽。

表2: 幾種常用的部署選項

選擇

描述

本地化開發

在本地使用你所偏好的IDE進行代碼的構建和調試。作爲CI流程的一部分,代碼是編譯過的,並且容器鏡像創建後上傳到一個容器註冊庫當中。

注意:作爲鏡像創建的一部分,對鏡像設置版本非常重要。在本文中你會看到更多關於版本控制的特性。

開發容器

開發容器鏡像包含應用以及應用診斷/測試所需要的工具和組件。在你開發主機上的源代碼目錄會作爲卷映射到容器,應用在本地容器環境中的容器裏面進行運行來進行測試,比如Docker for Mac。開發容器本身通常只會在開發階段使用,不會被用於生產環境。

應用容器

服務運行在一個類生產容器中進行測試。能夠讓開發人員在真實環境下測試他們的代碼。通常你要將開發和運行容器分離。這種方式需要許多重要的額外計劃和協調,比如維護一個類生產環境的容器,並且確保每一個團隊成員都使用的是相同的版本。

CI/CD管道

在Oracle,大多數的微服務平臺開發團隊都在使用本地化開發方式,因爲通過它能夠繼續使用它們選擇的的構建工具和系統,爲每一個團隊帶來了靈活性。有的團隊使用Maven,有的使用Gradle。他們甚至使用不同的工具和構建系統,每一個團隊產出一個容器鏡像,作爲我們持續集成的一部分。另一方面,每一個服務開發團隊都有他們自己的CI/CD管道,來實現獨立部署。圖1爲一個從本地化開發方式開始的DevOps流程的高階概覽。


1:使用本地化開發的微服務DevOps流程

以下是管道中每一個階段所發生的高階步驟:

  1. 服務開發團隊的開發人員檢入源代碼。
  1. 構建被觸發。在該階段,單元測試和消費者契約測試將針對構建進行執行。
  1. 如果測試成功,將會執行一個命令,來創建一個服務的容器鏡像。鏡像的標記/版本非常重要。
  1. 一旦鏡像創建完成,它就會被推送到容器註冊庫。
  1. 最後一個步驟,鏡像以手工(持續交付)或者自動(持續部署)的拉式或者推送方式,送入目標環境,比如,一個Kubernetes集羣。一旦鏡像在集羣中可用,容器就會啓動,並且服務啓動並運行。

這種DevOps流程的最後一方面是一旦服務部署到一個目標環境,就開始收集遙測和診斷數據。數據的收集不止包括“通常”的遙測數據,比如資源消耗、錯誤和警告,還包括請求消息的端到端追蹤,在某些情況下,甚至是使用的功能。收集的所有數據不僅能夠幫助你更高的理解服務運行時的行爲,還能夠給你一些從最終用戶角度如何使用你的服務的有價值的洞察,所以你能夠基於數據,而不是基於意見,做出產品決策。

這裏描述了一個簡化的流程,但是它應該能夠給你一個在服務開發過程方面很好的想法,是你能夠在最終環境中使用容器化服務。

測試

在大多數的企業當中,一個月最多會有一次交付,每一次交付通常都會需要大量的計劃與交付會議。在企業需要對bug、客戶反饋或者新的市場需求快速響應的敏捷世界當中,緩慢的行動是一個明顯的弱點。部署的自動化是微服務DevOps實踐的一個關鍵支柱,但是要使用一個完全自動化的DevOps管道,你需要能夠相信你的服務能夠滿足你的質量標準。所以,在交付管道中的每一個階段中進行徹底的測試是非常重要的。測試是由你特定的應用需求驅動的,比如SLA,對於微服務應用的不同的測試方法、測試自動化和測試方法已經遠超過了本文的範疇。也就是說,值得指出的是兩種主要的方法。第一種是使用階段式的環境,第二種是在生產環境中測試。

階段式的環境

下面展示了在階段式環境中如何實現不同的測試階段的例子。實際上,下面的例子從更高的層面,描述了我們的一個使用微服務架構設計的內部服務是如何處理交付和測試的。圖2展示了交付管道期間的測試階段。


圖2:交付管道測試階段

  1. 測試代碼質量:在這個階段,在服務級別上有大量的單元和集成測試需要被執行,以便在早期捕捉到問題。
  1. 沙箱:在這個階段,我們將服務部署到一個隔離的沙箱中,比如一個虛擬機,託管當前部署的所有其他服務。這也是服務升級的第一個檢查點。升級後,我們運行自動化的功能驗收測試。因爲功能驗收測試要花費很長的時間,我們將它分成每個10分鐘的組塊,這樣我們就可以並行的執行這些測試。底線是那些開發人員只需要等待10分鐘就可以知道他們的服務能否工作。
  1. 預階段:在這個階段,我們使用一個類生產環境(在我們的例子裏,我們的例子中它運行在我們的Oracle Bare Metal Cloud當中)。在這個環境中,我們運行額外的端到端測試來代表用戶環境,以便檢測是否所有的服務能夠在一個類生產的目標環境中一起工作。
  1. 預產品階段:這是最終測試階段,來運行非功能性測試,比如壓力和性能測試、疲勞測試,再次進行升級和功能驗收測試。這些測試每天晚上都會執行。根據測試的輸出結果,我們聲明服務交付的候選版本。

在我們的案例中,我們會自動化的將一個候選版本發佈到產品中;我們基本上只做持續交付。主要原因,除了商業決策,是我們必須要說明性能與疲勞測試的結果,在這些點上我們無法進行自動化。

如果你對我們如何處理產品級別的容器CI/CD和測試細節感興趣,可以參考OracleCode發佈的“Show and Tell Session onHandling Production Grade Containers”。

產品環境中的測試

對很多企業來說,自動化部署到生產環境當中是非常可怕的想法。那就是說,那些掌握了持續部署的公司會有一些被證明很成功的測試技術。

滾動升級

滾動升級是一種通常用於平臺級別遷移的的功能。也就是說,當你在你的環境中部署了一些新版本的服務時,系統處於從之前的服務版本升級到新版本的過程中,健康檢測會被執。如果部署升級失敗,會進行回滾。它的優勢是在部署的過程當中,用戶只會感受到很小的影響。前面提過,根據平臺的不同,你可能有多種滾動升級的實施方法。以Kubernetes爲例,它在系統中保存着整個部署的歷史,讓你能夠很容易的回滾到之前的版本。

金絲雀部署/測試

金絲雀測試是將一個新版本的微服務部署到一個使用用戶比較少的環境當中,來確保新版本服務的適當的行爲。比如,你可能需要確保新版本服務與其他微服務的集成工作正常,並且資源消耗,例如CPU、內存、硬盤空間等,都在預期的範圍之內。

比如,我們有一個新版本的前端微服務要進行金絲雀測試。新版本的服務部署到生產環境當中,流量分割如圖3所示,有99%的流量分流到當前版本(v1.0),1%的流量分流到新版本(v1.1)。如果新版本滿足你的需求,那麼你就可以增加流量的比例,知道100%的流量都使用新的版本。

如果在新版本發佈期間的任何時間點發生失敗,你都可以輕鬆的將流量切回到v1.0,而不需要回滾或者重新部署。


圖3:金絲雀部署

藍綠部署

藍綠部署的概念與金絲雀部署很相似,不同之處是這種方式假設你有兩種生產環境,其中一個環境處理100%的流量。當你爲服務準備一個新的交付時,你在藍色環境當中進行最終階段的測試。一旦你的測試和遙測數據顯示你的新版本在藍色環境當中工作正常,你的路由或者網關就可以將所有的流量定向到藍色環境,綠色環境將會空閒。藍綠部署是一種非常強大的方式來推出一個新的版本,但是它也有特定的缺點。比如,它需要額外的基礎架構環境。也就是說,雖然現代的平臺,比如Kubernetes允許你實現藍綠部署,而不需要額外的集羣,你可能會考慮他們的開箱即用的測試與部署到生產環境的功能,比如滾動升級和金絲雀交付。

A/B測試

雖然A/B測試能夠與金絲雀或者藍綠部署結合,但它卻是一個非常不同的東西。A/B測試的目標是服務和特性的使用行爲,通常用來驗證一個假設或者度量兩個版本的服務或者特性,以及他們在性能、可發現性和可用性方面的相互關係。A/B測試通常理由特性標記(特性開關),能夠讓你動態的打開和關閉特性。

之前提到過,好消息是很多容器化的平臺,比如Kubernetes提供了對在生產環境當中進行測試的開箱即用的支持。如果開箱即用的功能不滿足你的需要,你可以考慮使用比如ISTIO或者Linkerd這樣的服務。我們將會在後續的面向關於現代API/服務方式創建微服務的文章中,詳細介紹這些服務。

容器

版本控制

容器的版本控制可以通過對鏡像添加標籤來實現。默認情況下,當時使用“docker build”創建一個容器鏡像,不會有版本控制,Docker會給他增加一個“:lastest”標籤。這可能會引起困惑,因爲“latest”並不意味着最後創建的鏡像,它實際上以爲這沒有一個明顯的定義標籤的最新的鏡像。對於這個和其他版本控制的好處,你應該總是使用適當的容器鏡像版本控制,比如fe-commerce:1.0.0-b21,來爲你的鏡像添加標籤。

鏡像大小

通常的設想中,容器都很小,但是這並不一定正確。有些大的容器鏡像的大小與小的VM的相當。鏡像大小在很多場景中都很重要,擴展場景是一個很明顯的例子。假設你的集羣在滿負荷運行,你需要增加其他的主機到集羣當中(擴展)來分擔服務A的負載;在這個例子當中,在編排器爲服務A啓動一個容器之前,鏡像需要從註冊庫當中下載。根據鏡像的延遲和大小,這需要花費一點時間,所以作爲一個規則,你應該總是考慮使用尺寸更小的基於比如Oracle Linux 7.1的鏡像。通過將你的容器註冊庫儘可能的與託管服務的集羣靠近,會在一定程度上緩解這個問題。

編排

在很多情況下,當容器中實際的服務仍然在啓動時,編排器就報告容器運行的狀態。如果這個級別的時間對你很重要,你可以爲服務配置一個健康檢查URL,這樣就能夠確切的知道容器和裏面的處理流程是啓動和運行的了。這是進行健康檢查的一個最佳實踐,而不僅僅是檢查它是否是活動狀態,並且能夠返回200OK。健康檢查應該被設計成能夠從功能的角度報告服務的實際狀態。如果服務沒有處於健康狀態,編排器需要採取適當的行動,比如重啓容器。

測試

下面是一些從測試中獲得的經驗教訓

  • 爲開發、調試和測試分別準備隔離的沙箱環境
    • 團隊成員應該很容易的建立他們自己的隔離環境
  • 單元測試/集成測試/端到端測試的敏捷“測試金字塔”
    • 更多高質量的單元測試;更少的端到端測試來降低CI週期時間
  • 在可能的地方進行並行測試
    • 用更少的事件執行更多的測試
  • 在CI/CD管道的早期測試升級
    • 如果升級失敗/引入迴歸,能夠在其他的昂貴測試上節省時間
  • 立即解決端到端測試中的間歇性故障
    • 優先處理這些故障,識別根本原因/錯誤組件並進行修復

總結

在本系列博客的第四部分,我們瞭解了容器化微服務DevOps的基礎。這是本系列文章的結論。希望你已經瞭解了那些開發人員進入容器化微服務世界時需要了解事情。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章