1. 程式人生 > >Harbor使用者機制、映象同步和與Kubernetes的整合實踐_Kubernetes中文社群

Harbor使用者機制、映象同步和與Kubernetes的整合實踐_Kubernetes中文社群

目錄:
一、Harbor的安全機制
二、Harbor的映象同步
三、Harbor與K8s的整合實踐
四、兩個小貼士
五、總結

Habor是由VMWare公司開源的容器映象倉庫。事實上,Habor是在Docker Registry上進行了相應的企業級擴充套件,從而獲得了更加廣泛的應用,這些新的企業級特性包括:管理使用者介面,基於角色的訪問控制 ,AD/LDAP整合以及審計日誌等。

容器的核心在於鏡象的概念,由於可以將應用打包成映象,並快速的啟動和停止,因此容器成為新的炙手可熱的基礎設施CAAS,併為敏捷和持續交付包括DevOps提供底層的支援。

而Habor和Docker Registry所提供的容器映象倉庫,就是容器映象的儲存和分發服務。之所以會有這樣的服務存在,是由於以下三個原因:

  • 提供分層傳輸機制,優化網路傳輸
    Docker映象是是分層的,而如果每次傳輸都使用全量檔案(所以用FTP的方式並不適合),顯然不經濟。必須提供識別分層傳輸的機制,以層的UUID為標識,確定傳輸的物件。
  • 提供WEB介面,優化使用者體驗
    只用映象的名字來進行上傳下載顯然很不方便,需要有一個使用者介面可以支援登陸、搜尋功能,包括區分公有、私有映象。
  • 支援水平擴充套件叢集
    當有使用者對映象的上傳下載操作集中在某伺服器,需要對相應的訪問壓力作分解。

上面這些就是Docker Registry所完成的主要工作,而Habor在此之上,又提供了使用者、同步等諸多特性,這篇文章中我們就這幾個方面作一些闡述,同時例項程式碼介紹Harbor與K8s的整合。

一、Harbor的安全機制

企業中的軟體研發團隊往往劃分為諸多角色,如專案經理、產品經理、測試、運維等。在實際的軟體開發和運維過程中,這些角色對於映象的使用需求是不一樣的。從安全的角度,也是需要通過某種機制來進行許可權控制的。

舉例來說,開發人員顯然需要擁有對映象的讀寫(PULL/PUSH)許可權以更新和改正程式碼;測試人員中需要讀取(PULL)許可權;而專案經理需要對上述的角色進行管理。

Harbor為這種需求提供了使用者和成員兩種管理概念。

在Harbor中,使用者主要分為兩類。一類為管理員,另一類為普通使用者。兩類使用者都可以成為專案的成員。而管理員可以對使用者進行管理。

成員是對應於專案的概念,分為三類:管理員、開發者、訪客。管理員可以對開發者和訪客作許可權的配置和管理。測試和運維人員可以訪客身份讀取專案映象,或者公共映象庫中的檔案。
從專案的角度出發,顯然專案管理員擁有最大的專案許可權,如果要對使用者進行禁用或限權等,可以通過修改使用者在專案中的成員角色來實現,甚至將使用者移除出這個專案。

20170314213441

二、Harbor的映象同步

為什麼需要映象同步

由於對映象的訪問是一個核心的容器概念,在實際使用過程中,一個映象庫可能是不夠用的,下例情況下,我們可能會需要部署多個映象倉庫:

  • 國外的公有映象下載過慢,需要一箇中轉倉庫進行加速
  • 容器規模較大,一個映象倉庫不堪重負
  • 對系統穩定性要求高,需要多個倉庫保證高可用性
  • 映象倉庫有多級規劃,下級倉庫依賴上級倉庫

更常用的場景是,在企業級軟體環境中,會在軟體開發的不同階段存在不同的映象倉庫,

  • 在開發環境庫,開發人員頻繁修改映象,一旦程式碼完成,生成穩定的映象即需要同步到測試環境。
  • 在測試環境庫,測試人員對映象是隻讀操作,測試完成後,將映象同步到預上線環境庫。
  • 在預上線環境庫,運維人員對映象也是隻讀操作,一旦執行正常,即將映象同步到生產環境庫。
  • 在這個流程中,各環境的映象庫之間都需要映象的同步和複製。

Harbor的映象同步機制

有了多個映象倉庫,在多個倉庫之間進行映象同步馬上就成為了一個普遍的需求。比較傳統的映象同步方式,有兩種:

  • 第一種方案,使用Linux提供的RSYNC服務來定義兩個倉庫之間的映象資料同步。
  • 第二種方案,對於使用IaaS服務進行映象儲存的場景,利用IaaS的配置工具來對映象的同步進行配置。

這兩種方案都依賴於倉庫所在的儲存環境,而需要採用不同的工具策略。Harbor則提供了更加靈活的方案來處理映象的同步,其核心是三個概念:

  • 用Harbor自己的API來進行映象下載和傳輸,作到與底層儲存環境解耦。
  • 利用任務排程和監控機制進行復制任務的管理,保障複製任務的健壯性。在同步過程中,如果源映象已刪除,Harbor會自動同步刪除遠端的映象。在映象同步複製的過程中,Harbor會監控整個複製過程,遇到網路等錯誤,會自動重試。
  • 提供複製策略機制保證專案級的複製需求。在Harbor中,可以在專案中建立複製策略,來實現對映象的同步。與Docker Registry的不同之處在於,Harbor的複製是推(PUSH)的策略,由源端發起,而Docker Registry的複製是拉(PULL)的策略,由目標端發起。

20170314213448

Harbor的多級部署

在實際的企業級生產運維場景,往往需要跨地域,跨層級進行映象的同步複製,比如集團企業從總部到省公司,由省公司再市公司的場景。
這一部署場景可簡化如下圖:

20170314213455

更復雜的部署場景如下圖:

20170314213503

三、Harbor與K8s的整合實踐

Harbor提供了基於角色的訪問控制機制,並通過專案來對映象進行組織和訪問許可權的控制。kubernetes中通過namespace來對資源進行隔離,在企業級應用場景中,通過將兩者進行結合可以有效將kubernetes使用的映象資源進行管理和訪問控制,增強映象使用的安全性。尤其是在多租戶場景下,可以通過租戶、namespace和專案相結合的方式來實現對多租戶映象資源的管理和訪問控制。

整合的核心概念和關鍵步驟

兩者的整合,一個核心概念是k8s的secret。作為kubernetes中一個重要的資源secret,它的設計初衷是為了解決容器在訪問外部網路或外部資源時驗證的問題,例如訪問一個Git倉庫,連線一個數據庫,設定一些密碼配置等,需要額外驗證的場景Secret儲存了敏感資料,例如能允許容器接受請求的許可權令牌。通過將Harbor的使用者資訊與K8s的Secret相關聯,即達成了兩者的整合。步驟如下:

  • 在Harbor中建立建立使用者,專案,將專案設定為私有。
  • 將建立的使用者加入到專案中,設定使用者的角色為開發者或者為專案管理員。確保該賬戶具有拉取該倉庫映象的許可權。
  • 建立K8s下的Secret,其中secret中的使用者名稱、密碼和郵箱地址資訊為在Harbor中建立的使用者的資訊。

在此過程中需要注意的是,第三步中建立的secret,對應的使用者必須在Harbor的對應私庫中有下載映象的許可權,否則應用部署時會報無法下載映象。

舉例來說

  • 在Harbor中建立了使用者,如userD
  • 在Harbor中建立一個私有專案,如projectA
  • 在Harbor中使用Docker命令列登陸並上傳映象至步驟2中的私有庫
  • 在K8s中建立Namespace
  • 在K8s的Namespace中建立SecretC,該Secret對應Harbor中的使用者賬號userD

使用Harbor私庫中的映象在K8s的Namespace中部署應用,指定映象下載時使用上面建立的SecretC
如果只需要能夠拉取Harbor的映象在K8s中部署應用,Harbor中的userD需要在projectA中有最低許可權的訪客成員角色。

Harbor與K8s整合的程式碼實踐

imagePullSecret在K8s中用來儲存映象倉庫的認證資訊,以方便Kubelet在啟動Pod時,能夠獲得映象倉庫的認證資訊,確保能Kubelet夠有許可權從映象倉庫中下載Pod所需的映象。
首先我們來看一下k8s中的ImagePull型別的Secret如何來建立。官方文件為:https://kubernetes.io/docs/user-guide/images/#specifying-imagepullsecrets-on-a-pod

以下程式碼實踐Harbor版本是0.3.5。

首先,我們需要在harbor中選擇一個使用者,使用它的使用者名稱與密碼生成一個字串,使用者名稱與密碼中間用冒號相連,然後使用base64對它進行加密,如下所示:[[email protected] ~]# echo “test:tT001″|base64dGVzdDp0VDAwMQo=

然後,我們需要生成一個dockerconfig.json,需要使用上面生成的加密字串,內容大致如下,假如對應的harbor庫的地址為:hub.testharbor.com:

{
 "auths":{
 "hub.testharbor.com": {
 "auth": "dGVzdDp0VDAwMQo=",
 "email": ""
 }
 }
 }

我們需要把這整個json使用base64進行加密。生成的字串可能比較長,需要加上 -w 0 引數,不讓它換行。將上面的json儲存成dockerconfig.json檔案,然後執行命令:

[[email protected] secret]# cat dockerconfig.json |base64 -w 0
 ewogICJhdXRocyI6IHsKICAgICJodWIudGVzdGhhcmJvci5jb20iOiB7CiAgICAgICJhdXRoIjogImRHVnpkRHAwVkRBd01Rbz0iLAogICAgICAiZW1haWwiOiAiIgogICAgfQogIH0KfQo=

現在,我們可以來建立secret所需的yaml了。secret建立的時候,必須指定namespace。多個namespace中的secret可以同名。假如我們需要在名為hub中的namespace中建立名為testsecret的secret,對應的secret.yaml內容如下。需要使用上面生成的加密字串。
此時在k8s中使用kubectl create 命令即可建立對應的secret:

kubectl create -f secret.yaml

最後,在部署應用的時候,我們需要為Pod指定下載映象所需的secret名字,如下所示:

apiVersion: v1
 kind: Pod
 metadata:
 name: httpdpod
 namespace: hub
 spec:
 containers:
 - name: httpdpod
 image:hub.testharbor.com/project1/httpd:2.2
 imagePullSecrets:
 - name:testsecret

注意,要想部署成功,test使用者必須為harbor中的project1專案中的成員,它才能有下載這個httpd:2.2的許可權。

容器雲的使用者與整合

作為容器雲執行時,Harbor的使用者與K8s的Secret可以有更集約的整合方式。在我們的專案實踐中,一個容器雲的使用者與一個Harbor中同名Project一一對應,但此使用者可以在k8s中可以建立多個namespace。為了簡化管理過程,目前我們的做法是:

  • 在容器雲啟動過程中,自動在Harbor中建立一個專用使用者,專門用來在各私庫中下載映象
  • 每個在Harbor中新建的私庫,都會將這個專用使用者新增為它的訪客成員角色 ,使這個專用使用者擁有下載此庫中映象的許可權
  • 在K8s中,每建立一個新的namespace的同時,在此namespace下,使用上面的專用使用者的資訊建立固定名稱的secret(多namespace中可存在同名secret)
  • 部署應用時,指定imagePullSecrets下面的名稱為上面固定的secret名稱。

四、兩個小貼士

使用線上工具讓Harbor的介面文件更易讀

Harbor對外提了restful形式的介面供其它系統整合,它的介面描述以swagger格式的文件包含在原始碼中,文件地址為:https://github.com/vmware/harbor/blob/master/docs/swagger.yaml。

目前,越來越多的系統使用restful的介面對外暴露服務,而swagger已經成了事實上的restful介面的描述標準。直接使用文字編輯器去檢視這種swagger文件,會有點暈,沒法方便清晰地檢視介面的整體結構。我們可以藉助一些工具來看這些文件。線上的,比如官方提供的swagger線上編輯器,把文件內容複製至左邊,右邊即可顯示html格式的文件,可以摺疊等,讓人對所有介面一目瞭然。離線的,則可以在一些編輯器安裝外掛,將它同樣轉化成html進行檢視,比如vscode,安裝 Swagger Viewer外掛即可。關於Swagger的使用,也可以閱讀我的同事李小飛的文章《微服務架構實戰:Swagger規範RESTful API》。

兩種格式的文件展示如下:

20170314213511

小貼士:Harbor的Java Client開源實現

對於熟悉Java程式設計的使用者來說,Harbor官方沒有提供java client,但是在github上也有人寫了相關的專案,專案地址:https://github.com/grissomsh/harbor-java-client

20170314213518

五、總結

本文主要介紹了Harbor的使用者機制、映象同步和與K8s的整合實踐。

Harbor的使用者機制分為系統使用者和專案成員兩類。使用者可以成為專案成員,而不同成員有不同的映象讀寫許可權。

Harbor的同步策略和任務排程機制,為映象庫間的映象同步提供了靈活的機制。

利用K8s的Secret與Harbor使用者的關聯,可以在K8s中拉取Harbor私有庫中的映象來部署應用。我們也用程式碼進行了舉例。

最後,再分享幾個在Harbor(0.3.5)的使用過程中碰到的小坑:

  • 在Harbor中建立使用者時,密碼必須為複雜密碼。但是修改時,沒有了此限制
  • 使用者更新密碼的時候,原密碼不能與新密碼一致,否則報500內部錯誤
  • 在為harbor的project新增成員的時候,成員角色沒有相關API,需要給的id值也沒有常量定義,目前來看,1為admin, 2為devlop,3為guest。

關於作者:
秦雙春
現任普元雲端計算架構師。曾在PDM,雲端計算,資料備份,移動互聯相關領域公司工作,10年IT工作經驗。曾任上海科企軟體桌面虛擬化產品的核心工程師,主導過愛數TxCloud雲櫃的設計與開發,主導過萬達資訊的食安管理與追溯平臺的移動平臺開發。國內雲端計算的早期實踐者,開源技術愛好者,容器技術專家。

關於EAWorld
致力於軟體架構創新與實踐,加速企業數字化轉型,EAii(Enterprise Architecture Innovation Institute)企業架構創新研究院旗

本文原標題:為什麼有了Docker registry還需要Harbor?