Harbor: 跨數據中心複製Docker鏡像的開源實現

容器鏡像複製和發佈一直缺乏良好的工具,是實際開發和運維中的一大痛點。開源Harbor Registry提供強大的鏡像複製/同步能力,成爲衆多用戶喜好的殺手級功能。本文介紹了鏡像複製功能的工做原理,做者爲Harbor項目核心工程師姜坦、尹文開。git

VMware公司3月份開源了企業級Registry項目Harbor,由VMware中國研發的團隊負責開發。Harbor可幫助用戶迅速搭建企業級的registry 服務。它提供了管理圖形界面, 基於角色的訪問控制RBAC,鏡像遠程複製(同步),AD/LDAP集成、以及審計日誌等企業用戶需求的功能,同時還原生支持中文,深受中國用戶的喜好。該項目推出4多個月以來,在GitHub 得到了超過900多個點贊星星和200多個 forks,Github地址:github

https://github.com/vmware/harbor數據庫

在最近發佈的版本中,Harbor新增了基於策略的Docker鏡像複製功能,可在不一樣的數據中心、不一樣的運行環境之間同步鏡像,並提供友好的管理界面,大大簡化了實際運維中的鏡像管理工做,已經有用戶部署了遠程鏡像雙向複製的案例。本文將對該功能的實現原理作詳細介紹。服務器

Harbor鏡像複製的管理界面微信

功能簡介網絡

在功能設計方面,Harbor仍然以「項目」爲中心, 經過對項目配置「複製策略」,標明須要複製的項目以及鏡像。管理員在複製策略中指明目標實例,即複製的「目的地」,並對它的地址和鏈接時使用的用戶名密碼進行設置。當複製策略被激活時,源項目下的全部鏡像,都會被複制到目標實例;此外,當源項目下的鏡像被添加或刪除(push或delete), 只要策略還在激活狀態,鏡像的變化都會同步到目標實例上去, 以下圖所示:併發

 

在較大的容器集羣中,每每須要多個Registry服務器作負載均衡,能夠採用主從發佈模式,鏡像只須要發佈一次,就能夠推送到多個Registry實例中。同時還支持雙主複製和層次型的多級鏡像發佈,以下圖所示: 負載均衡

設計與實現運維

在不一樣的Registry實例之間複製鏡像是十分廣泛的需求,過去常見的作法是經過拷貝鏡像數據,好比按期經過rsync同步文件系統中鏡像的數據,或者,對於部署在IaaS服務上的狀況,經過對IaaS存儲服務一層進行配置實現對象複製,這些方法每每是根據registry使用的存儲而採用不一樣工具。然而對於Harbor來講,咱們但願下降這種依賴,並提升靈活性, 好比用戶可能有一個開發用的registry使用文件系統做爲存儲,並但願把鏡像同步到基於S3存儲的遠端發佈用的registry上。考慮到這種狀況,咱們選擇經過調用registry自己的API下載並傳輸鏡像,從而作到了與下層存儲無關。工具

在控制方面,咱們引入了一個新的組件,Job Service,用來對鏡像複製任務進行管理。當以項目爲單位進行復制時,會以鏡像爲單位生成一系列任務(job)由Job Service 調度管理,Job Service在執行任務的過程當中將每一個任務的狀態更新到數據庫中, 以便用戶經過UI查看。大致結構以下圖所示:

下面介紹一下Job Service 的實現,從外部看它也是經過REST API接收請求調度並執行任務,面臨的問題主要有兩點,首先,接收到大量複製請求時須要進行限流以避免消耗過多IO資源;其次,複製策略有可能在任務執行過程當中改變,好比失效,這就須要一種機制能從外界對運行中的任務進行干預。

咱們經過任務隊列,分發器(dispatcher)和worker pool實現了生產者消費者模型,利用Go語言內置的channel,每一個任務會經過scheduler放到channel裏,dispatcher 經過channel得到任務,同時,worker在工做結束後會被放入另外一個channel, dispatcher 經過這個channel與worker配對,因而,空閒的worker經過dispatcher得到任務id並執行任務,這樣能夠很方便地經過worker pool中 worker數量來控制併發數:

 

對於另外一個問題,每個 worker內部是一個抽象的狀態機(state machine),經過給不一樣狀態註冊處理器(handler)完成具體工做,同時,狀態機能夠受到干預,能夠中途取消(cancel)任務,或在任務執行發生異常時將任務置爲錯誤(error)狀態丟棄或交給調度器(scheduler)重試。 另外因爲狀態機的狀態是可定製的,這樣就很方便擴展和調整。對於一個抽象的任務來講,它的狀態轉移以下圖所示: 

而對於具體遠程同步鏡像的任務來講,Running 狀態會被進一步細分紅多個子狀態,以下圖所示:

首先, 從源Harbor實例下載相應tag的manifest,分析其所包含的blob,針對每個blob,檢查其在目標實例中是否已經存在,若是不存在,則同步此blob。最後,檢查manifest在目標實例中是否已存在,若是不存在,則上傳manifest。檢查blob的存在性,能夠有效減小沒必要要的網絡流量;而因爲manifest的上傳有可能會觸發鏡像的同步,因此對manifest存在性的檢查,則能夠避免當同步的多個Harbor造成環路時進入不斷同步的死循環狀態。對同一個鏡像中的每個tag重複以上過程,就能夠完成整個鏡像的同步工做。

總結與展望

本文介紹了Harbor新版本中遠程鏡像複製功能的設計與實現。從此咱們將對此功能進行擴展,好比在策略(policy)中加入更加豐富的控制和過濾條件方便用戶選擇須要複製的鏡像,以及控制複製的發生時間等。也但願讀者和用戶們在多向咱們提供反饋意見。Harbor項目網址:

https://github.com/vmware/harbor

爲便於交流,微信用戶可申請加入「Harbor開源項目羣」,請先掃描下面二維碼關注「亨利筆記」公衆號,並在公衆號後臺發送"入羣"信息便可。 

相關文章
相關標籤/搜索