Harbor1.9+Nginx高可用叢集倉庫搭建筆記

akiya發表於2019-10-04

Harbor簡介

Harbor是一個用於儲存和分發Docker映象的企業級Registry伺服器,通過新增一些企業必需的功能特性,例如安全、標識和管理等,擴充套件了開源Docker Distribution。作為一個企業級私有Registry伺服器,Harbor提供了更好的效能和安全。提升使用者使用Registry構建和執行環境傳輸映象的效率。Harbor支援安裝在多個Registry節點的映象資源複製,映象全部儲存在私有Registry中, 確保資料和智慧財產權在公司內部網路中管控。另外,Harbor也提供了高階的安全特性,諸如使用者管理,訪問控制和活動審計等。

架構說明

本次搭建以NFS作為共享儲存存放Harbor相關data,並分離PostgreSQL與Redis為多個Harbor共同連線使用,使用Nginx做負載均衡。

Harbor1.9+Nginx高可用叢集倉庫搭建筆記
如果最終生產環境叢集中伺服器較多,依賴做完LB的Harbor也無法完全達到需求時,可以使用如下架構,部署下級Harbor節點從主節點同步映象,然後再分發給生產伺服器。

Harbor1.9+Nginx高可用叢集倉庫搭建筆記

環境說明

  • 作業系統:CentOS 7 (Minimal Install)
# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
複製程式碼
  • 演示環境軟體版本
軟體 版本
Docker 18.06.3-ce
docker-compose 1.25.0-rc2
Harbor 1.9.0
Nginx 1.16.1
PostgreSQL 9.6.14
Redis 4.0.10
  • 演示環境網路

這裡主要做Harbor高可用演示,真實生產環境請按需分離NFS與DB單獨部署。

IP 主機名
10.10.1.10 Nginx+NFS+DB
10.10.1.11 Harbor-01
10.10.1.12 Harbor-02

部署

簽發私有證照

生成私鑰

正式生產環境建議使用商業證照!

使用openssl工具生成一個RSA私鑰

# openssl genrsa -des3 -out harbor.key 2048
Generating RSA private key, 2048 bit long modulus
.......................+++
......+++
e is 65537 (0x10001)
Enter pass phrase for harbor.key:                   # 輸入一個至少4位的密碼
Verifying - Enter pass phrase for harbor.key:       # 重複輸入密碼
複製程式碼

刪除harbor.key中的密碼

# openssl rsa -in harbor.key -out harbor.key
Enter pass phrase for harbor.key:                 # 輸入剛才建立時的密碼
writing RSA key
複製程式碼

生成CSR(證照籤名請求)

# openssl req -new -key harbor.key -out harbor.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:cn             # 國家
State or Province Name (full name) []:Sichuan    # 地區 
Locality Name (eg, city) [Default City]:Chengdu  # 城市
Organization Name (eg, company) [Default Company Ltd]:akiya  # 組織
Organizational Unit Name (eg, section) []:akiya  # 組織單位
Common Name (eg, your name or your server's hostname) []:akiya    # 常用名可填自己名字或域名
Email Address []:a@b.com                         # 郵件地址

Please enter the following 'extra' attributes
to be sent with your certificate request      
A challenge password []:       # 可留空
An optional company name []:   # 可留空
複製程式碼

生成自簽名證照

注意:在使用自簽名的臨時證照時,瀏覽器會提示證照的頒發機構是未知的。

# echo subjectAltName = IP:10.10.1.10 > extfile.cnf
# openssl x509 -req -days 365 -in harbor.csr -signkey harbor.key -out harbor.crt -extfile extfile.cnf
Signature ok
subject=/C=cn/ST=Sichuan/L=Chengdu/O=akiya/OU=akiya/CN=akiya/emailAddress=a@b.com
Getting Private key
複製程式碼

存放證照

複製證照到/www/certs待用

# mkdir -p /www/certs && cp harbor.crt harbor.key /www/certs
複製程式碼

Docker

官方一鍵指令碼安裝

# curl -sSL https://get.docker.com/ | sh
複製程式碼

使用阿里雲源安裝

  • 先安裝必要的依賴環境
# yum -y install yum-utils device-mapper-persistent-data lvm2
複製程式碼
  • 新增軟體源資訊
# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
複製程式碼
  • 更新快取
# yum makecache fast
複製程式碼
  • 查詢庫中Docker版本
# yum list docker-ce --showduplicates | sort -r
已載入外掛:fastestmirror
可安裝的軟體包
 * updates: mirrors.aliyun.com
Loading mirror speeds from cached hostfile
 * extras: mirrors.aliyun.com
docker-ce.x86_64            3:19.03.2-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.1-3.el7                     docker-ce-stable
docker-ce.x86_64            3:19.03.0-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.9-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.8-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.7-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.6-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.5-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.4-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.3-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.2-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.1-3.el7                     docker-ce-stable
docker-ce.x86_64            3:18.09.0-3.el7                     docker-ce-stable
docker-ce.x86_64            18.06.3.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.2.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.1.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.06.0.ce-3.el7                    docker-ce-stable
docker-ce.x86_64            18.03.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            18.03.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.12.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.12.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.09.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.09.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.2.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.06.0.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.3.ce-1.el7                    docker-ce-stable
docker-ce.x86_64            17.03.2.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.1.ce-1.el7.centos             docker-ce-stable
docker-ce.x86_64            17.03.0.ce-1.el7.centos             docker-ce-stable
 * base: mirrors.aliyun.com
複製程式碼
  • 安裝Docker或安裝指定版本Docker
# yum -y install docker
複製程式碼
# yum -y install docker-ce-18.06.3.ce-3.el7
複製程式碼
  • 檢視Docker版本
# docker --version
Docker version 18.06.3-ce, build d7080c1
複製程式碼
  • 修改Docker倉庫為國內映象站
# curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io
複製程式碼
  • 啟動Docker服務並新增至開機自啟
# systemctl start docker
# systemctl enable docker
複製程式碼

Compose

compose是Docker提供的一個命令列工具,用來定義和執行由多個容器組成的應用。使用compose,我們可以通過YAML檔案宣告式的定義應用程式的各個服務,並由單個命令完成應用的建立和啟動。

由於國內政策原因,可能在海外網站上下載檔案速度較慢,建議下載本地後上傳至伺服器

下載docker-compose並賦予可執行許可權

# curl -L https://github.com/docker/compose/releases/download/1.25.0-rc2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
複製程式碼

檢視compose本地版本

# docker-compose -v
docker-compose version 1.25.0-rc2, build 661ac20e
複製程式碼

DB

由於Harbor v1.9.0使用的是PostgreSQL,我們也同樣獨立部署一套PostgreSQL與Redis,此次演示使用Docker部署,實際生產環境按需要選擇是否部署至宿主機。

PostgreSQL

通過檢視已安裝的Harbor v1.9.0單機版中執行的harbor-db容器可得知此次執行的PostgreSQL版本為9.6.14

# docker exec -it harbor-db /bin/bash
postgres [ / ]$ psql
psql (9.6.14)
Type "help" for help.

postgres=# select version();
                                    version
-------------------------------------------------------------------------------
 PostgreSQL 9.6.14 on x86_64-pc-linux-gnu, compiled by gcc (GCC) 6.3.0, 64-bit
(1 row)
複製程式碼

Redis

根據官方文件描述,使用Redis需要4.0.10-1.ph2版本。同樣,此次我們為了演示使用也使用docker-compose來部署。

yaml指令碼

那麼我們使用同一版本的PostgreSQL與Redis,編寫docker-compose.yml 內容如下:

# author:akiya
version: "3"

networks:
  harbor:
    driver: bridge

services:
  registry:
    image: postgres:9.6.14
    container_name: harbor-registry
    restart: always
    environment:
      POSTGRES_DB: registry
      POSTGRES_PASSWORD: root123
    volumes:
      - $PWD/postgres/registry:/var/lib/postgresql/data
    networks:
      - harbor
    ports:
      - 20010:5432
  clair:
    image: postgres:9.6.14
    container_name: harbor-clair
    restart: always
    environment:
      POSTGRES_DB: clair
      POSTGRES_PASSWORD: root123
    volumes:
      - $PWD/postgres/clair:/var/lib/postgresql/data
    networks:
      - harbor
    ports:
      - 20011:5432
  notarysigner:
    image: postgres:9.6.14
    container_name: harbor-notarysigner
    restart: always
    environment:
      POSTGRES_DB: notarysigner
      POSTGRES_PASSWORD: root123
    volumes:
      - $PWD/postgres/notarysigner:/var/lib/postgresql/data
    networks:
      - harbor
    ports:
      - 20012:5432
  notaryserver:
    image: postgres:9.6.14
    container_name: harbor-notaryserver
    restart: always
    environment:
      POSTGRES_DB: notaryserver
      POSTGRES_PASSWORD: root123
    volumes:
      - $PWD/postgres/notaryserver:/var/lib/postgresql/data
    networks:
      - harbor
    ports:
      - 20013:5432
  Redis:
    image: redis:4.0.10
    container_name: harbor-redis
    command: redis-server /usr/local/etc/redis/redis.conf
    restart: always
    volumes:
      - $PWD/redis/data:/data
      - $PWD/redis/redis.conf:/usr/local/etc/redis/redis.conf
    networks:
      - harbor
    ports:
      - 20000:6379
複製程式碼

儲存後我們用docker-compose up -d命令啟動相應的容器,並在防火牆中開放對應的埠

# docker-compose up -d
# firewall-cmd --zone=public --permanent --add-port=20000/tcp
# firewall-cmd --zone=public --permanent --add-port=20010/tcp
# firewall-cmd --zone=public --permanent --add-port=20011/tcp
# firewall-cmd --zone=public --permanent --add-port=20012/tcp
# firewall-cmd --zone=public --permanent --add-port=20013/tcp
# firewall-cmd --reload
複製程式碼

NFS

服務端

建立NFS共享檔案路徑

# mkdir -p /data/nfs
複製程式碼

安裝NFS(在安裝完nfs-utils後,rpcbind預設是啟動了的)

# yum -y install nfs-utils rpcbind
複製程式碼

啟動NFS相關服務並設定開機啟動

# systemctl start rpcbind
# systemctl enable rpcbind
# systemctl start nfs-server
# systemctl enable nfs-server
# systemctl start nfs-lock
# systemctl enable nfs-lock
# systemctl start nfs-idmap
# systemctl enable nfs-idmap
複製程式碼

使用如下命令像/etc/exports中新增配置

# echo '/data/nfs  10.0.0.0/8(rw,sync,no_root_squash)' >> /etc/exports
# exportfs -a      # 使exports的修改生效
複製程式碼

檢查NFS共享目錄是否正確

# showmount -e localhost
Export list for localhost:
/data/nfs 10.0.0.0/8
複製程式碼

放行防火牆相應服務

# firewall-cmd --add-service=nfs --permanent --zone=public
# firewall-cmd --add-service=mountd --permanent --zone=public
# firewall-cmd --add-service=rpc-bind --permanent --zone=public
# firewall-cmd --reload
複製程式碼

客戶端

建立NFS掛載檔案路徑

# mkdir /data
複製程式碼

安裝NFS

# yum -y install nfs-utils
複製程式碼

檢查NFS遠端共享目錄是否存在

# showmount -e 10.10.1.10
Export list for 10.10.1.10:
/data/nfs 10.0.0.0/8
複製程式碼

掛載遠端NFS共享檔案路徑

# mount -t nfs 10.10.1.10:/data/nfs /data
複製程式碼

新增到系統開機自動掛載

# echo '10.10.1.10:/data/nfs /data nfs defaults 0 0' >> /etc/fstab
複製程式碼

測試

在客戶端上掛載完NFS後建立一個測試檔案

# touch /data/test
複製程式碼

然後切換到伺服器檢視是否存在

# ls /data/nfs/
test
複製程式碼

Harbor

下載

下載Harbor離線安裝包,離線安裝包檔案較大(約為:590M),建議在本地使用多執行緒工具下載後上傳伺服器使用。

# curl -O https://storage.googleapis.com/harbor-releases/release-1.9.0/harbor-offline-installer-v1.9.0.tgz
複製程式碼

也可以在伺服器上安裝axel多執行緒下載工具加速下載(可以自己找原始碼編譯)

# curl -O http://download-ib01.fedoraproject.org/pub/epel/7/x86_64/Packages/a/axel-2.4-9.el7.x86_64.rpm
# rpm -ivh axel-2.4-9.el7.x86_64.rpm
# axel -n 20 https://storage.googleapis.com/harbor-releases/release-1.9.0/harbor-offline-installer-v1.9.0.tgz
複製程式碼

解壓安裝包

# tar -zxvf harbor-offline-installer-v1.9.0.tgz && cd harbor
複製程式碼

修改配置檔案

修改harbor.yml配置檔案

# vim harbor.yml
複製程式碼

主要配置引數如下,由於我們這裡使用外接PostgreSQL與Redis所以直接註釋掉database相關配置改用external_databaseexternal_redis

# 修改為當前伺服器內網IP地址即可
hostname: reg.mydomain.com
# HTTP相關配置
http:
  port: 80
# HTTPS相關配置,這裡由於我們會在前端加一個Nginx
# 所以我們直接使用HTTP,而在Nginx上做SSL
#https:
#  # HTTPS埠
#  port: 443
#  # TLS證照
#  certificate: /www/certs/harbor.crt
#  # TLS私鑰
#  private_key: /www/certs/harbor.key
# 預設管理員密碼
harbor_admin_password: Harbor12345
# Harbor DB配置,由於使用外部資料庫,所以這裡我們註釋掉
# database:
#   password: root123
#   max_idle_conns: 50
#   max_open_conns: 100
...
# 外部PostgreSQL,由於Harbor使用了4個資料庫,這裡我們也需要對相應資料庫地址進行配置
external_database:
  harbor:
    host: 10.10.1.10
    port: 20010
    db_name: registry
    username: postgres
    password: root123
    ssl_mode: disable
    max_idle_conns: 2
    max_open_conns: 0
  clair:
    host: 10.10.1.10
    port: 20011
    db_name: clair
    username: postgres
    password: root123
    ssl_mode: disable
  notary_signer:
    host: 10.10.1.10
    port: 20012
    db_name: notarysigner
    username: postgres
    password: root123
    ssl_mode: disable
  notary_server:
    host: 10.10.1.10
    port: 20013
    db_name: notaryserver
    username: postgres
    password: root123
    ssl_mode: disable
# 使用外部Redis,取消相應註釋即可
external_redis:
  host: 10.10.1.10
  port: 20000
  password:
  registry_db_index: 1
  jobservice_db_index: 2
  chartmuseum_db_index: 3
...
複製程式碼

生成harbor執行的必要檔案(環境)以及docker-compose.yml檔案;執行後會通過網路獲取Docker Image,建議提前修改好國內映象站加速。

# ./prepare
複製程式碼

安裝Harbor

# ./install.sh
複製程式碼

開放Harbor埠

# firewall-cmd --zone=public --permanent --add-port=80/tcp
# firewall-cmd --reload
複製程式碼

Nginx

安裝

新增Nginx源

# rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
複製程式碼

yum安裝Nginx

# yum -y install nginx
複製程式碼

啟動Nginx

# systemctl start nginx
# systemctl enable nginx
複製程式碼

編寫配置

建立/etc/nginx/conf.d/harbor.conf檔案,並寫入如下內容

upstream harbor {
    ip_hash;
    server 10.10.1.11:80;
    server 10.10.1.12:80;
}
server {
   listen       80;
   # 提供訪問的域名或者IP
   server_name  harbor.yourdomain.com;
   return      308 https://$host$request_uri;
}
server {
    listen  443 ssl;
    server_name harbor.yourdomain.com;
    
    # SSL 證照
    ssl_certificate ./certs/harbor.crt;
    # SSL 私鑰
    ssl_certificate_key ./certs/harbor.key;
    client_max_body_size 0;
    chunked_transfer_encoding on;

    location / {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto https;
        proxy_redirect off;
        proxy_ssl_verify off;
        proxy_ssl_session_reuse on;
        proxy_pass http://harbor;
        proxy_http_version 1.1;
}
    location /v2/ {
        proxy_pass http://harbor/v2/;
        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_set_header X-Forwarded-Proto $scheme;
        proxy_ssl_verify off;
        proxy_ssl_session_reuse on;
        proxy_buffering off;
        proxy_request_buffering off;
    }
}
複製程式碼

啟動Nginx

驗證Nginx配置正確性

# nginx -t
複製程式碼

平滑重啟Nginx

# nginx -s reload
複製程式碼

開放防火牆80/443埠

# firewall-cmd --zone=public --permanent --add-port=80/tcp
# firewall-cmd --zone=public --permanent --add-port=443/tcp
# firewall-cmd --reload
複製程式碼

問題處理

Nginx

問題:使用自簽證照時報錯

emerg] 31815#31815: cannot load certificate "/www/certs/harbor.crt": BIO_new_file() failed (SSL: error:0200100D:system library:fopen:Permission denied:fopen('/www/certs/harbor.crt','r') error:2006D002:BIO routines:BIO_new_file:system lib)
複製程式碼

解決方法:建立/etc/nginx/certs路徑,並複製證照到此路徑

mkdir -p /etc/nginx/certs && cp /www/certs/ ./certs
複製程式碼

修改harbor.conf中證照相關路徑

# 剛才我們自己簽發的證照
ssl_certificate ./certs/harbor.crt;
# 證照對應的私鑰
ssl_certificate_key ./certs/harbor.key;
複製程式碼

相關文章