1. 程式人生 > >Harbor用戶機制、鏡像同步和與Kubernetes的集成實踐

Harbor用戶機制、鏡像同步和與Kubernetes的集成實踐

kuberntes

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中,用戶主要分為兩類。一類為管理員,另一類為普通用戶。兩類用戶都可以成為項目的成員。而管理員可以對用戶進行管理。

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

技術分享

二、Harbor的鏡像同步

為什麽需要鏡像同步

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

  • 國外的公有鏡像下載過慢,需要一個中轉倉庫進行加速

  • 容器規模較大,一個鏡像倉庫不堪重負

  • 對系統穩定性要求高,需要多個倉庫保證高可用性

  • 鏡像倉庫有多級規劃,下級倉庫依賴上級倉庫

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

  • 在開發環境庫,開發人員頻繁修改鏡像,一旦代碼完成,生成穩定的鏡像即需要同步到測試環境。

  • 在測試環境庫,測試人員對鏡像是只讀操作,測試完成後,將鏡像同步到預上線環境庫。

  • 在預上線環境庫,運維人員對鏡像也是只讀操作,一旦運行正常,即將鏡像同步到生產環境庫。

  • 在這個流程中,各環境的鏡像庫之間都需要鏡像的同步和復制。

Harbor的鏡像同步機制

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

  • 第一種方案,使用Linux提供的RSYNC服務來定義兩個倉庫之間的鏡像數據同步。

  • 第二種方案,對於使用IaaS服務進行鏡像存儲的場景,利用IaaS的配置工具來對鏡像的同步進行配置。

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

  • 用Harbor自己的API來進行鏡像下載和傳輸,作到與底層存儲環境解耦。

  • 利用任務調度和監控機制進行復制任務的管理,保障復制任務的健壯性。在同步過程中,如果源鏡像已刪除,Harbor會自動同步刪除遠端的鏡像。在鏡像同步復制的過程中,Harbor會監控整個復制過程,遇到網絡等錯誤,會自動重試。

  • 提供復制策略機制保證項目級的復制需求。在Harbor中,可以在項目中創建復制策略,來實現對鏡像的同步。與Docker Registry的不同之處在於,Harbor的復制是推(PUSH)的策略,由源端發起,而Docker Registry的復制是拉(PULL)的策略,由目標端發起。

技術分享

Harbor的多級部署

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

技術分享

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

技術分享

三、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》。

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

技術分享

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

對於熟悉Java編程的用戶來說,Harbor官方沒有提供java client,但是在github上也有人寫了相關的項目,項目地址:https://github.com/grissomsh/harbor-java-client

技術分享

五、總結

本文主要介紹了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。


本文出自 “我的天空” 博客,請務必保留此出處http://sky66.blog.51cto.com/2439074/1934009

Harbor用戶機制、鏡像同步和與Kubernetes的集成實踐