企業級容器Registry開源項目Harbor架構簡介mysql
做者:姜坦 張海寧git
(本文做者爲Harbor項目組核心成員,於2016年9月5日做了更新。)github
1. Harbor項目web
VMware公司最近開源了企業級Registry項目Harbor,由VMware中國研發的團隊負責開發。Harbor項目是幫助用戶迅速搭建一個企業級的registry 服務。它以Docker公司開源的registry爲基礎,提供了管理UI, 基於角色的訪問控制(Role Based Access Control),鏡像遠程複製(同步),AD/LDAP集成、以及審計日誌(Audit logging) 等企業用戶需求的功能,同時還原生支持中文,對廣大中國用戶是一個好消息。本文將介紹Harbor項目的主要組件,並闡述Harbor的工做原理。sql
(源代碼地址:https://github.com/vmware/harbor )docker
2.架構介紹數據庫
1) 主要組件後端
Harbor在架構上主要由6個組件構成:瀏覽器
· Proxy:Harbor的registry, UI, token等服務,經過一個前置的反向代理統一接收瀏覽器、Docker客戶端的請求,並將請求轉發給後端不一樣的服務。服務器
· Registry: 負責儲存Docker鏡像,並處理docker push/pull 命令。因爲咱們要對用戶進行訪問控制,即不一樣用戶對Docker image有不一樣的讀寫權限,Registry會指向一個token服務,強制用戶的每次docker pull/push請求都要攜帶一個合法的token, Registry會經過公鑰對token 進行解密驗證。
· Core services: 這是Harbor的核心功能,主要提供如下服務:
o UI:提供圖形化界面,幫助用戶管理registry上的鏡像(image), 並對用戶進行受權。
o webhook:爲了及時獲取registry 上image狀態變化的狀況, 在Registry上配置webhook,把狀態變化傳遞給UI模塊。
o token 服務:負責根據用戶權限給每一個docker push/pull命令簽發token. Docker 客戶端向Regiøstry服務發起的請求,若是不包含token,會被重定向到這裏,得到token後再從新向Registry進行請求。
· Database:爲core services提供數據庫服務,負責儲存用戶權限、審計日誌、Docker image分組信息等數據。
Job Services:提供鏡像遠程複製功能,能夠把本地鏡像同步到其餘Harbor實例中。
· Log collector:爲了幫助監控Harbor運行,負責收集其餘組件的log,供往後進行分析。
各個組件之間的關係以下圖所示:
2) 實現
Harbor的每一個組件都是以Docker 容器的形式構建的,所以很天然地,咱們使用Docker Compose來對它進行部署。
在源代碼中(https://github.com/vmware/harbor), 用於部署Harbor的Docker Compose 模板位於 /Deployer/docker-compose.yml. 打開這個模板文件,會發現Harbor由5個容器組成:
· proxy: 由Nginx 服務器構成的反向代理。
· registry:由Docker官方的開源registry 鏡像構成的容器實例。
· ui: 即架構中的core services, 構成此容器的代碼是Harbor項目的主體。
· mysql: 由官方MySql鏡像構成的數據庫容器。
job services: 經過狀態機機制實現遠程鏡像複製功能,包括鏡像刪除也能夠同步到遠端Harbor實例。
· log: 運行着rsyslogd的容器,經過log-driver的形式收集其餘容器的日誌。
這幾個容器經過Docker link的形式鏈接在一塊兒,這樣,在容器之間能夠經過容器名字互相訪問。對終端用戶而言,只須要暴露proxy (即Nginx)的服務端口。
3. 工做原理
下面以 兩個Docker 命令爲例,講解主要組件之間如何協同工做。
docker login
假設咱們將Harbor部署在IP 爲192.168.1.10的虛機上。用戶經過docker login命令向這個Harbor服務發起登陸請求:
# docker login 192.168.1.10
當用戶輸入所需信息並點擊回車後,Docker 客戶端會向地址 「192.168.1.10/v2/」 發出HTTP GET請求。 Harbor的各個容器會經過如下步驟處理:
(a) 首先,這個請求會由監聽80端口的proxy容器接收到。根據預先設置的匹配規則, 容器中的Nginx會將請求轉發給後端的registry 容器;
(b) 在registry容器一方,因爲配置了基於token的認證,registry會返回錯誤代碼401,提示Docker客戶端訪問token服務綁定的URL。在Harbor中,這個URL指向Core Services;
(c) Docker 客戶端在接到這個錯誤代碼後,會向token服務的URL發出請求,並根據HTTP協議的Basic Authentication規範,將用戶名密碼組合並編碼,放在請求頭部(header);
(d)相似地,這個請求經過80端口發到proxy容器後,Nginx會根據規則把請求轉發給ui容器,ui容器監聽token服務網址的處理程序接收到請求後,會將請求頭解碼,獲得用戶名、密碼;
(e) 在獲得用戶名、密碼後,ui容器中的代碼會查詢數據庫,將用戶名、密碼與mysql容器中的數據進行比對(注:ui 容器還支持LDAP的認證方式,在那種狀況下ui會試圖和外部LDAP服務進行通訊並校驗用戶名/密碼)。比對成功,ui容器會返回表示成功的狀態碼, 並用密鑰生成token,放在響應體中返回給Docker 客戶端。
這個過程當中組件間的交互過程以下圖所示:
至此,一次docker login 成功地完成了,Docker客戶端會把步驟(c)中編碼後的用戶名密碼保存在本地的隱藏文件中。
2. docker push
用戶登陸成功後用docker push命令向Harbor 推送一個Docker image:
# docker push 192.168.1.10/library/hello-world
(a) 首先,docker 客戶端會重複login的過程,首先發送請求到registry,以後獲得token 服務的地址;
(b) 以後,Docker 客戶端在訪問ui容器上的token服務時會提供額外信息,指明它要申請一個對image library/hello-world進行push操做的token;
(c) token 服務在通過Nginx轉發獲得這個請求後,會訪問數據庫覈實當前用戶是否有權限對該image進行push。若是有權限,它會把image的信息以及push動做進行編碼,並用私鑰簽名,生成token返回給Docker客戶端;
(d) 獲得token以後 Docker客戶端會把token放在請求頭部,向registry發出請求,試圖開始推送image。 Registry 收到請求後會用公鑰解碼token並進行覈對,一切成功後,image的傳輸就開始了。
咱們省去proxy轉發的步驟,下圖描述了這個過程當中各組件的通訊過程:
4.參考材料
本文並未涉及Harbor項目自己的配置、部署, 這方面請參考Harbor在github上的文檔:https://github.com/vmware/harbor
相關文章:
歡迎廣大用戶使用Harbor項目並反饋意見和建議,也歡迎加入咱們貢獻代碼。若是您是Harbor的用戶或開發者,可申請加入Harbor開源項目微信羣,以方便溝通。請先掃描下面二維碼關注「亨利筆記」公衆號,並在公衆號後臺發送"入羣"信息便可。