harbor 詳解

企業級鏡像管理系統Harbor

Harbor簡介

在說harbor之前,我們首先說一說直接使用docker registry的一些缺陷:

  1. 缺少認證機制,任何人都可以隨意拉取及上傳鏡像,安全性缺失
  2. 缺乏鏡像清理機制,鏡像可以push卻不能刪除,日積月累,佔用空間會越來越大
  3. 缺乏相應的擴展機制

鑑於以上缺點,我們通常在生產環境中,不會直接使用docker registry來實現提供鏡像服務。而Harbor正好解決了上述所有的問題。

Harbor是一個用於存儲和分發Docker鏡像的企業級Registry服務器,通過添加一些企業必需的功能特性,例如安全、標識和管理等,擴展了開源Docker Distribution。作爲一個企業級私有Registry服務器,Harbor提供了更好的性能和安全。提升用戶使用Registry構建和運行環境傳輸鏡像的效率。Harbor支持安裝在多個Registry節點的鏡像資源複製,鏡像全部保存在私有Registry中,確保數據和知識產權在公司內部網絡中管控。另外,Harbor也提供了高級的安全特性,諸如用戶管理,訪問控制和活動審計等。

Harbor官方網站:http://vmware.github.io/harbor/

Harbor源碼地址:https://github.com/vmware/harbor

harbor的二進制包同時提供online和offline版本,我們這裏直接使用online版本。

配置

架構圖

harbor架構

如上圖所示,harbor由6大模塊級成:

  • Proxy: Harbor的registry、UI、token services等組件,都處在一個反向代理後邊。該代理將來自瀏覽器、docker clients的請求轉發到後端服務上。
  • Registry: 負責存儲Docker鏡像,以及處理Docker push/pull請求。因爲Harbor強制要求對鏡像的訪問做權限控制, 在每一次push/pull請求時,Registry會強制要求客戶端從token service那裏獲得一個有效的token。
  • Core services: Harbor的核心功能,主要包括如下3個服務:
    • UI: 作爲Registry Webhook, 以圖像用戶界面的方式輔助用戶管理鏡像。1) WebHook是在registry中配置的一種機制, 當registry中鏡像發生改變時,就可以通知到Harbor的webhook endpoint。Harbor使用webhook來更新日誌、初始化同步job等。 2) Token service會根據該用戶在一個工程中的角色,爲每一次的push/pull請求分配對應的token。假如相應的請求並沒有包含token的話,registry會將該請求重定向到token service。 3) Database 用於存放工程元數據、用戶數據、角色數據、同步策略以及鏡像元數據。
    • Job services: 主要用於鏡像複製,本地鏡像可以被同步到遠程Harbor實例上。
    • Log collector: 負責收集其他模塊的日誌到一個地方

組件說明

需要說明的是,harbor的每個組件都是以Docker容器的形式構建的,可以使用Docker Compose來進行部署,當然,如果你的環境中使用了kubernetes,harbor也提供了kubernetes的配置文件。

harbor共有8個容器組成:

  • ui:harbor的核心服務。
  • log:運行着rsyslog的容器,進行日誌收集。
  • mysql:由官方mysql鏡像構成的數據庫容器
  • nginx:使用Nginx做反向代理
  • registry:官方的Docker registry
  • adminserver:harbor的配置數據管理器
  • jobservice:Harbor的任務管理服務。
  • redis:用於存儲session

下面我們所有的配置都以harbor 1.5.2版本作配置說明。

harbor可以支持http和https,建議使用https,https證書最好是受信任的ca頒發的證書,這樣,在配置docker的時候,就不需要添加"insecure-registries"配置項。我們這裏就直接使用自簽名證書。

生成證書:

openssl genrsa -des3 -out server.key 1024
openssl rsa -in server.key -out server.key    #去除server.key的加密口令
openssl req -new -key server.key -out server.csr
openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

將證書放入/data/certs/目錄下:

cp server.crt server.key /data/certs

harbor.cfg配置文件示例

harbor的核心配置文件是harbor.cfg,路徑在源碼目錄下的make目錄下,示例配置如下:

_version = 1.5.0

# harbor的訪問地址
hostname = hub.dz11.com

# 使用https協議
ui_url_protocol = https

# harbor的數據庫密碼
db_password = xxxxx

max_job_workers = 50
customize_crt = on

# 證書相關路徑
ssl_cert = /data/certs/dz11.com.crt
ssl_cert_key = /data/certs/dz11.com.key
secretkey_path = /data

admiral_url = NA

# 定義日誌滾動
log_rotate_count = 50
log_rotate_size = 200M

http_proxy =
https_proxy =
no_proxy = 127.0.0.1,localhost,ui

# email相關配置
email_identity = 
email_server = smtp.163.com
email_server_port = 25
email_username = [email protected]
email_password = yan_ruo_gu0711
email_from = admin <[email protected]>
email_ssl = false

# 登錄harbor的管理員密碼
harbor_admin_password = xxxxxx

# harbor的驗證方式,支持db_auth和ldap_auth,這裏使用的是ldap_auth,如果使用db_auth的話,直接將auth_mode修改爲db_auth即可,ldap的配置不再需要。
auth_mode = ldap_auth
ldap_url = ldap://10.1.1.1:389
ldap_searchdn = CN=jenkins,OU=LDAP,OU=Dev-wh.xxx.com,DC=dev-wh,DC=xxx,DC=com
ldap_search_pwd = xxxx
ldap_basedn = OU=Dev-wh.xxx.com,DC=dev-wh,DC=xxx,DC=com
ldap_filter = (objectClass=person)
ldap_uid = 0
ldap_scope = 2 
ldap_timeout = 5

self_registration = on
token_expiration = 30
project_creation_restriction = everyone
verify_remote_cert = on

# 數據庫相關配置,默認如果不需要使用自建的數據庫,這些配置就都不需要
db_host = mysql
db_password = root123
db_port = 3306
db_user = root
redis_url = redis:6379
clair_db_host = postgres
clair_db_password = password
clair_db_port = 5432
clair_db_username = postgres
clair_db = postgres
uaa_endpoint = uaa.mydomain.org
uaa_clientid = id
uaa_clientsecret = secret
uaa_verify_cert = true
uaa_ca_cert = /path/to/ca.pem
registry_storage_provider_name = filesystem
registry_storage_provider_config =

部署harbor

harbor支持docker-compose和kubernetes的部署方式,默認採用docker-compose作單機部署。

先執行./prepare,然後執行./install.sh進行啓動。執行./install.sh的時候,即調用了docker-compose運行了當前目錄下的docker-compose.yml文件。

在執行.prepare的時候拋出如下異常:

root@ubuntu:~/harbor# ./prepare 
Generated and saved secret to file: /data/secretkey
Generated configuration file: ./common/config/nginx/nginx.conf
Generated configuration file: ./common/config/adminserver/env
Generated configuration file: ./common/config/ui/env
Generated configuration file: ./common/config/registry/config.yml
Generated configuration file: ./common/config/db/env
Generated configuration file: ./common/config/jobservice/env
Generated configuration file: ./common/config/jobservice/config.yml
Generated configuration file: ./common/config/log/logrotate.conf
Generated configuration file: ./common/config/jobservice/config.yml
Generated configuration file: ./common/config/ui/app.conf
Fail to generate key file: ./common/config/ui/private_key.pem, cert file: ./common/config/registry/root.crt

需要修改prepare文件,將第498行:

empty_subj = "/C=/ST=/L=/O=/CN=/"

修改如下:

empty_subj = "/C=US/ST=California/L=Palo Alto/O=VMware, Inc./OU=Harbor/CN=notarysigner"

在實際啓動過程中,出現過registry啓動失敗的情況,/var/log/harbor/registry.log輸出如下:

May 30 21:06:00 172.18.0.1 registry[3218]: panic: unable to configure authorization (token): unable to open token auth root certificate bundle file "/etc/registry/root.crt": open /etc/registry/root.crt: permission denied
May 30 21:06:00 172.18.0.1 registry[3218]: 
May 30 21:06:00 172.18.0.1 registry[3218]: goroutine 1 [running]:
May 30 21:06:00 172.18.0.1 registry[3218]: panic(0xb4cd40, 0xc4203ae160)
May 30 21:06:00 172.18.0.1 registry[3218]: #011/usr/local/go/src/runtime/panic.go:500 +0x1a1
May 30 21:06:00 172.18.0.1 registry[3218]: github.com/docker/distribution/registry/handlers.NewApp(0x1067820, 0xc4203a8630, 0xc4202df180, 0x1067820)
May 30 21:06:00 172.18.0.1 registry[3218]: #011/go/src/github.com/docker/distribution/registry/handlers/app.go:302 +0x1b6a
May 30 21:06:00 172.18.0.1 registry[3218]: github.com/docker/distribution/registry.NewRegistry(0x7fcfa30dd198, 0xc4203a8630, 0xc4202df180, 0xe, 0x0, 0x0)
May 30 21:06:00 172.18.0.1 registry[3218]: #011/go/src/github.com/docker/distribution/registry/registry.go:86 +0x213
May 30 21:06:00 172.18.0.1 registry[3218]: github.com/docker/distribution/registry.glob..func1(0x108f1a0, 0xc42036d240, 0x1, 0x1)
May 30 21:06:00 172.18.0.1 registry[3218]: #011/go/src/github.com/docker/distribution/registry/registry.go:55 +0x106
May 30 21:06:00 172.18.0.1 registry[3218]: github.com/docker/distribution/vendor/github.com/spf13/cobra.(*Command).execute(0x108f1a0, 0xc42036d1f0, 0x1, 0x1, 0x108f1a0, 0xc42036d1f0)
May 30 21:06:00 172.18.0.1 registry[3218]: #011/go/src/github.com/docker/distribution/vendor/github.com/spf13/cobra/command.go:495 +0x190
May 30 21:06:00 172.18.0.1 registry[3218]: github.com/docker/distribution/vendor/github.com/spf13/cobra.(*Command).Execute(0x108f340, 0xc4201d7f40, 0xc4200001a0)
May 30 21:06:00 172.18.0.1 registry[3218]: #011/go/src/github.com/docker/distribution/vendor/github.com/spf13/cobra/command.go:560 +0x3c3
May 30 21:06:00 172.18.0.1 registry[3218]: main.main()
May 30 21:06:00 172.18.0.1 registry[3218]: #011/go/src/github.com/docker/distribution/cmd/registry/main.go:24 +0x2d

這是因爲registry容器沒有/etc/registry/root.crt的訪問權限導致。這個文件默認是掛載的./common/config/registry/root.crt這個文件,所以我們需要對這個文件作授權。

通過觀察可知,harbor的容器啓動用戶非root身份,而是以一個uid和gid都爲10000的用戶。所以只需要爲該用戶授權即可:

chown 10000.10000 ./common/config/registry/root.crt

正常啓動之後,配置完成。

可以通過如下方式訪問: https://hub.dz11.com

注意事項

需要說明的是,harbor支持http和https,但如果使用http的話,在拉取鏡像的時候,會拋出倉庫不受信任的異常。需要在所有的docker客戶端的docker配置文件/etc/docker/daemon.json中添加如下配置:

{
    "insecure-registries": ["https://hub.dz11.com"],
}

如果使用自簽名的https證書,仍然會提示證書不受信任的問題。需要將自簽名的ca證書發送到所有的docker客戶端的指定目錄。

關於使用自簽名證書配置harbor的具體過程可以參考:https://github.com/WingkaiHo/docker-calico/blob/master/harbor/README.md

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章