1.安装部署

使用Docker安装

下载离线安装包 harbor-offline-installer-v1.10.2.tar.gz 解压,编辑 harbor.yml ,注意以下配置:

  • hostname:主机名
  • http.port: http端口
  • https.port: https端口
  • https.certificate: CA签发到服务端的证书
  • https.private_key: 服务端私钥
  • data_volume: 数据目录,映射到主机上

执行prepare,生成配置后,执行docker-compose启动服务!

Kubernetes部署

Helm包安装时以下配置需要注意:

  • expose.type:当前Harbor支持ingress、nodePort、clusterIP、loadBalancer
  • expose.tls.enabled:是否启用HTTPS
  • expose.tls.secret.secretName:自定义域名密文
  • expose.ingress.hosts.core:ingress生成的域名
  • externalURL:该配置决定了Harbor的地址,配置
  • jobservice.jobLogger:日志服务输出配置,集群部署的时候请设置成database
  • persistence.imageChartStorage.disableredirect:使用外部存储时client是否直连

2.生成自签名证书

创建根证书

1
2
3
4
5
openssl genrsa -out ca.key 4096
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=xxx/L=xxx/O=xxx/OU=xxx/CN=yoaz.com" \
-key ca.key \
-out ca.crt

生成服务端证书

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
## 1. 服务端私钥
openssl genrsa -out harbor.yoaz.com.key 4096
## 2. 服务端的签发请求
openssl req -sha512 -new \
-subj "/C=CN/ST=xxx/L=xxx/O=xxx/OU=xxx/CN=harbor.yoaz.com" \
-key harbor.yoaz.com.key \
-out harbor.yoaz.com.csr

## 3. 生成签发请求
cat > v3.ext <<-EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names

[alt_names]
DNS.1=harbor.yoaz.com
DNS.2=harbor.yoaz
DNS.3=yoaz
EOF

## 4. 生成服务端证书
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor.yoaz.com.csr \
-out harbor.yoaz.com.crt

配置Docker客户端证书

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
## 1. 证书转换cert格式(Docker使用这个格式的证书)
openssl x509 -inform PEM -in harbor.yoaz.com.crt -out harbor.yoaz.com.cert

## 2. 配置docker端证书
mkdir -p  /etc/docker/certs.d/harbor.yoaz.com
cp harbor.yoaz.com.cert /etc/docker/certs.d/harbor.yoaz.com
cp harbor.yoaz.com.key /etc/docker/certs.d/harbor.yoaz.com
cp ca.crt /etc/docker/certs.d/harbor.yoaz.com

## 3. 修改/etc/hosts,添加:<ipaddress> harbor harbor.yoaz.com

## 4. 登录验证
docker login harbor.yoaz.com -u admin

可以直接将私有根证书添加到操作系统的信任域,Centos7上可以安装以下方式操作:

1
2
3
4
5
cp ca.crt /etc/pki/ca-trust/source/anchors/ca.crt 
chmod -w /etc/pki/ca-trust/source/anchors/ca.crt
update-ca-trust
# 重启docker使证书生效
systemctl restart docker 

3.生成SAN格式证书

当应用使用 Golang 1.15 以上版本编译时,访问使用openssl证书的Harbor服务,可能出现以下异常:

“legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0”

原因是 go 1.15 版本开始废弃 CommonName,推荐使用 SAN 证书。

按照以下步骤生成SAN证书:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 生成根证书
openssl genrsa -out rootCA.key 4096
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 36500 -out rootCA.crt -subj "/C=CN/ST=xxx/L=xxx/O=xxx/OU=HCI/CN=hci.io"

# 生成服务端证书
touch /etc/pki/CA/index.txt
echo 01 > /etc/pki/CA/serial 
openssl genrsa -out server.key 2048
openssl req -new \
    -sha256 \
    -key server.key \
    -subj "/C=CN/ST=xxx/L=xxx/O=xxx/OU=HCI/CN=registry.hci.io" \
    -reqexts SAN \
    -config <(cat /etc/pki/tls/openssl.cnf \
        <(printf "[SAN]\nsubjectAltName=DNS:*.hci.io,DNS:*.hci.io")) \
    -out server.csr
openssl ca -in server.csr \
    -md sha256 \
    -keyfile rootCA.key \
    -days 36500 \
    -cert rootCA.crt \
    -extensions SAN \
    -config <(cat /etc/pki/tls/openssl.cnf \
        <(printf "[SAN]\nsubjectAltName=DNS:*.hci.io,DNS:*.hci.io")) \
    -out server.crt

4.Harbor v1.5.0升级

Harbor v1.5.0通过Docker部署,并且使用S3作为镜像数据存储。需要将Harbor升级到v1.9.4并移动到Kubernetes部署,数据库使用外置的PG,镜像数据仍然存储在原有S3中。

v1.5.0 版本使用MYSQL作为默认数据库,升级时需要先升级到1.6.0版本。升级到1.6.0后,需要按照v1.6.3、v1.7.6、v1.9.4的顺序依次升级Harbor。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Harbor 服务停机
docker-compose down

# 备份数据(/data/harbor数据目录)
cp /data/harbor /data/harbor_backup

# 作为环境变量供调用
harbor_db_path=/data/harbor/database
harbor_cfg=/root/harbor/harbor_150.cfg # 1.50 版本的启动文件

# 升级数据库文件(# PS:如果使用了clair和notary,这两个东西要独立升级)
docker run -it --rm -e DB_USR=root -e DB_PWD=root123 -v ${harbor_db_path}:/var/lib/mysql -v ${harbor_cfg}:/harbor-migration/harbor-cfg/harbor.cfg goharbor/harbor-migrator:v1.6.0 up

harbor-migrator容器退出后,/data/harbor/database 目录下的元数据已经转化为PG格式,可以在这之上直接启动PG服务。

此时可以通过docker-compose启动 v1.6.3、v1.7.6、v1.9.4 版本的harbor (数据目录为/data/harbor/database),每次启动高版本Harbor之后都会自动重写数据库的元数据。

将升级完成的元数据导出为sql文件,并导入到生产实际使用的PG中:

1
2
3
# 导出PGSQL中Registry数据库的数据
docker exec  harbor-db /bin/sh -c  "pg_dump -U postgres --no-owner --no-privileges --schema-only  registry" > registry-schema.sql
docker exec  harbor-db /bin/sh -c  "pg_dump -U postgres --inserts --data-only  registry" > registry-data.sql

为了加快数据库导入导出数据,建议清空 registry 库的 img_scan_job 表和 img_scan_overview 表。

导入数据到DB:

1
2
PGPASSWORD={PASSWORD} psql -h {HOST_IP} -p 5431  -d registry -U {USERNAME} -f registry-schema.sql
PGPASSWORD={PASSWORD} psql -h {HOST_IP} -p 5431  -d registry -U {USERNAME} -f registry-data.sql

FAQ

  • 1.7.6 - > 1.9.4 -> 2.0.2 每个版本升级时,harbor-core 都需要花费大量时间重启。如果部署在Kubernetes中,探针机制会主动杀死Harbor Core 导致升级失败。因此需要手工编辑Ready探针的时间(建议直接编辑存活探针到3个小时以上,或者在values.xml中加入配置core.livenessProbe.initialDelaySeconds).
  • 测试过程中发现1.9.x 版本之间Login API之间有一些差异,1.9.0版本没有进行csrf校验,而1.9.2、1.9.4版本进行了校验。但是1.9.x 版本校验方式又和2.0.x不相同
  • 1.9.x版本的csrf校验可以通过配置文件关闭(1.9.x使用的是 BEEG框架,参考),相关配置项为EnableXSRF=false
  • 2.0.x没有找到关闭XSRF校验的配置

5.PostgreSQL HA

Repmgr 方案

Repmgr 基于 PostgreSQL 原生自带的 Streaming replication 能力进行HA,并在此之上提供了一些额外能力。

1
2
helm repo add bitnami https://charts.bitnami.com/bitnami
helm pull bitnami/postgresql-ha --version=7.8.7

获取环境信息

1
2
3
4
5
6
7
8
export REPMGR_PASSWORD=$(kubectl get secret --namespace harbor postgresql-ha-postgresql -o jsonpath="{.data.repmgr-password}" | base64 --decode)
export POSTGRES_PASSWORD=$(kubectl get secret --namespace harbor postgresql-ha-postgresql -o jsonpath="{.data.postgresql-password}" | base64 --decode)
kubectl run postgresql-ha-client --rm --tty -i --restart='Never' \
--namespace harbor \
--image registry.hci.io/bitnami/postgresql-repmgr:11.13.0-debian-10-r0 \
--env="PGPASSWORD=$POSTGRES_PASSWORD"  \
--command \
-- psql -h postgresql-ha-pgpool -p 5432 -U postgres -d postgres

参考:

PGO方案

pgo 是crunchydata公司提供的一款 Postgres Operator 工具,通过该工具用户可以在k8s上部署一个完整的,具备高可用性、灾难恢复和监控、以及TLS通信能力的生产级Postgres集群。

参考资料:

其他方案

5.配置多个域名

对于同一个Harbor服务配置多个域名,其中内外网可以通过不同的域名访问到Harbor,以提高内网用户访问Harbor速度。

Harbor核心服务包括:core、jobservice、registry 这三个服务可以组成集群,并且每个core实例可以填写不同的域名以及协议。 可以通过部署不同helm实例,并共享外部PG、Redis的方式实现网络分离、多域名绑定等功能,部署时helm配置需要注意以下几点:

  • jobservice.jobLogger:日志服务输出配置,集群部署的时候请设置成database
  • 不同helm实例中,组件 secret 要配置成一致,否则集群内部通信会出现问题(jobservice、core、registry三个组件)

PS: 上述方案实际验证中可以工作,但是并没经过生产考验。建议还是通过不同Harbor服务直接主备镜像实现这一点

参考