harbor鏡像倉庫原理和安裝


 源地址:harbor鏡像倉庫原理和安裝

目錄

------------------------------------------------------------------------

 
一:Harbor簡介
Harbor是一個用於存儲和分發Docker鏡像的企業級Registry服務器。
Harbor和Registry都是Docker的鏡像倉庫,但是Harbor作為更多企業的選擇,是因為相比較於Regisrty來說,它具有很多的優勢。
 
1. docker registry的缺點:
  • 缺少認證機制,任何人都可以隨意拉取及上傳鏡像,安全性缺失
  • 缺乏鏡像清理機制,鏡像可以push卻不能刪除,日積月累,占用空間會越來越大
  • 缺乏相應的擴展機制
 
2. Harbor優點
a.提供分層傳輸機制,優化網絡傳輸
Docker鏡像是是分層的,而如果每次傳輸都使用全量文件(所以用FTP的方式並不適合),顯然不經濟。必須提供識別分層傳輸的機制,以層的UUID為標識,確定傳輸的對象。
b.提供WEB界面,優化用戶體驗
只用鏡像的名字來進行上傳下載顯然很不方便,需要有一個用戶界面可以支持登陸、搜索功能,包括區分公有、私有鏡像。
c.支持水平擴展集群
當有用戶對鏡像的上傳下載操作集中在某服務器,需要對相應的訪問壓力作分解。
d.良好的安全機制
企業中的開發團隊有很多不同的職位,對於不同的職位人員,分配不同的權限,具有更好的安全性。
e.Harbor提供了基於角色的訪問控制機制,並通過項目來對鏡像進行組織和訪問權限的控制。
kubernetes中通過namespace來對資源進行隔離,在企業級應用場景中,通過將兩者進行結合可以有效將kubernetes使用的鏡像資源進行管理和訪問控制,增強鏡像使用的安全性。尤其是在多租戶場景下,可以通過租戶、namespace和項目相結合的方式來實現對多租戶鏡像資源的管理和訪問控制。
 
3. Harbor介紹
鏡像的存儲harbor使用的是官方的docker registry(v2命名是distribution)服務去完成。harbor在docker distribution的基礎上增加了一些安全、訪問控制、管理的功能以滿足企業對於鏡像倉庫的需求。harbor以docker-compose的規范形式組織各個組件,並通過docker-compose工具進行啟停。
docker的registry是用本地存儲或者s3都是可以的,harbor的功能是在此之上提供用戶權限管理、鏡像復制等功能,提高使用的registry的效率。Harbor的鏡像拷貝功能是通過docker registry的API去拷貝,這種做法屏蔽了繁瑣的底層文件操作、不僅可以利用現有docker registry功能不必重復造輪子,而且可以解決沖突和一致性的問題。
Harbor官方網站:http://vmware.github.io/harbor/
Harbor源碼地址:https://github.com/vmware/harbor/
 
 
二:Harbor主要組件
Proxy:對應啟動組件nginx。它是一個nginx反向代理,代理Notary client(鏡像認證)、Docker client(鏡像上傳下載等)和瀏覽器的訪問請求(CoreService)給后端的各服務;
UI(Core Service):對應啟動組件harbor-ui。底層數據存儲使用mysql數據庫,主要提供了四個子功能:
  • UI:一個web管理頁面ui;
  • API:Harbor暴露的API服務;
  • Auth:用戶認證服務,decode后的token中的用戶信息在這里進行認證;auth后端可以接db、ldap、uaa三種認證實現;
  • Token服務(上圖中未體現):負責根據用戶在每個project中的role來為每一個docker push/pull命令issuing一個token,如果從docker client發送給 registry的請求沒有帶token,registry會重定向請求到token服務創建token。
Registry:對應啟動組件registry。負責存儲鏡像文件,和處理鏡像的pull/push命令。Harbor對鏡像進行強制的訪問控制,Registry會將客戶端的每個pull、push請求轉發到token服務來獲取有效的token。
Admin Service:對應啟動組件harbor-adminserver。是系統的配置管理中心附帶檢查存儲用量,ui和jobserver啟動時候需要加載adminserver的配置;
Job Sevice:對應啟動組件harbor-jobservice。負責鏡像復制工作的,他和registry通信,從一個registry pull鏡像然后push到另一個registry,並記錄job_log;
Log Collector:對應啟動組件harbor-log。日志匯總組件,通過docker的log-driver把日志匯總到一起;
Volnerability Scanning:對應啟動組件clair。負責鏡像掃描
Notary:對應啟動組件notary。負責鏡像認證
DB:對應啟動組件harbor-db,負責存儲project、 user、 role、replication、image_scan、access等的metadata數據。
 
需要說明的是,harbor的每個組件都是以Docker容器的形式構建的,可以使用Docker Compose來進行部署,當然,如果你的環境中使用了kubernetes,harbor也提供了kubernetes的配置文件。
docker鏡像:harbor-jobservice, nginx, harbor-core, redis, harbor-portal, harbor-db, registry, registryctl, harbor-log
harbor共有8個容器組成:
  • ui:harbor的核心服務。
  • log:運行着rsyslog的容器,進行日志收集。
  • mysql:由官方mysql鏡像構成的數據庫容器
  • nginx:使用Nginx做反向代理
  • registry:官方的Docker registry
  • adminserver:harbor的配置數據管理器
  • jobservice:Harbor的任務管理服務。
  • redis:用於存儲session
 
 

-------------------

 
三:Harbor架構
 
1. Harbor登錄過程
假設Harbor部署在IP為192.168.1.10的主機上。用戶運行docker命令將登錄請求發送到Harbor:
$ docker login 192.168.1.10
用戶輸入所需憑證后,Docker客戶端向地址“192.168.1.10/v2/”發送HTTP GET請求。Harbor的不同容器將按照以下步驟進行處理:
(a)首先,該請求由監聽端口80的代理容器接收。容器中的Nginx將請求轉發到后端的registry容器。
(b)Registry容器已配置為基於令牌的身份驗證,因此它返回錯誤代碼401,通知Docker客戶端從指定的URL獲取有效的令牌。在Harbor,這個URL指向核心服務的令牌服務;
(c)Docker客戶端收到此錯誤代碼后,會根據HTTP規范的基本認證向令牌服務URL發送請求,將請求頭部嵌入用戶名和密碼;
(d)通過端口80將該請求發送到代理容器后,Nginx會根據預先配置的規則再次將該請求轉發給UI容器。UI容器內的令牌服務接收請求,解碼請求並獲取用戶名和密碼;
(e)獲取用戶名和密碼后,令牌服務將檢查數據庫,並通過MySql數據庫中的數據驗證用戶。當令牌服務配置為LDAP / AD身份驗證時,它將對外部LDAP / AD服務器進行身份驗證。認證成功后,令牌服務返回一個表示成功的HTTP代碼。HTTP響應體包含由私鑰生成的令牌。
 
2. Docker push 的過程
(我們省略了代理轉發步驟,上圖顯示了Docker推送過程中不同組件之間的通信)
用戶成功登錄后,Docker Image將通過Docker Push命令發送到Harbor:
# docker push 192.168.1.10/library/hello-world
(a)首先,碼頭客戶端通過向注冊表發送請求重復類似登錄的過程,然后取回令牌服務的URL;
(b)隨后,當接觸令牌服務時,Docker客戶端提供附加信息以在image(library/ hello-world)上應用推送操作的令牌;
(c)收到Nginx轉發的請求后,令牌服務查詢數據庫查詢用戶的角色和權限,以推送image。如果用戶具有適當的權限,則對Push操作的信息進行編碼,並用私鑰對其進行簽名,並向Docker客戶端生成一個令牌;
(d)在Docker客戶端獲取令牌之后,它向包含令牌的頭部向Registry發送推送請求。一旦Registry接收到請求,它將使用公鑰解碼令牌並驗證其內容。公鑰對應於令牌服務的私鑰。如果Registry找到令牌有效推送Image,則Image傳輸過程開始。
 
 
 
四:harbor鏡像倉庫部署
1. 安裝harbor環境
系統版本: centos7.6
確認docker 和 docker-compose版本號( docker和docker-compose安裝
[root@harbor harbor]# docker version
Client: Docker Engine - Community
 Version: 18.09.7
Server: Docker Engine - Community
  Version: 18.09.7
[root@harbor harbor]# docker-compose --version
docker-compose version 1.24.1, build 4667896
 
2. 安裝harobr鏡像倉庫
github官網地址 https://github.com/goharbor/harbor/releases
[root@harbor ~]# wget https://github.com/goharbor/harbor/releases/download/v1.9.3/harbor-offline-installer-v1.9.3.tgz
[root@harbor ~]# tar -zxvf harbor-offline-installer-v1.9.1.tgz 
[root@harbor ~]# cd harbor/
[root@harbor harbor]# ls
harbor.v1.9.1.tar.gz harbor.yml install.sh LICENSE prepare
[root@harbor harbor]# ls keys/ #自己制作證書的位置
ikan.key ikan.pem
 
 
3.修改主機名,開啟https認證並安裝
不需要添加域名,到時候nginx直接轉發過來即可,和主機名同時支持
數據默認放置在data_volume: /data下,日志在/var/lib/harbor下
[root@harbor harbor]# vim harbor.yml #修改以下這些地方
hostname: harbor1.ikan.com
https:
  port: 443
  certificate: /root/harbor/keys/ikan.pem
  private_key: /root/harbor/keys/ikan.key
 
          
[root@harbor harbor]# ./prepare 
prepare base dir is set to /root/harbor
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
loaded secret from file: /secret/keys/secretkey
Generated certificate, key file: /secret/core/private_key.pem, cert file: /secret/registry/root.crt
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir
[root@harbor harbor]# ./install.sh 
 
[Step 0]: checking installation environment ...
 
Note: docker version: 19.03.2
 
Note: docker-compose version: 1.24.1
 
[Step 1]: loading Harbor images ...
cad87ea2da29: Loading layer [==================================================>] 77.02MB/77.02MB
 
安裝完成后,它會提示你訪問harbor的地址是多少,你就可以直接在瀏覽器中訪問這個地址了。
  • 停止服務: docker-compose stop
  • 開始服務: docker-compose start
 
五:Harbor使用
1. 通過界面登陸harbor
https://harbor1.ikan.com ,開啟https后默認只走這個
 
默認用戶名和密碼 admin Harbor12345
 
2. 創建鏡像項目kubernetes
路徑:項目 -> 新建項目 -> 項目名稱 kubernetes -> 確認
 
3. 測試harbor倉庫可用性
[root@harbor2 ~]# docker login harbor1.ikan.com
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
 
Login Succeeded
[root@harbor2 ~]# # 登陸成功后,token會存放在 ~/.docker/config.json.文件里
 
[root@harbor2 ~]# docker tag busybox harbor.ikan.com/kubernetes/busybox:v0.3
[root@harbor2 ~]# docker push harbor.ikan.com/kubernetes/busybox:v0.3
The push refers to repository [harbor.ikan.com/kubernetes/busybox]
eac247cb7af5: Layer already exists 
v0.3: digest: sha256:24fd20af232ca4ab5efbf1aeae7510252e2b60b15e9a78947467340607cd2ea2 size: 527
 
 
報錯1:鏡像直接上傳到harbor正常,但是通過nginx一直顯示超時:
[root@harbor2 ~]# docker push harbor.ikan.com/kubernetes/busybox:v0.3
The push refers to repository [harbor.ikan.com/kubernetes/busybox]
eac247cb7af5: Retrying in 10 seconds 
解決:需要修改安裝包里面Nginx配置文件,刪掉scheme的那幾行,在反向代理的配置上如果有寫的話
 
報錯2: 在拉取鏡像的時候,會拋出倉庫不受信任的異常。
解決:需要在所有的docker客戶端的docker配置文件/etc/docker/daemon.json中添加如下配置:
{ "insecure-registries": ["https://harbor1.ikan.com"], }
 
 
六:harbor鏡像倉庫高可用
高可用方案有兩種:
1. 雙主復制
所謂的雙主復制其實就是復用主從同步實現兩個harbor節點之間的雙向同步,來保證數據的一致性,然后在兩台harbor前端頂一個負載均衡器將進來的請求分流到不同的實例中去,只要有一個實例中有了新的鏡像,就是自動的同步復制到另外的的實例中去,這樣實現了負載均衡,也避免了單點故障,在一定程度上實現了Harbor的高可用性:
這個方案有一個問題就是有可能兩個Harbor實例中的數據不一致。假設如果一個實例A掛掉了,這個時候有新的鏡像進來,那么新的鏡像就會在另外一個實例B中,后面即使恢復了掛掉的A實例,Harbor實例B也不會自動去同步鏡像,這樣只能手動的先關掉Harbor實例B的復制策略,然后再開啟復制策略,才能讓實例B數據同步,讓兩個實例的數據一致。
在實際生產使用中,主從復制有時候會出現報錯。
 
2. 多harbor實例共享后端存儲,
共享后端存儲算是一種比較標准的方案,就是多個Harbor實例共享同一個后端存儲,包括數據庫,redis和本地存儲數據;任何一個實例持久化到存儲的鏡像,都可被其他實例中讀取。通過前置LB進來的請求,可以分流到不同的實例中去處理,這樣就實現了負載均衡,也避免了單點故障:
 
這個方案在實際生產環境中部署需要考慮三個問題:
    1. 共享存儲的選取,Harbor的后端存儲目前支持AWS S3、Openstack Swift, Ceph等,在我們的實驗環境里,就直接使用nfs
    2. Session在不同的實例上共享,這個現在其實已經不是問題了,在最新的harbor中,默認session會存放在redis中,我們只需要將redis獨立出來即可。可以通過redis sentinel或者redis cluster等方式來保證redis的可用性。在我們的實驗環境里,仍然使用單台redis
    3. Harbor多實例數據庫問題,這個也只需要將harbor中的數據庫拆出來獨立部署即可。讓多實例共用一個外部數據庫,數據庫的高可用也可以通過數據庫的高可用方案保證。
 
目前,Harbor官方並未給出具體的高可用部署方案,用戶需要根據自己的情況來設計合適的高可用方案並完成部署。主從同步高可用方案,只是一種簡單的實現。
 
0.1 已經有了另一台鏡像倉庫harbor2
1. 創建用戶
 
2. 項目中添加用戶
 
3. 倉庫管理中添加目標
  1. 選擇系統管理中的倉庫管理,點擊“新建目標”,如下圖
  2. 輸入對應信息。
    1. 目標名和描述隨意,
    2. 目錄URL為另一台地址,如果為https協議,則證書需要安全。(制作免費的https證書.note
    3. Access ID和Access Secret為有同步權限的賬號即可
  1. 點擊“測試鏈接”,顯示“測試鏈接成功”,則表示權限通過,點解“確認”添加即可
 
4. 添加復制規則
  1. 在系統管理的復制管理里,點擊“新建規則”,如下圖
  2. 添加規則信息
    1. 名稱和描述隨意
    2. 選擇復制模式:Push-based 從本地倉庫推送到遠程倉庫,Pull-based 拉去鏡像到本地倉庫
    3. 鏡像過濾規則,包括包含名稱,標簽等
    4. 選擇遠程鏡像倉庫和命名空間
    5. 選擇觸發模式,分為手動/定時/事件,鏡像是否強制覆蓋,是否啟動規則等
 
5. 測試harbor倉庫可用性
這時你推送鏡像到鏡像倉庫harbor1,則在鏡像倉庫harbor2上也能看到
[root@harbor2 ~]# docker tag busybox harbor.ikan.com/kubernetes/busybox:v0.4
[root@harbor2 ~]# docker push harbor.ikan.com/kubernetes/busybox:v0.4
The push refers to repository [harbor.ikan.com/kubernetes/busybox]
eac247cb7af5: Layer already exists 
v0.3: digest: sha256:24fd20af232ca4ab5efbf1aeae7510252e2b60b15e9a78947467340607cd2ea2 size: 527
 
鏡像自動化刪除
默認情況下,Harbor將鏡像存儲在本地磁盤,隨着鏡像越來越多,可能會導致磁盤空間不夠。為了提供磁盤的利用率,需要把不用或者多余的鏡像刪除。 Harbor提供了刪除鏡像的功能,但需要手動去處理。
可以采用cron job定期去運行鏡像刪除腳本來實現鏡像自動化刪除。腳本通過調用Harbor的RESTful API,來獲取要刪除鏡像的名稱和tag。刪除鏡像的過程如下:
1) 獲取所有project並解析project_id字段,得到project的個數;
2) 獲取每個project的repo名稱;
3) 根據repo名稱獲取每個repo下的tag並統計個數;
4) 若tag數大於規定的個數,進行排序,刪除最早的tag(並不會刪除鏡像);
5) 刪除鏡像,命令如下:
docker-compose stop;
docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.1-photon garbage-collect /etc/registry/config.yml;
docker-compose start;
 
 
問題:registry https://192.168.70.120 is unhealthy: unhealthy
解決:證書自簽名,不被信任。
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM