1. 程式人生 > >企業級Docker映象倉庫的管理和運維

企業級Docker映象倉庫的管理和運維

容器應用的使用越來越廣泛,容器技術突出的優點就是開發運維一體化。通過把應用及其所依賴的軟體包、作業系統檔案等封裝在容器映象中,使得應用在開發、測試和釋出過程中都具有相同的執行環境,帶來極大的便利。從圖1這張經典的Docker容器狀態轉換圖可以看到,容器映象(images)的關聯箭頭最多,不言而喻,映象就是容器技術的核心所在。

圖片描述

圖1 Docker容器狀態轉換圖

概括地說,容器技術包含一靜一動兩部分:封裝應用的靜態映象(images)和執行應用的動態容器(containers)。相應地,容器的開發運維主要涉及映象管理和執行時(Runtime)管理兩部分。本文主要和大家談談容器映象管理的部分。

容器映象的管理主要圍繞映象倉庫(registry)來進行。在應用的生命週期中,無論開發人員或CI系統釋出映象,還是測試人員或運維人員下載映象,都要通過映象倉庫來完成。映象倉庫可以使用公有的SaaS服務,例如Docker Hub。公有服務的優點是可直接使用,無需自己維護。但考慮到訪問效率和映象安全等方面的原因,大多數公司都建立了自己的私有映象倉庫(Registry),因此也需要有貫穿整個應用生命週期的映象管理策略。

下文主要介紹在開發運維中的管理容器映象原理和方法,為了便於說明原理,較多地使用Harbor作為例子。Harbor是由VMware中國研發團隊負責開發的開源企業級Registry,可幫助使用者迅速搭建企業級的registry 服務,提供許可權控制、映象同步、中文管理介面等強大功能,深受廣大使用者喜愛。有興趣的朋友可以關注或使用: 

https://github.com/vmware/harbor 。

確保映象內容的一致性

在應用的開發、測試和執行等各個階段,需要確保都使用同一個應用的映象。一種做法是在每個階段都用相同dockerfile去生成所需映象。通常認為,相同的dockerfile可以構件出相同的映象,而實際上卻並非如此。例如下面的dockerfile 部分:

FROM ubuntu
RUN apt-get install –y python
ADD app.jar /myapp/app.jar

首先,FROM的基礎映象隱含使用了latest版本,在不同時間構建的映象,可能是不同的版本。即使指明瞭ubuntu:14.04這樣的版本號也不保險,因為相同版本的系統可能含有補丁等不盡相同的軟體包。

再看apt-get這樣的命令(類似的還有curl,wget等),往往會從網際網路上引入第三方的軟體包,版本的一致性就更加無從確定了。還有在ADD語句中新增到映象裡面的檔案app.jar,取決於構建時的檔案版本,也是一個不確定的因素。

從上面的例子可以看到,儘管docker映象的目的是構造不可更改的應用環境,但由於其構建的時候往往具有不確定的輸入,相同dockerfile生成的映象未必包含相同的內容。因此,最好的方法還是在不同的環境中始終採用相同的映象(二進位制格式),雖然在傳輸量上比dockerfile要大,但是可以確保映象的一致性。

映象的傳輸

很多使用者在開發、測試和運維中都使用同一個Registry作為映象倉庫,這種方式比較適合小團隊或簡單的專案。在其他情況下,最好使用多個Registry以區分不同的用途和安全控制要求。容器映象管理的參考流程(如圖2所示)。

圖片描述

圖2 應用映象的管理流程
  • 開發環境的Registry: 主要由開發人員使用,映象變化頻繁。當開發完成後,通過CI系統生成穩定映象,並同步到測試Registry;

  • 測試環境的Registry: 主要由測試人員使用,映象保持不變。當測試通過後,映象推送到準生產環境的Registry;

  • 準生產環境(Staging)的Registry: 主要由測試和運維人員使用,映象保持不變。當準生產環境試執行後平穩後,再發布到生產環境的Registry;

  • 生產環境的Registry: 釋出映象到生產環境的節點執行。

從開發到生產的整個過程中,符合要求的容器映象會逐步進入下一級的Registry,最後到達生產系統,從而實現容器映象的構建-傳輸-執行(Build-Ship-Run)過程。

Harbor提供Registry之間的映象自動同步和複製功能,通過配置複製策略,自動化管理映象傳輸流程。Harbor的複製策略啟動之後,會比較目標Registry和本地源Registry在映象上的差異,並把目標Registry缺少的映象從本地推送過去,使得兩個Registry例項的映象完全一致。後續推送到源例項上的映象,會以增量的形式同步到目標例項上。當在源例項上刪除映象的時候,目標例項上的映象也會被刪除。通過Harbor的複製機制,可實現兩個或多個registry例項之間的映象同步。

映象的許可權控制

在企業中,通常有不同的開發團隊來負責不同的應用專案,和原始碼分專案管理一樣,映象也需要按照專案來存放和管理。由於專案團隊中有不同的成員,如專案經理、產品經理、開發、測試和運維等人員,每種人員使用映象的需求不同,因此可以根據角色分配相應的許可權。

例如,測試人員通常只需要映象的讀許可權(pull),開發人員需要讀寫許可權(push/pull),專案經理除了擁有開發人員的許可權之外,還可以增加和刪除專案成員,設定他們的角色。

在Harbor Registry中,每個專案中可有三種角色:專案管理員(project admin)、開發者(developer)和客人(guest)。某些專案,如放在library中的公共映象, 可以允許匿名訪問,即使用者不用docker login也可以訪問,這樣方便某些場景的使用。在整個系統中,還設有系統管理員,具有維護映象同步策略、使用者增刪等許可權。

需要指出的是,在不同的環境中,某個成員的角色可以不同。例如,在開發環境的registry中,運維人員一般不需要許可權(或只需要讀許可權);而在生產環境中的Registry,運維人員就需要有讀寫許可權。

大規模映象釋出方式

在實際生產運維的中,往往需要把映象釋出到幾十、上百臺或更多的叢集節點上。這時,單個Registry已經無法滿足大量節點的下載需求,因此要配置多個registry例項做負載均衡。手工維護多個registry例項上的映象,將是十分繁瑣的事情。Harbor支援一主多從的映象釋出模式,可以解決大規模映象釋出的難題。

圖片描述

圖3 主從模式的映象分發

如圖3所示,只要往一臺registry上釋出,映象就像“仙女散花”般地同步到多個registry中。

如果是地域分佈較廣的多資料中心或跨雲的叢集,還可以採用層次型釋出方式,如從集團總部同步到省公司,從省公司再同步到市公司(如圖4所示):

圖片描述

圖4 多級主從模式的映象分發

在同步過程中,如果源映象已刪除,Harbor會自動同步刪除遠端的映象。在映象同步複製的過程中,Harbor會監控整個複製過程,遇到網路等錯誤,會自動重試。

同步複製的監控畫面如圖5所示:

圖片描述

圖5 映象複製策略的監控

映象刪除和空間回收

Docker命令沒有提供Registry映象刪除功能,系統日積月累地執行中,將會產生許多無用的映象,佔用大量儲存空間。若要刪除映象並回收空間,需要呼叫docker registry API來完成,非常麻煩。Harbor提供了視覺化的映象刪除介面,可以邏輯刪除映象。在維護狀態下可以回收垃圾映象的空間。

Registry高可用性

Registry高可用性(HA)是多數生產系統需要關心的問題,基本要求就是沒有單點故障。通常需要根據允許服務中斷的時間,以及可以承受的成本和損失,來確定採用的技術。下面介紹3種不同的高可用參考方案。 
圖片描述

圖6用共享儲存實現多Registry例項

一種比較標準的方案,就是多個的Registry例項共享同一個後端儲存,任何一個例項持久化到儲存的映象,都可被其他例項中讀取。通過前置LB進來的請求,可以分流到不同的例項中去處理,實現了負載均衡,也避免了單點故障(如圖6所示)。

應該指出,實際中需要考慮的問題遠比上述模型複雜。例如,共享儲存的選取,使用者session在不同的例項上共享等等。使用者可根據自己業務要求設計出不同的方案。Harbor將會推出基於swift分散式儲存,以及共享session的方案(採用redis)來滿足使用者的需求。

如果沒有共享儲存,可採用第2種方案,就是在兩個節點間採用雙主複製策略,互相複製映象。即使有一個例項失效,另一個例項仍然可以提供服務,從而在一定程度上可以滿足HA的需求。在這種場景下,兩個例項的使用者資料並沒有同步,因此需要分別配置相同的使用者賬號(如圖7所示)。

圖片描述

圖7 雙主複製實現準HA

第3中方案是利用已有的高可用平臺,例如vSphere HA,配合分散式儲存VSAN,可以實現Registry的高可用性, 具體架構如圖8所示:

圖片描述

圖8 基於VSAN和vSphere搭建高可用Registry架構

節點出現故障的時候,有vSphere自動切換到好的節點上,映象資料不丟失(如圖9所示)。

圖片描述

圖9 用VSAN和vSphere實現Registry自動遷移

小結

本文以開源Harbor Registry為例子,總結了企業中Registry的常見使用場景和要點,希望對大家有所啟發。同時也歡迎大家使用Harbor和反饋意見, Harbor的github地址:https://github.com/vmware/harbor 。