由于docker registry只提供了基本的鏡像上傳下載保存功能,在用戶認證及鑒權、多用戶管理、安全掃描、鏡像清理、鏡像同步等部分有所欠缺,因此如果要在公司內部使用鏡像倉庫,推薦使用harbor。
Harbor 2.0版本支持OCI(Open Container Initiative)鏡像(如鏡像、Helm Chart等)以及OCI鏡像索引。鏡像索引是一種high level manifest,指向一個manifest列表。通過鏡像索引,可以根據client端的架構不同,自動下載對應架構的鏡像。(創建多架構支持的鏡像方法參考)
Harbor 2.0的整體架構如下圖所示。
image.png
整個Harbor架構可以分為三層,分別為Consumer、Fundamental Service和Data Access Layer。
Consumer是Harbor的使用方。除了Harbor自帶的前端界面(web portal)外,也可以通過其他client訪問harbor,如kubelet、helm、docker等。
Fundamental Service模塊較多,后面介紹。
Data Access Layer用于數據存儲。主要有三塊:
- 鍵值對存儲: 使用的是Redis。redis主要用來進行registry緩存、session存儲包括后期的helm chartmuseum緩存。
- 數據存儲: 用于存儲registry(鏡像)和chart數據。支持對接塊存儲、文件存儲和對象存儲。
- 數據庫: 使用的是PG,存儲Harbor使用到的各個表。包括projects, users, roles, replication policies, tag retention policies, scanners, charts, images等
下面介紹下Fundamental Service的各個組成模塊。
Harbor自帶的模塊主要有以下幾個:
- Core: Core模塊包含較多子模塊,每個模塊中也有自己的子模塊。
- API Server: 接收Rest 請求,并通過子模塊處理后返回結果。
- Authentication & Authorization
- Authentication服務:通過本地數據庫、AS/LDAP或OIDC對請求進行Authentication(登陸認證)
- Authorization服務:對action進行RBAC鑒權,如pull/push鏡像。
- Token Service:根據用戶對project的權限,簽發不同的token用于push/pull等操作。如果docker client發送的請求不含token,Registry會將請求重定向到token服務。
- MiddleWare: 中間件用于請求的預處理,確定請求是否需要轉發到后端。包含的預處理功能有“quota management”, “signature check”, “vulnerability severity check”和“robot account parsing”等。
- API Handlers: 解析、驗證請求參數,根據相應的API controller完成業務邏輯處理,并生成相應的響應。
- Authentication & Authorization
- Config Manager: 系統配置管理。
- Project Management: 管理Project(namespace)。
- Quota Manager: 管理Project的quota配額。
- Chart Controller: 轉發chart相關的處理請求到后端
chartmuseum
。提供了一些擴展來優化chart管理。 - Retention Manager:管理tag回收(保留)策略,并執行和監控。
- Content Trust: 方便使用Notary功能的一個擴展(插件)。
- Replication Controller: 管理鏡像復制(備份)策略,并執行和監控;適配不同registry。當前適配的registry有docker registry、Docker hub、Huawei SWR等,參考架構圖。
- Scan Manager: 鏡像掃描,提供掃描結果。支持對接Trivy,Clairs等。
- Notification Manager:webhook回調管理。支持HTTP POST請求和Slack channel。
- OCI Artifact Manager:提供OCI制品的全生命周期管理(CRUD)。包括安全掃描報告、鏡像構建歷史等鏡像元數據及額外信息的管理;helm charts的readme、dependencies、value.yaml文件管理;制品的Tag管理等。
- Registry Driver: 與底層的registry(目前是docker registry)進行通信的registry client SDK。OCI Artifact Manager需要通過該組件獲取制品的manifest及Config JSON等信息。
- API Server: 接收Rest 請求,并通過子模塊處理后返回結果。
- GC controller: GC。刪除鏡像后,需要通過GC將存儲空間釋放。
- Log Collector: 日志記錄。
- Job Service: 異步任務處理。如鏡像定時掃描等。
依賴的外部模塊有:
- Proxy:提供代理服務,使用的是Nginx,將consumer的請求代理轉發到后端的各個模塊。
- Notary:Notary 是一套鏡像的簽名工具, 用來保證鏡像層在 pull、push、transfer 過程中的一致性和完整性。避免中間人攻擊,阻止非法的鏡像更新和運行。鏡像層的創建者可以對鏡像層做數字簽名,生成摘要,保存在 Notary 服務中。開啟 Content Trust 機制之后,未簽名的鏡像無法被拉取。
關于notary的詳細功能見: https://github.com/zj1244/Blog/blob/master/2019/harbor%E7%9A%84Notary%E5%8A%9F%E8%83%BD%E6%B5%8B%E8%AF%95.md
- Chart Museum:用于保存helm chart鏡像的組件。
-
Docker Distribution(docker registry):harbor本身不提供鏡像上傳/下載等功能,相關功能是通過調用docker registry的API實現的。因此,需要依賴到docker registry服務。
另外支持對接一些外部模塊,如鏡像掃描使用的Clair和Trivy,鏡像備份使用的Docker Distribution、Docker Hub等。
docker login的過程
- Proxy在80端口接收到請求,并轉發給Registry container。
- Registry container需要token-based authentication。會返回401,并告訴client從指定的URL(指向token service)獲取token。
- docker client發送請求到token service。(請求頭中包含username和password,用于HTTP的basic authentication)
- proxy在80端口接收到請求后,會將請求轉發到UI container中(UI container中包含token service)。token service接收到請求后,獲取其中的username和password。
- token service將username和password在數據庫或者是LDAP/AD等服務中進行authentication。成功后,返回一個HTTP狀態碼表示認證成功,并將通過私鑰生成的token放在返回的body中。
- docker client接收到成功的返回后,將用戶名密碼編碼后保存在本地的文件中。
docker push鏡像過程。
docker push xxx/library/hello-world
- 首先,同登陸一樣,docker client會發送請求,并拿到token service的URL。
- 然后,docker client向token service發送請求,除了用戶名密碼外,在請求中還會提供一些額外信息(action為push,resource為library/hello-world)。
- token service查詢數據庫,獲取用戶綁定的角色(role),查看是否有權限進行push鏡像。有權限則編碼push操作對應的信息,并使用私鑰簽發token給docker client。
- docker client發送push請求到registry,并在header中帶上token。registry使用公鑰解碼token后,驗證內部信息。如果驗證通過,則開始上傳流程。
如果需要臨時訪問密鑰,則可以用harbor的私鑰簽發一個帶有時效的token即可。