Kubernetes-5-2:Harbor倉庫的幾種高可用方案與搭建

高可用Harbor搭建 

思路及介紹
Harbor官方有推出主從架構和雙主架構來實現Harbor的高可用及數據備份。
 
一、主從架構:
 說白了,就是往一台Harbor倉庫中push鏡像,然後再通過這台Harbor分散下發至所有的從Harbor,類似下圖:
這個方法保證了數據的冗餘性,但是仍然解決不了Harbor主節點的單點問題,當業務量足夠大時,甚至會引起主節點崩潰。

 

二、雙主架構:

雙主複製就是兩套Harbor的數據互相同步,來保證數據的一致性,然後兩套Harbor的前端再掛一層負載,來達到分均流量、減輕某一台壓力過大的現象,也避免了單點故障,類似於下圖:

這個方案有一個問題:假設有實例A和實例B互為主備,當A掛掉後,所有的業務流量就會流向B,當A修復後,B不會自動同步A新push的鏡像,還要手動將B的同步策略關閉,重新開啟才能開始同步。
 

三、還有一種就是利用共享存儲和共享資料庫來實現服務的高可用性和數據的冗餘,我們也是推薦用這種高可用方式:

思路如下:
  1. 將PostgreSQL服務單獨部署出來,並將Harbor中默認創建在PostgreSQL的所有表的結構、初始數據等導入進單獨部署的PostgreSQL服務中,PostgreSQL數據的冗餘就完全可以使用PostgreSQL的同步策略來實現;
  2. Redis服務單獨部署出來,其他特殊操作無需執行,Redis的高可用也可直接使用其集群解決方案;
  3. 最後存儲後端要使用共享存儲,來實現數據的統一;

 

具體操作

環境介紹
Harbor基於Docker環境運行,所使用的機器必須有docker及docker-compose
ip
系統版本
服務
192.168.24.253(post1)
Centos7
PostgreSQL、Redis、Harbor
192.168.24.252(post2)
Centos8
NFS、Harbor
在此所有其他服務均搭建在post1中,並且是搭建單機,僅為演示使用,生產中數據的備份等再自行研究。
我這裡post1 和 post2的域名分別為:
    hub.vfancloud1.com;hub.vfancloud2.com,記得先要寫入hosts文件中以防解析不到。
 
1、先部署一套Harbor,用於將其所有表結構導出,部署過程上文已給出:
https://www.cnblogs.com/v-fan/p/13034272.html

 

2、進入導出PostgreSQL表結構

## 進入PostgreSQL容器
docker exec -it xxxx bash

## 執行 psql 進入資料庫
postgres [ / ]$ psql
psql (9.6.14)
Type "help" for help.

## 查看當前所有的資料庫,postgres、template0、template1為默認資料庫
postgres=# \l
                                   List of databases
     Name     |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
--------------+----------+----------+-------------+-------------+-----------------------
 notaryserver | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres         +
              |          |          |             |             | postgres=CTc/postgres+
              |          |          |             |             | server=CTc/postgres
 notarysigner | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =Tc/postgres         +
              |          |          |             |             | postgres=CTc/postgres+
              |          |          |             |             | signer=CTc/postgres
 postgres     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 registry     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 template0    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
              |          |          |             |             | postgres=CTc/postgres
 template1    | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | =c/postgres          +
              |          |          |             |             | postgres=CTc/postgres
(6 rows)

## 導出表結構及數據
postgres [ / ]$ pg_dump -U postgres registry > /tmp/registry.sql
postgres [ / ]$ pg_dump -U postgres notaryserver > /tmp/notaryserver.sql
postgres [ / ]$ pg_dump -U postgres notarysigner > /tmp/notarysigner.sql
    -U 資料庫用戶
    -p 訪問埠
    -f 指定文件,和 > 功能一樣
    -h 指定資料庫地址
    -s 表示只導出表結構,不導數據

## 導出到宿主機
docker cp [容器id]:/tmp/registry.sql ./
docker cp [容器id]:/tmp/notaryserver.sql ./
docker cp [容器id]:/tmp/notarysigner.sql ./

 

3、單獨部署一套PostgreSQL服務

# Install RPM
sudo yum install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# Install server
sudo yum install -y postgresql13-server

# init db
sudo /usr/pgsql-13/bin/postgresql-13-setup initdb

# 修改遠程訪問配置
vim /var/lib/pgsql/13/data/postgresql.conf
...
將 listen_addresses = 'localhost' 修改為
listen_addresses = '*'
...

# 添加信任的遠程連接,生產中不要添加0.0.0.0
vim /var/lib/pgsql/13/data/pg_hba.conf
...
host    all             all             0.0.0.0/0               trust
# host    all             all             0.0.0.0/0               md5
# 最後一列如果是trust,則登錄pg不需要密碼,若為md5,則需要密碼
...


# start and enable server
sudo systemctl enable postgresql-13
sudo systemctl start postgresql-13

# 檢查服務是否啟動成功
ps看進程 或 ss看埠號

 

4、給postgresql設置密碼,增強安全性

## 直接寫入新密碼
postgres=# \password
輸入新的密碼:
再次輸入:

 

5、將備份的數據,導入進單獨部署的postgresql中

## 創建資料庫
postgres=# CREATE DATABASE registry;
postgres=# CREATE DATABASE notaryserver;
postgres=# CREATE DATABASE notarysigner;

## 導入數據
psql -h post1 -U postgres -p 5432 -d registry -f registry.sql 
psql -h post1 -U postgres -p 5432 -d notaryserver -f notaryserver.sql 
psql -h post1 -U postgres -p 5432 -d notarysigner -f notarysigner.sql 
    -U 資料庫用戶
    -p 訪問埠
    -f 指定文件,和 < 功能一樣
    -h 指定資料庫地址
    -d 指定資料庫名

 

6、搭建共享存儲(在此以nas為例)

## 安裝nfs工具
yum -y install nfs-utils rpcbind

## 編輯共享目錄
vim /etc/exports
...
/alibaba *(rw,no_root_squash,no_all_squash,sync)
...

## 掛載
mkdir /alibaba
mount -t nfs post2:/alibaba/ /alibaba/

 

7、搭建Redis
## 安裝 || 或源碼安裝自行選擇
yum -y install redis

## 
vim /etc/redis
...
bind 0.0.0.0 # 設置所有主機可以連接
requirepass redis # 設置客戶端連接密碼
daemonize yes # 打開守護進程模式
...

## 啟動redis
systemctl start redis

## 查看埠狀態
[root@centos7 src]# ss -tnlp | grep 6379 
LISTEN     0      128    127.0.0.1:6379                     *:*                   users:(("redis-server",pid=3405,fd=6))

 

8、配置Harbor

## 自行下載源碼包
https://github.com/goharbor/harbor/releases

## 解壓進入
tar zxvf harbor-offline-installer-v2.1.2.tgz && cd harbor/

## 導入鏡像
docker load -i harbor.v2.1.2.tar.gz

## 編輯配置文件,需要更改的主要有以下幾點:
    1.hostname 改為主機ip或完全限定域名,不要使用127.0.0.1或localhost
    2.https選項,如需要,指定crt和key的路徑,若不需要,直接注釋掉
    3.harbor_admin_password,默認密碼,可以更改
    4.data_volume,數據默認存儲位置,設計為共享路徑
    5.注釋掉database模組 及 Clair模組
    6.開啟external_database 和 external_redis模組及正確配置其中參數
    7.集群內所有harbor配置均一樣,改一下hostname值即可
下邊進行實際修改,以下為我的配置:
vim harbor.yml.tmpl

hostname: hub.vfancloud1.com

https:
  # https port for harbor, default is 443
  port: 443
  # The path of cert and key files for nginx
  certificate: /data/cert/server.crt
  private_key: /data/cert/server.key

harbor_admin_password: Harbor12345

data_volume: /alibaba

external_database:
  harbor:
    host: 192.168.24.253
    port: 5432
    db_name: external_redis
    username: postgres
    password: 123456
    ssl_mode: disable
    max_idle_conns: 2
    max_open_conns: 0
  clair:
    host: 192.168.24.253
    port: 5432
    db_name: clair
    username: postgres
    password: 123456
    ssl_mode: disable
  notary_signer:
    host: 192.168.24.253
    port: 5432
    db_name: notarysigner
    username: postgres
    password: 123456
    ssl_mode: disable
  notary_server:
    host: 192.168.24.253
    port: 5432
    db_name: notaryserver
    username: postgres
    password: 123456
    ssl_mode: disable

external_redis:
  # support redis, redis+sentinel
  # host for redis: <host_redis>:<port_redis>
  # host for redis+sentinel:
  #  <host_sentinel1>:<port_sentinel1>,<host_sentinel2>:<port_sentinel2>,<host_sentinel3>:<port_sentinel3>
  host: 192.168.24.253:6379
  password: redis
  # sentinel_master_set must be set to support redis+sentinel
  #sentinel_master_set:
  # db_index 0 is for core, it's unchangeable
  registry_db_index: 1
  jobservice_db_index: 2
  chartmuseum_db_index: 3
  clair_db_index: 4
  trivy_db_index: 5
  idle_timeout_seconds: 30
開始安裝:
./install.sh----Harbor has been installed and started successfully.----

[root@kubenode2 harbor]# docker ps 
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS                   PORTS                                         NAMES
0fffdbdc1efd        goharbor/harbor-jobservice:v2.1.2    "/harbor/entrypoint.…"   3 minutes ago       Up 3 minutes (healthy)                                                 harbor-jobservice
330d73923321        goharbor/nginx-photon:v2.1.2         "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes (healthy)   0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp   nginx
f6511d387e7f        goharbor/harbor-core:v2.1.2          "/harbor/entrypoint.…"   3 minutes ago       Up 3 minutes (healthy)                                                 harbor-core
2fe648a128da        goharbor/harbor-registryctl:v2.1.2   "/home/harbor/start.…"   3 minutes ago       Up 3 minutes (healthy)                                                 registryctl
62c6de742d9b        goharbor/registry-photon:v2.1.2      "/home/harbor/entryp…"   3 minutes ago       Up 3 minutes (healthy)                                                 registry
f5e6b82363bb        goharbor/harbor-portal:v2.1.2        "nginx -g 'daemon of…"   3 minutes ago       Up 3 minutes (healthy)                                                 harbor-portal
bb0fb84251f1        goharbor/harbor-log:v2.1.2           "/bin/sh -c /usr/loc…"   3 minutes ago       Up 3 minutes (healthy)   127.0.0.1:1514->10514/tcp                     harbor-log
 
第一台機器安裝完畢,可以簡單測試一下各項功能,正常後繼續部署其他伺服器

 

開始部署第二台,相同的配置,改一下hostname即可:
hostname: hub.vfancloud2.com

 

測試

9、在vfancloud1機器push鏡像,在vfancloud2查看是否可以同步並pull

## 在192.168.24.253中push鏡像
## 先在/etc/docker/daemon.json文件添加以下內容
vim /etc/docker/daemon.json
...
{
        "insecure-registries": ["//hub.vfancloud1.com","//hub.vfancloud2.com"]
}
...

## 重新載入docker服務    
systemctl daemon-reload 
systemctl restart docker 

## 登錄harbor
[root@centos7 harbor]# docker login hub.vfancloud1.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

## push鏡像
[root@centos7 alibaba]# docker tag hub.vfancloud.com/test/myapp:v1 hub.vfancloud1.com/library/myapp:v1
[root@centos7 alibaba]# docker push hub.vfancloud1.com/library/myapp:v1
The push refers to repository [hub.vfancloud1.com/library/myapp]
a0d2c4392b06: Pushed 
05a9e65e2d53: Pushed 
68695a6cfd7d: Pushed 
c1dc81a64903: Pushed 
8460a579ab63: Pushed 
d39d92664027: Pushed 
v1: digest: sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e size: 1569
 
push成功,倉庫1中已有此鏡像
查看倉庫2:

注意看域名不同

 
在post2導入倉庫2的鏡像:
[root@kubenode2 harbor]# docker pull hub.vfancloud2.com/library/myapp:v1
v1: Pulling from library/myapp
550fe1bea624: Pull complete 
af3988949040: Pull complete 
d6642feac728: Pull complete 
c20f0a205eaa: Pull complete 
438668b6babd: Pull complete 
bf778e8612d0: Pull complete 
Digest: sha256:9eeca44ba2d410e54fccc54cbe9c021802aa8b9836a0bcf3d3229354e4c8870e
Status: Downloaded newer image for hub.vfancloud2.com/library/myapp:v1
hub.vfancloud2.com/library/myapp:v1

至此Harbor高可用完成!實際使用中將兩台Harbor前邊加一層負載即可!