1. 程式人生 > >基於 Harbor 和 Cephfs 搭建高可用 Docker 映象倉庫叢集

基於 Harbor 和 Cephfs 搭建高可用 Docker 映象倉庫叢集

目錄

  • Harbor & Cephfs 介紹
  • 環境、軟體準備
  • Cephfs 檔案系統建立
  • 單節點 Harbor 服務搭建
    • 安裝 Harbor
    • 配置掛載路徑
    • 配置使用外部資料庫
  • 多節點 Harbor 叢集服務搭建
  • 測試 Habor 叢集

1、Harbor & Cephfs 介紹

Harbor 是由 VMware 公司開源的企業級的 Docker Registry 管理專案,它包括許可權管理(RBAC)、LDAP、日誌稽核、管理介面、自我註冊、映象複製和中文支援等功能,可以很好的滿足我們公司私有映象倉庫的需求。Cephfs 是 Ceph 分散式儲存系統中的檔案儲存,可靠性高,管理方便,伸縮性強,能夠輕鬆應對 PB、EB 級別資料。我們可以使用 Cephfs 作為 Harbor 底層分散式儲存使用,提高 Harbor 叢集的高可用性。

2、環境、軟體準備

本次演示環境,我是在虛擬機器 Linux Centos7 上操作,以下是安裝的軟體及版本:

  1. Docker:version 1.12.6
  2. Docker-compose: version 1.13.0
  3. Harbor: version 1.1.2
  4. Ceph:version 10.2.10
  5. Mysql:version 5.7.15

注意:要完成搭建 Harbor 高可用 Docker 映象倉庫叢集,我們使用到 Cephfs,所以需要提前搭建好 Ceph 儲存叢集,這裡就忽略搭建過程了,詳細過程可參考之前文章 初試 Centos7 上 Ceph 儲存叢集搭建。單節點 Harbor 服務的搭建以及使用配置,可參考之前文章

Docker映象倉庫Harbor之搭建及配置

本次演示 Harbor 叢集和 Ceph 儲存叢集均在本機虛擬機器搭建,由於本機記憶體限制,共開啟了 4 個虛擬機器,

admin: 10.222.77.73
node0: 10.222.78.7
node1: 10.222.78.8
nginx: 10.222.76.70
mysql: 10.222.76.74

說明一下,Ceph 儲存叢集搭建,參考之前搭建的系統,admin 作為 ceph-deploy 和 mon,node0 作為 osd0,node1 作為 osd1 (這裡我只有一個 mon,建議多配置幾個,組成 HA 高可用),並且將建立的 cephfs mount 到這三個節點上,同時在這三個節點上安裝 Harbor 服務組成一個映象倉庫叢集(這樣 Harbor 就可以直接掛載本地 cephfs 路徑了)。此外,在提供一個節點 Nginx 作為負載均衡將請求均衡到這三個節點,最後在提供一個節點 Mysql 作為外部資料庫儲存,建議做成 HA 高可用,鑑於資源有限,這裡我就暫時拿本機 Mysql 替代一下。因此節點功能圖大致如下:

這裡寫圖片描述

這裡要提一下的是,本次演示搭建的映象倉庫叢集,並不是最理想的高可用狀態,鑑於成本和資源的考慮,只要我們能保證資料安全,即我們的 Harbor 叢集出現故障,要保證資料不丟失,能夠很快恢復服務就很好。如何保證 Harbor 後端映象資料能夠及時同步,不丟失呢?Harbor 預設提供了映象複製方法,即通過配置兩個或多個 Harbor 之間相互複製映象資料規則的方式,來實現資料同步。不過這種方式對於多個 Harbor 之間資料同步,稍嫌麻煩,而且實時性有待考證。這裡我們採用多 Harbor 服務共享後端儲存的方式,即通過 Ceph 分散式儲存方案來解決。

這裡寫圖片描述

結合上圖,再次說明一下,我們在每個 Harbor 服務節點上都 mount 配置好的 cephfs,然後配置每個 Harbor 服務的各個元件 volume 都掛載 cephfs 路徑,最後通過統一的入口 Nginx 負載均衡將流量負載在各個 Harbor 服務上,來實現整個 Harbor 叢集的 “高可用”。

注意,這裡我們要將預設 harbor-db 資料庫元件拆出來,讓其連線外部 Mysql 資料庫 (預設 Harbor 會在每個節點都啟動 Mysql 服務進行資料儲存,這樣資料就沒法統一,即使我們將 Mysql 資料儲存在 cephfs 上,三個節點共用同一份資料,但是依舊不可行,因為 Mysql 多個例項之間無法共享一份 mysql 資料檔案,啟動的時候會報錯 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11)。

3、Cephfs 檔案系統建立

在安裝 Harbor 之前,我們先建立一個 Cephfs 檔案系統,具體建立過程可參考之前文章 初試 Ceph 儲存之塊裝置、檔案系統、物件儲存 中檔案儲存部分,這裡就不詳細闡述了,直接貼操作程式碼吧!

# 在 admin(ceph-deploy) 節點操作

# 建立 MDS 元資料伺服器
$ ceph-deploy mds create admin node0 node1
...

# 檢視 MDS 狀態
$ ceph mds stat
e6: 1/1/1 up {0=node0=up:active}, 1 up:standby

# 建立 cephfs
$ ceph osd pool create cephfs_data 128
pool 'cephfs_data' created
$ ceph osd pool create cephfs_metadata 128
pool 'cephfs_metadata' created
$ ceph fs new cephfs cephfs_metadata cephfs_data
new fs with metadata pool 11 and data pool 10
$ ceph fs ls
name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ]

# 檢視金鑰
$ cat /etc/ceph/ceph.client.admin.keyring
[client.admin]
    key = AQCeYjxa4vb+CBAA154r9pAO5nZyDkK8cnljDQ==
    caps mds = "allow *"
    caps mon = "allow *"
    caps osd = "allow *"

# 建立金鑰檔案    
$ sudo vim /etc/ceph/admin.secret
AQCeYjxa4vb+CBAA154r9pAO5nZyDkK8cnljDQ==

# 建立掛載目錄
$ sudo mkdir /mnt/cephfs

# 掛載 cephfs 到該目錄,並指明使用者名稱和金鑰
$ sudo mount -t ceph 10.222.77.73:6789:/ /mnt/cephfs -o name=admin,secretfile=/etc/ceph/admin.secret

$ df -h
...
10.222.77.73:6789:/   66G   31G   36G   47% /mnt/cephfs

經過上邊操作,我們就建立好了一個 cephfs 檔案系統了。而且將 cephfs 掛載到了 admin 節點的 /mnt/cephfs 目錄,下邊該節點安裝 Harbor 的時候,就可以直接將 volume 修改到此目錄即可。

4、單節點 Harbor 服務搭建

接下來,我們以一臺節點 admin 為例,安裝並配置 Harbor 服務,其他 node0 和 node1 節點照此操作即可了。

4.1 安裝 Harbor

# 下載 Harbor 安裝包
$ sudo mkdir /home/cephd/harbor && cd /home/cephd/harbor
$ wget https://github.com/vmware/harbor/releases/download/v1.1.2/harbor-offline-installer-v1.1.2.tgz
$ tar -zxvf harbor-offline-installer-v1.1.2.tgz
$ cd harbor

# 修改 harbor.cfg 配置
hostname = 10.222.77.73

$ ./install.sh
...

# docker ps
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS              PORTS                                                              NAMES
8fa11d4329bd        vmware/nginx:1.11.5-patched        "nginx -g 'daemon off"   15 seconds ago      Up 13 seconds       0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp   nginx
fb3c7567dbd6        vmware/harbor-jobservice:v1.1.2    "/harbor/harbor_jobse"   15 seconds ago      Up 13 seconds                                                                          harbor-jobservice
e79ed895dd7e        vmware/harbor-ui:v1.1.2            "/harbor/harbor_ui"      16 seconds ago      Up 14 seconds                                                                          harbor-ui
371ba59c7ce8        vmware/registry:2.6.1-photon       "/entrypoint.sh serve"   18 seconds ago      Up 16 seconds       5000/tcp                                                           registry
5b259f7dedd8        vmware/harbor-db:v1.1.2            "docker-entrypoint.sh"   18 seconds ago      Up 16 seconds       3306/tcp                                                           harbor-db
6308ca7f1d7d        vmware/harbor-adminserver:v1.1.2   "/harbor/harbor_admin"   18 seconds ago      Up 16 seconds                                                                          harbor-adminserver
1be51fdfbb62        vmware/harbor-log:v1.1.2           "/bin/sh -c 'crond &&"   19 seconds ago      Up 17 seconds       127.0.0.1:1514->514/tcp    

執行完畢,如果一切順利的話,我們就可以通過瀏覽器訪問 http://10.222.77.73 看到 Harbor UI 頁面了。

4.2 配置掛載路徑

Harbor 預設將儲存資料 volume 掛載到主機 /data 目錄下,日誌 volume 掛載到主機 /var/log/harbor/ 目錄下。既然上邊我們已經搭建好了 Cephfs 儲存保證資料的高可用,那麼這裡就需要修改 Harbor 各個元件掛載的路徑,分別將資料和日誌 volume 掛載到 cephfs 在節點上的路徑 /mnt/cephfs/harbor/ 路徑下,這裡我們需要修改兩個檔案,分別為 docker-compose.yml 和 harbor.cfg。

修改 docker-compose.yml 如下

8c8
<       - /var/log/harbor/:/var/log/docker/:z
---
>       - /mnt/cephfs/harbor/log/:/var/log/docker/:z
18c18
<       - /data/registry:/storage:z
---
>       - /mnt/cephfs/harbor/data/registry:/storage:z
57,59c57,59
<       - /data/config/:/etc/adminserver/config/:z
<       - /data/secretkey:/etc/adminserver/key:z
<       - /data/:/data/:z
---
>       - /mnt/cephfs/harbor/data/config/:/etc/adminserver/config/:z
>       - /mnt/cephfs/harbor/data/secretkey:/etc/adminserver/key:z
>       - /mnt/cephfs/harbor/data/:/data/:z
78,79c78,79
<       - /data/secretkey:/etc/ui/key:z
<       - /data/ca_download/:/etc/ui/ca/:z
---
>       - /mnt/cephfs/harbor/data/secretkey:/etc/ui/key:z
>       - /mnt/cephfs/harbor/data/ca_download/:/etc/ui/ca/:z
98c98
<       - /data/job_logs:/var/log/jobs:z
---
>       - /mnt/cephfs/harbor/data/job_logs:/var/log/jobs:z
100c100
<       - /data/secretkey:/etc/jobservice/key:z
---
>       - /mnt/cephfs/harbor/data/secretkey:/etc/jobservice/key:z

修改 harbor.cfg 如下:

#The path of cert and key files for nginx, they are applied only the protocol is set to https
ssl_cert = /mnt/cephfs/harbor/data/cert/server.crt
ssl_cert_key = /mnt/cephfs/harbor/data/cert/server.key

#The path of secretkey storage
secretkey_path = /mnt/cephfs/harbor/data

修改完配置之後,我們需要重啟一下 Harbor 服務。

$ docker-compose down -v
$ dokcer-compose up -d
或
$./install

這次 Harbor 服務啟動之後,我們再次瀏覽器訪問 http://10.222.77.73,會發現使用了cephfs 之後,頁面載入速度有所降低,比上邊直接本機儲存的方式要慢一些。

確認一下是否已經資料和日誌儲存到 cephfs 儲存目錄啦!

$ ls -al /mnt/cephfs/harbor/
drw------- 1 root root 5 1222 11:49 data
drwxr-xr-x 1 root root 1 1222 11:49 log

OK 到此,Harbor 儲存這塊已經達到了高可用,那麼接下來就要遷移一下 db 儲存到外部資料庫。在遷移資料之前,我們先來簡單的操作一下,造一點資料儲存到預設 Mysql 資料庫裡面去,方便後邊 Harbor 其他節點搭建完畢後,驗證資料是否同步。

首先使用一個新的使用者 wanyang3 上傳一個 nginx 映象到該節點 Harbor 倉庫中。建立使用者 wanyang3 並且建立一個 wanyang3 的專案,並分配該專案許可權給使用者 wanyang3,這部分可以在 Harbor UI 頁面上操作,這裡就不在演示了。

# 注意以下操作前修改一下 docker 配置檔案,增加 –insecure-registry=10.222.77.73
# 登入 Harbor
$ docker login 10.222.77.73
Username: wanyang3
Password:
Login Succeeded

# tag 並 push 映象到 Harbor
$ docker tag nginx:1.11 10.222.77.73/wanyang3/nginx:1.11
$ docker push 10.222.77.73/wanyang3/nginx:1.11
The push refers to a repository [10.222.77.73/wanyang3/nginx]
cbb475ff5c8e: Pushed
2eea2d5e43e6: Pushed
b6ca02dfe5e6: Pushed
1.11: digest: sha256:820c2fa427c19d4369271dfc529870f7c4b963f7c56d7dcedd1426cbaf739946 size: 948

實測確實有點慢啊!有點慢啊!有點慢啊!難道是 cephfs 資料同步到其他 node 花費了這麼多時間麼。。。

再次檢視下映象資料有沒有儲存到 cephfs 中吧!

$ ls -al /mnt/cephfs/harbor/data/registry/docker/registry/v2/repositories/wanyang3/nginx
drwxr-xr-x 1 root root 1 1222 11:57 _layers
drwxr-xr-x 1 root root 2 1222 11:58 _manifests
drwxr-xr-x 1 root root 0 1222 11:58 _uploads

4.3 配置使用外部資料庫

上邊提到,將 Mysql 資料儲存在 cephfs 上,三個節點共用同一份資料,但是發現不可行,因為 Mysql 多個例項之間無法共享一份 mysql 資料檔案,啟動的時候會報錯 [ERROR] InnoDB: Unable to lock ./ibdata1, error: 11。所以,我們需要使用外部資料庫或者 HA 資料庫叢集來解決這個問題。這裡我暫時使用本機的 Mysql 資料庫來替代一下,所以並不是理想狀態下的 HA,如果想實現 db 高可用,大家可以自行搭建一下吧!

4.3.1 遷移 db 資料

因為之前的操作,已經有一部分資料儲存到 harbor-db 資料庫裡面去了,而且 Harbor 啟動時也會建立好所需要的資料庫、表和資料等。這裡我們先進入 harbor-db 容器中,將 registry 資料庫 dump 一份,然後 Copy 到當前節點機器。

# 進入 harbor-db 容器
$ docker exec -it e23760eba95e bash

# 備份資料到預設目錄 /tmp/registry.dump 
$ mysqldump -u root -p registry > registry.dump        
Enter password: root123
$ exit

# 退出容器,copy 備份資料到當前節點機器。
$ docker cp e23760eba95e:/tmp/registry.dump /home/cephd/harbor/

# 將備份資料通過共享資料夾複製到本機
$ cp /home/cephd/harbor/registry.dump /media/sf_share/

注意:因為當前 master 節點沒有安裝 mysql-client,所以無法通過 mysql -h <db_ip> -P <db_port> -u <db_user> -p <db_password> 直接連線外部資料庫操作。因此,這裡我通過虛擬機器共享資料夾將資料複製到本機。

現在資料已經到本機了,接下來我們就可以登入本機 Mysql,建立使用者並匯入資料了。

$ mysql -u root -p xxxxxx
mysql> CREATE USER 'harbor'@'%' IDENTIFIED BY 'root123'; 
mysql> GRANT ALL ON *.* TO 'harbor'@'%';
mysql> FLUSH PRIVILEGES;

這裡為了方便後續操作,我們建立一個專門的賬戶 harbor,並賦上所有操作許可權。接下來使用 harbor 賬戶登入,建立資料庫 registry 並匯入 dump 資料。

$ mysql -u harbor -p xxxxxx
mysql> CREATE DATABASE IF NOT EXISTS registry default charset utf8 COLLATE utf8_general_ci;
mysql> USE registry;
Database changed
mysql> source /Users/wanyang3/VirtualBox VMs/share/registry.dump;

OK 現在外部資料庫也已經搞定了,那怎麼樣讓 Harbor 元件使用我們配置的外部 db 呢?

4.3.2 修改配置使用外部 db

首先,既然我們已經有外部資料庫了,那麼就不需要 Harbor 在啟動 harbor-db 服務了,只需要配置連線外部資料庫即可。因此就需要刪除 docker-compose.yml 中 mysql 相關配置。

# 刪除以下 mysql 配置
mysql:
    image: vmware/harbor-db:v1.1.2
    container_name: harbor-db
    restart: always
    volumes:
      - /data/database:/var/lib/mysql:z
    networks:
      - harbor
    env_file:
      - ./common/config/db/env
    depends_on:
      - log
    logging:
      driver: "syslog"
      options:  
        syslog-address: "tcp://127.0.0.1:1514"
        tag: "mysql"

# 刪除 depends_on 中 mysql 部分
depends_on:
  # - mysql # 此處刪除
  - registry
  - ui
  - log

其次,我們還需要修改 ./common/config/adminserver/env 配置,這裡面主要存放的是一些配置資訊,裡面就有配置 Mysql 的連線資訊。因為該檔案是執行 install.sh 的時候根據 ./common/templates/adminserver/env 配置生成的,所以即使我們修改了,也是一次性的,重新 install 又會覆蓋掉,所以可以直接修改 ./common/templates/adminserver/env 該檔案就一勞永逸了。

# 修改 ./common/templates/adminserver/env 檔案
...
MYSQL_HOST=10.222.76.74
MYSQL_PORT=3306
MYSQL_USR=harbor
MYSQL_PWD=root123
MYSQL_DATABASE=registry
...
RESET=true

注意:這裡一定要設定 RESET=true 因為只有設定了該開關,Harbor 才會在啟動時覆蓋預設配置,啟用我們配置的資訊。

再次啟動 Harbor 服務,看下能否啟動成功,能否正常連線配置的外部資料庫吧。

# 重啟 Harbor 服務
$ docker-compose down -v
$ dokcer-compose up -d
或
$./install

# 檢視 Harbor 各元件容器啟動狀態,harbor-db 服務已經移除
$ docker ps
CONTAINER ID        IMAGE                              COMMAND                  CREATED             STATUS              PORTS                                                              NAMES
b1ab727bc072        vmware/nginx:1.11.5-patched        "nginx -g 'daemon off"   4 seconds ago       Up 2 seconds        0.0.0.0:80->80/tcp, 0.0.0.0:443->443/tcp, 0.0.0.0:4443->4443/tcp   nginx
d818f03c08f8        vmware/harbor-jobservice:v1.1.2    "/harbor/harbor_jobse"   4 seconds ago       Up 2 seconds                                                                           harbor-jobservice
77f4fd50d1d9        vmware/harbor-ui:v1.1.2            "/harbor/harbor_ui"      4 seconds ago       Up 3 seconds                                                                           harbor-ui
933b3273c062        vmware/registry:2.6.1-photon       "/entrypoint.sh serve"   5 seconds ago       Up 3 seconds        5000/tcp                                                           registry
c7e93e736150        vmware/harbor-adminserver:v1.1.2   "/harbor/harbor_admin"   5 seconds ago       Up 4 seconds                                                                           harbor-adminserver
29efd79e17c8        vmware/harbor-log:v1.1.2           "/bin/sh -c 'crond &&"   6 seconds ago       Up 4 seconds        127.0.0.1:1514->514/tcp  

# 檢視 ui 和 jobservice 日誌,是否連線上 mysql
$ cat /mnt/cephfs/harbor/log/2017-12-22/ui.log
...
Dec 22 14:40:28 172.18.0.1 ui[26424]: 2017-12-22T06:40:28Z [INFO] configurations initialization completed
Dec 22 14:40:28 172.18.0.1 ui[26424]: 2017-12-22T06:40:28Z [INFO] initializing database: type-MySQL host-10.222.76.74 port-3306 user-harbor database-registry
Dec 22 14:40:28 172.18.0.1 ui[26424]: 2017-12-22T06:40:28Z [INFO] initialize database completed

$cat /mnt/cephfs/harbor/log/2017-12-22/cat /mnt/cephfs/harbor/log/2017-12-22/jobservice.log
...
Dec 22 14:40:29 172.18.0.1 jobservice[26424]: 2017-12-22T06:40:29Z [INFO] configurations initialization completed
Dec 22 14:40:29 172.18.0.1 jobservice[26424]: 2017-12-22T06:40:29Z [INFO] initializing database: type-MySQL host-10.222.76.74 port-3306 user-harbor database-registry
Dec 22 14:40:29 172.18.0.1 jobservice[26424]: 2017-12-22T06:40:29Z [INFO] initialize database completed

OK 成功啟動,harbor-db 服務按照設計也沒有啟動,日誌顯示連線外部資料庫也沒有問題,再次通過瀏覽器訪問 http://10.222.77.73 看下之前操作的資料是否能夠正常顯示出來吧!

這裡寫圖片描述

妥妥沒問題! 到此,單節點的 Harbor 服務已經完成了倉庫儲存和資料庫儲存的 “高可用”,實際應用中,單一節點肯定是不能滿足需求的,暫且不說能否抵抗高流量的訪問衝擊,光發生節點故障時,就沒法滿足映象倉庫叢集的高可用性,所以我們還需要搭建多個 Harbor 節點組成一個叢集。

5、多節點 Harbor 叢集服務搭建

單節點 Harbor 服務搭建以及配置 “高可用” 已經搞定,其他節點也就同樣操作了,不過也要稍微改下配置,這裡就不一一詳細描述過程了,直接貼操作過程,這裡以 node0 (10.222.78.7) 操作為例。

# 登入 node0 節點操作 
$ ssh node0

# 檢視當前 MDS 狀態,顯示報錯,是因為檔案許可權的問題
$ ceph mds stat
2017-12-22 15:03:16.626707 7fec89740700 -1 auth: unable to find a keyring on /etc/ceph/ceph.client.admin.keyring,/etc/ceph/ceph.keyring,/etc/ceph/keyring,/etc/ceph/keyring.bin: (2) No such file or directory
2017-12-22 15:03:16.626715 7fec89740700 -1 monclient(hunting): ERROR: missing keyring, cannot use cephx for authentication
2017-12-22 15:03:16.626716 7fec89740700  0 librados: client.admin initialization error (2) No such file or directory
Error connecting to cluster: ObjectNotFound

# 對金鑰檔案賦許可權
$ sudo chmod +r /etc/ceph/ceph.client.admin.keyring

# 檢視當前 MDS 狀態顯示正常狀態
$ ceph mds stat
e6: 1/1/1 up {0=node0=up:active}, 1 up:standby

# 檢視當前 fs 列表,注意一個叢集只支援一個 cephfs
$ ceph fs ls
name: cephfs, metadata pool: cephfs_metadata, data pools: [cephfs_data ]

# 檢視金鑰
$ cat /etc/ceph/ceph.client.admin.keyring 
[client.admin]
    key = AQCeYjxa4vb+CBAA154r9pAO5nZyDkK8cnljDQ==
    caps mds = "allow *"
    caps mon = "allow *"
    caps osd = "allow *"

# 建立金鑰檔案    
$ sudo vim /etc/ceph/admin.secret
AQCeYjxa4vb+CBAA154r9pAO5nZyDkK8cnljDQ==

# 建立掛載目錄並掛載 cephfs 到該目錄,並指明使用者名稱和金鑰
$ sudo mkdir /mnt/cephfs
$ sudo mount -t ceph 10.222.77.73:6789:/ /mnt/cephfs -o name=admin,secretfile=/etc/ceph/admin.secret

$ df -h
...
10.222.77.73:6789:/   66G   31G   36G   47% /mnt/cephfs

# 顯示資料已經掛載進來了,這是上邊 admin 節點啟動 Harbor 時建立的資料
$ sudo ls -al /mnt/cephfs/harbor/
drw------- 1 root root 5 1222 11:49 data
drwxr-xr-x 1 root root 1 1222 11:49 log

# 切換到 root  使用者操作,操作同上邊單節點操作。
1、下載 harbor 安裝包
2、修改 harbor.conf 
hostname = 10.222.78.7
ssl_cert = /mnt/cephfs/harbor/data/cert/server.crt
ssl_cert_key = /mnt/cephfs/harbor/data/cert/server.key
secretkey_path = /mnt/cephfs/harbor/data

3、修改 docker-compose.yml
刪除 mysql 配置,修改 log 元件 volume 配置路徑為
volumes:
      - /mnt/cephfs/harbor/log0/:/var/log/docker/:z
將各個節點日誌分隔開,不然日誌會覆蓋,不方便查詢問題。

4、修改 common/templates/adminserver/env 配置 mysql 連線

5、啟動 Harbor 服務
./install.sh

6、檢視掛載資料 ls -al /mnt/cephfs/harbor/
drwxr-xr-x 1 root root 1 1222 15:25 log0
drw------- 1 root root 5 1222 11:49 data
drwxr-xr-x 1 root root 1 1222 11:49 log

好了,經過上述操作,node0 也已經成功啟動了 Harbor 服務,並且倉庫儲存及日誌使用了 cephfs 共享儲存,db 資料儲存使用了外部資料庫,同理,按照上述操作步驟對 node1 (10.222.78.8) 進行操作,這裡就不描述了。

6、測試 Habor 叢集

好了,現在已經建立好了由三個 Harbor 節點組成的一個簡單的 “高可用” 映象倉庫叢集,那麼接下來,我們來測試一下 Harbor 叢集。我們都知道,生產環境下,針對某個服務叢集,一般使用一個統一的域名進行訪問,然後將請求負載均衡分發到各個子節點上。這裡我們就模擬一下通過統一 IP(生產環境下申請域名替換即可) 入口訪問該 Harbor 叢集吧!

這裡,我們在一個新的節點 Nginx (10.222.76.70) 上邊安裝 Nginx 服務,作為訪問 Harbor 服務統一的入口,然後負載均衡到上邊各個 Harbor 子節點上。為了快速安裝 Nginx,可採用 Docker 方式啟動 Nginx 服務。

# 建立 default.conf 配置檔案
$ mkdir /root/nginx
$ vim default.conf
upstream service_harbor {
    server 10.222.77.73;
    server 10.222.78.7;
    server 10.222.78.8;
    ip_hash;
}

server {
    listen       80;
    server_name  10.222.76.70;
    index  index.html index.htm;    

    #access_log  /var/log/nginx/host.access.log  main;

    location / {
        add_header Access-Control-Allow-Origin *;
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_pass http://service_harbor;    
    }

    access_log /var/log/harbor.access.log;
    error_log /var/log/harbor.error.log;    

    error_page  404              /404.html;

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}

# Docker 啟動 Nginx 服務,掛載上邊配置檔案覆蓋預設配置,並開放 80 埠
docker run --name nginx-harbor -p 80:80 -v /root/nginx/default.conf:/etc/nginx/conf.d/default.conf:ro -d nginx

OK 現在 Nginx 服務也起來了,我們來測試一下,通過瀏覽器訪問 http://10.222.76.70/ 是否能夠訪問 Harbor UI 吧!

這裡寫圖片描述

妥妥沒問題的,我們可以看到資料也是同步顯示出來的。接下來我們本機或其他機器通過命令列方式登入 Harbor 並且嘗試推送一個新的 Image 到映象倉庫叢集中試試吧。

# 注意以下操作前修改一下 docker 配置檔案,增加 –insecure-registry=10.222.76.70
# 登入 Harbor
$ docker login 10.222.76.70
Username: wanyang3
Password:
Login Succeeded

# tag 並 push 映象到 Harbor
$ docker tag tomcat:8.0 10.222.76.70/wanyang3/tomcat:8.0
$ docker push 10.222.76.70/wanyang3/tomcat:8.0
The push refers to a repository [10.222.76.70/wanyang3/tomcat]
06a56cfbd702: Pushed
978148d13d7d: Pushing [==================================================>]  16.32MB/16.32MB
e31c8669b930: Pushing [==================================================>]    130kB
8443dd1bccc9: Pushing [==================================================>]  7.316MB/7.316MB
bf40d7791c7e: Pushed
9125381ad905: Pushing   2.56kB
be6a597f6221: Waiting
ff8f2671c638: Waiting
9e9ecb074181: Waiting
60a0858edcd5: Waiting
b6ca02dfe5e6: Waiting
error parsing HTTP 413 response body: invalid character '<' looking for beginning of value: "<html>\r\n<head><title>413 Request Entity Too Large</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>413 Request Entity Too Large</h1></center>\r\n<hr><center>nginx/1.13.7</center>\r\n</body>\r\n</html>\r\n"

不過貌似發生了錯誤 413 Request Entity Too Large。。。 出現這個錯誤,是因為 Nginx 預設設定的接收客戶端傳送的 body 實體長度太小所致,解決辦法就是增大接收 body 實體長度限制。

$ vim default.conf
    ...
    location / {
         ...
         client_max_body_size  1024m  # 設定接收客戶端 body 最大長度為 1024M
     }

這裡我設定 1G 大小,基本上能夠滿足日常需求。重啟 nginx-harbor 容器,然後再次 push 一下試試。

# nginx (10.222.76.70) 節點上重啟
$ docker restart nginx-harbor

# 本機 push 映象到 Harbor
$ docker push 10.222.76.70/wanyang3/tomcat:8.0
The push refers to a repository [10.222.76.70/wanyang3/tomcat]
06a56cfbd702: Layer already exists
978148d13d7d: Pushed
e31c8669b930: Layer already exists
8443dd1bccc9: Pushed
bf40d7791c7e: Layer already exists
9125381ad905: Layer already exists
be6a597f6221: Pushed
ff8f2671c638: Pushed
9e9ecb074181: Pushed
60a0858edcd5: Pushed
b6ca02dfe5e6: Pushed
8.0: digest: sha256:13d33abafd848993176a8a04e3c4143bdf8aeda2454705f642bf37cfe80730d5 size: 2624

# 任意 Harbor 服務節點檢視下資料是否儲存到 cephfs
$ ll -al /mnt/cephfs/harbor/data/registry/docker/registry/v2/repositories/wanyang3
drwxr-xr-x 1 root root 3 1222 11:58 nginx
drwxr-xr-x 1 root root 3 1222 16:53 tomcat

# 測試下 pull,先刪除本地已存在的映象 tag 以及原映象,否則不會執行 pull
$ docker rmi 10.222.76.70/wanyang3/tomcat:8.0
Untagged: 10.222.76.70/wanyang3/tomcat:8.0
Untagged: 10.222.76.70/wanyang3/[email protected]:13d33abafd848993176a8a04e3c4143bdf8aeda2454705f642bf37cfe80730d5
$ docker rmi tomcat:8.0

# pull 映象
$ docker pull 10.222.76.70/wanyang3/tomcat:8.0
8.0: Pulling from wanyang3/tomcat
1ade878aecd1: Already exists
fdca7d84dcaf: Pull complete
89db77df620b: Pull complete
b0cac26819d3: Pull complete
fd0c12e9a364: Pull complete
6e834cb7f4c2: Pull complete
e23224460585: Pull complete
2978c7a1a062: Pull complete
a1b2cddfa98e: Pull complete
cf2776c8b30b: Pull complete
3a0099682c97: Pull complete
Digest: sha256:13d33abafd848993176a8a04e3c4143bdf8aeda2454705f642bf37cfe80730d5
Status: Downloaded newer image for 10.222.76.70/wanyang3/tomcat:8.0

實測,Push 速度確實有點慢哈!網上搜索了一下,確實大家反映 cephfs 分散式檔案系統整體效能不是很理想,會慢一些,不過 Ceph 可以根據系統環境進行效能調優,比如 osd、 rbd chache 引數調優等,當然對這個 Ceph 調優我不太瞭解,以後有時間在慢慢研究下吧!

這裡寫圖片描述

值的一提的是,當我嘗試在 Harbor UI 上刪除某一個映象時,發現 cephfs 共享儲存中依舊存在,我們可以通過刪除某映象後再次 push 該映象來驗證一下。

# Harbor UI 上先刪除 wanyang3/tomcat:8.0 映象,在進行如下操作

$ docker push 10.222.76.70/wanyang3/tomcat:8.0
The push refers to a repository [10.222.76.70/wanyang3/tomcat]
06a56cfbd702: Layer already exists
978148d13d7d: Layer already exists
e31c8669b930: Layer already exists
8443dd1bccc9: Layer already exists
bf40d7791c7e: Layer already exists
9125381ad905: Layer already exists
be6a597f6221: Layer already exists
ff8f2671c638: Layer already exists
9e9ecb074181: Layer already exists
60a0858edcd5: Layer already exists
b6ca02dfe5e6: Layer already exists
8.0: digest: sha256:13d33abafd848993176a8a04e3c4143bdf8aeda2454705f642bf37cfe80730d5 size: 2624

會顯示遠端倉庫已經存在該映象了。這是什麼原因呢? 查看了下 Harbor 文件,發現我們在 UI 上執行 Delete 操作,是邏輯刪除,並沒有執行真正的物理檔案刪除,這也就解釋了為啥第二次 push 會顯示遠端已經存在了。如果我們想刪除物理檔案的話,可以通過官方提供的方法執行 GC 回收。

# 執行 GC 前需要停止 Harbor 服務
$ docker-compose stop

# docker 啟動 gc 容器刪除映象資料,可以加上 --dry-run 引數,這樣會只打印詳情,並未真正執行刪除操作。
$ docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect --dry-run /etc/registry/config.yml

# 確認上述列印詳情日誌沒問題後,去掉引數,執行刪除操作。
$ docker run -it --name gc --rm --volumes-from registry vmware/registry:2.6.2-photon garbage-collect /etc/registry/config.yml

通過上邊一系列的操作,一個 “高可用” 的 Docker 映象倉庫叢集就搭建完成了,基本能夠滿足我們的日常需求。不過之所以稱之為帶引號的高可用,因為還有幾個地方可以改進下,比如 Ceph 叢集 HA 高可用、Cephfs 效能調優、Mysql 叢集達到 HA 高可用、增加 Harbor 叢集節點數來支撐大流量的衝擊、Nginx 引數調優等等。

參考資料