搭建 Harbor 1.10.6 高可用集群

推荐阅读

Helm3(K8S 资源对象管理工具)视频教程:https://edu.csdn.net/course/detail/32506
Helm3(K8S 资源对象管理工具)博客专栏:https://blog.csdn.net/xzk9381/category_10895812.html

本文原文链接:https://blog.csdn.net/xzk9381/article/details/110819978,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

一、集群模式说明

Harbor 支持如下几种集群模式:

  • 主从同步
  • 双主复制
  • 多 Harbor 实例共享后端存储

1. 主从同步

其中主从同步方式是 Harbor 官方提供的模式,只要向其中的主 Harbor 中 push 镜像,即可将镜像自动复制到多个从节点中。这种方式可以应用于镜像规模庞大,服务器节点较多,分布地域广泛的问题。对于主 Harbor 仓库单节点故障的问题,可以通过结合多 Harbor 实例共享后端存储的方式来解决。

2. 双主复制

双主复制就是在主从同步的基础上,实现两个 Harbor 节点上的双向同步来保证数据的一致性。通过负载均衡设备将请求分流到两个 Harbor 节点中,只要有一个 Harbor 中新增了镜像,就会自动同步到另一个 Harbor 中。

但是这样的方式存在一个问题,如果其中一个 Harbor 挂掉了,另一个 Harbor 中又有新的数据变更。那么在恢复了故障的节点后,新增的数据也不会同步过去。需要重新开启复制策略才可以。所以在生产环境中不建议使用这种方式。

3. 多 Harbor 实例共享后端存储

共享后端存储就是让多个 Harbor 使用一个存储,并且配置同一个 Redis 集群和数据库集群,来保证每个节点访问的数据都是一致的。然后通过负载均衡将请求分流到不同的 Harbor 实例中。

对于 Session 在不同实例中共享的问题,这个可以通过配置外部 Redis 集群来处理,新版本的 Harbor 已经将 Session 存储在 Redis 中了。

在本文中,主要介绍的就是这种集群方式,但是由于 Harbor 内部已经启动了一个 Nginx 服务,所以此次部署没有在 Harbor 多实例前面搭建 Nginx 负载均衡服务,而是通过配置 VIP 和 Keepalived 来保证集群的高可用性。

二、安装前注意事项

  • Harbor 服务器:10.211.55.11、10.211.55.12

1. 数据库

搭建集群过程中需要使用到 Redis 集群和 数据库集群,这两个集群的搭建方式可以参考其他资料:使用源码安装 PostgreSQL 12.5 主从集群,本文中不进行描述。

需要注意的是,在 Harbor 1.6 版本之后,数据库仅支持使用 PostgreSQL。所以本文中连接外部数据库使用的是 PostgreSQL 12.5 版本。

另外,在 Harbor 2.x 版本之前,配置 Redis 集群仅支持主从模式,2.x 版本之后才支持配置 Sentinel 集群,但是不确定是否支持使用 Redis 官方 Cluster 模式,因为在 Harbor 源码包中给出的 harbor.yml 文件示例中,关于外部 Redis 配置的部分如下:

# Uncomment external_redis if using external Redis server
# 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: redis:6379
# password:
# # 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

所以在此次搭建过程中,Redis 和 PostgreSQL 使用的都是主从模式。注意在搭建之前,先关闭服务器防火墙和 SELinux。

2. 共享存储

本次搭建的环境中,共享存储使用的是 cephfs。具体搭建过程可参考其他资料 CentOS 7 搭建 Ceph 集群(nautilus 版本)

将 cephfs 挂载到两台机器的 /opt/harbor_data 目录下,该目录用于存储 Harbor 数据。

三、安装 Docker 环境

Harbor 是基于 docker-compose 编排启动的容器环境,所以首先在两台服务器中安装 Docker。这里直接下载 Docker 最新版本的二进制包:

wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.13.tgz -O /root

将二进制包解压后得到一个 docker 目录,将该目录下的所有文件拷贝到 /usr/bin 目录下:

mv /root/docker/* /usr/bin

创建 /usr/lib/systemd/system/docker.service 文件,内容如下:

[Unit]
Description=Docker Application Container Engine
Documentation=https://docs.docker.com
After=network-online.target firewalld.service containerd.service
Wants=network-online.target

[Service]
Type=notify
ExecStart=/usr/bin/dockerd $DOCKER_NETWORK_OPTIONS
ExecReload=/bin/kill -s HUP $MAINPID
TimeoutSec=0
RestartSec=2
Restart=always
StartLimitBurst=3
StartLimitInterval=60s
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
Delegate=yes
KillMode=process

[Install]
WantedBy=multi-user.target

保存退出后执行如下命令使 service 文件生效,并配置 docker 服务开机启动:

systemctl daemon-reload && systemctl enable docker.service

四、安装 docker-compose

在两台服务器中,使用如下命令安装 docker-compose 环境:

curl -L "https://github.com/docker/compose/releases/download/1.27.4/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

五、制作 HTTPS 证书

由于 Harbor 推荐使用 HTTPS 的方式去访问镜像仓库,所以首先制作 HTTPS 证书,步骤如下:

1. 生成 CA 证书

首先在 /opt/harbor_data 目录下创建一个 ssl 目录:

mkdir -p /opt/harbor_data/ssl

进入到该目录下,使用 openssl 命令生成一个 CA 机构证书私钥:

openssl genrsa -out ca.key 4096

根据这个私钥生成 CA 机构证书:

openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.mrd.com" \
-key ca.key \
-out ca.crt

其中 -days 3650 代表证书有效期为 10 年,harbor.mrd.com 是镜像仓库访问的域名,可以根据实际需求进行更改。如果使用 IP 地址访问,需要将域名替换成 IP 地址。

2. 生成服务器证书

接下来生成服务器证书,通常包含一个 .crt 文件和 .key 文件。首先生成私钥文件,最好以域名进行命名:

openssl genrsa -out harbor.mrd.com.key 4096

根据私钥文件生成证书签名请求文件( CSR 文件 ):

openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=example/OU=Personal/CN=harbor.mrd.com" \
-key harbor.mrd.com.key \
-out harbor.mrd.com.csr

再生成一个 x509 v3 扩展文件。无论是使用 FQDN还 是 IP 地址连接到 Harbor 主机,都必须创建这个文件,以便可以为 Harbor 主机生成符合主题备用名称(SAN)和 x509 v3 的证书扩展要求的证书文件。将其中的 DNS 条目修改为实际的 Harbor 访问域名:

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.mrd.com
DNS.2=harbor.mrd.com
DNS.3=harbor.mrd.com
EOF

如果是使用 IP 地址访问,需要将 subjectAltName = @alt_names 中的 @alt_names 修改为 IP 地址。

使用这个 v3.ext 文件生成服务器证书:

openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor.mrd.com.csr \
-out harbor.mrd.com.crt

这样证书制作就已经完成,在 ssl 目录下会有如下文件:

[root@localhost ssl]# ll
总用量 28
-rw-r--r-- 1 root root 2033 11月 30 11:20 ca.crt
-rw-r--r-- 1 root root 3243 11月 30 11:20 ca.key
-rw-r--r-- 1 root root   17 11月 30 11:31 ca.srl
-rw-r--r-- 1 root root 2118 11月 30 11:31 harbor.mrd.com.crt
-rw-r--r-- 1 root root 1708 11月 30 11:25 harbor.mrd.com.csr
-rw-r--r-- 1 root root 3243 11月 30 11:25 harbor.mrd.com.key
-rw-r--r-- 1 root root  275 11月 30 11:31 v3.ext

3. 将证书提供给 Harbor、Docker 和 操作系统

证书生成后,为了能够让各个服务识别到证书,需要将证书文件拷贝到指定目录下。

3.1 配置 Docker 服务识别证书

为 Docker 配置证书路径,这样在调用 docker login 命令时,就可以建立安全的连接,避免出现由于证书问题而导致的报错。

首先创建如下目录:

mkdir -p /etc/docker/certs.d/harbor.mrd.com

如果将 NGINX 默认的 443 端口修改为其他端口号,则需要创建 /etc/docker/certs.d/yourdomain.com:port 或 /etc/docker/certs.d/harbor_IP:port 目录

由于 Docker 的守护进程会将 .crt 文件解释为 CA 证书,将 .cert 文件解释为客户端证书。所以需要将刚才生成的 harbor.mrd.com.crt 证书文件转换为 harbor.mrd.com.cert 文件。

openssl x509 -inform PEM -in harbor.mrd.com.crt -out harbor.mrd.com.cert

将 /opt/harbor_data/ssl 目录下的 CA 证书和服务器证书、私钥文件拷贝到 /etc/docker/certs.d/harbor.mrd.com 目录下:

cp -pr ca.crt harbor.mrd.com.{ cert,key} /etc/docker/certs.d/harbor.mrd.com

重新启动 Docker 服务即可:

systemctl restart docker.service

本文原文链接:https://blog.csdn.net/xzk9381/article/details/110819978,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

3.2 配置操作系统识别证书

将证书文件拷贝到系统证书路径下:

cp -pr harbor.mrd.com.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust
3.3 配置 Harbor 识别证书

刚才配置的 /opt/harbor_data/ssl 目录就是两个 Harbor 节点的共享存储目录,所以配置 Harbor 时只需要指定这个目录中的文件即可。

六、创建 Harbor 需要使用的数据库和用户

1. 创建库和用户

由于使用的是外部 PostgreSQL 数据库,所以需要提前将 Harbor 使用的库名和用户创建好。在 PostgreSQL 数据库服务器中使用 postgres 用户执行如下命令进行创建:

[postgres@localhost ~]$ psql
psql (12.5)
Type "help" for help.

postgres=# CREATE USER harbor with password 'harbor_admin';
CREATE ROLE

postgres=# CREATE DATABASE harbor;
CREATE DATABASE

postgres=# CREATE DATABASE harbor_clair;
CREATE DATABASE

postgres=# CREATE DATABASE harbor_notary_server;
CREATE DATABASE

postgres=# CREATE DATABASE harbor_notary_signer;
CREATE DATABASE

postgres=# GRANT ALL PRIVILEGES ON DATABASE harbor to harbor;
GRANT

postgres=# GRANT ALL PRIVILEGES ON DATABASE harbor_clair to harbor;
GRANT

postgres=# GRANT ALL PRIVILEGES ON DATABASE harbor_notary_server to harbor;
GRANT

postgres=# GRANT ALL PRIVILEGES ON DATABASE harbor_notary_signer to harbor;
GRANT

2. 配置远程访问权限

接下来为创建的 harbor 用户配置远程访问的权限,修改 PostgreSQL 数据目录下的 pg_hba.conf 文件,添加如下一行内容:

host    all             harbor          0.0.0.0/0               trust

这个代表允许任何机器使用 harbor 用户远程连接 PostgreSQL 数据库。配置完成后重启数据库服务:

/etc/init.d/postgresql restart

3. 配置时区

需要特别注意的一点,使用外部 PostgreSQL 数据库,必须要将数据库配置文件 postgresql.conf 中的 timezone 配置项设置为 UTC,否则 Harbor UI 界面中显示的时间戳显示的时间会与实际的时间相差 8 个或 13 个小时。这个问题应该是由于 Harbor 的内部代码逻辑导致的,现在还不确定,后续确认后再补充:

timezone = 'UTC'

修改完成后重启数据库。

七、安装 Harbor

在 Harbor 官网中下载 Harbor 1.10.6 版本离线安装包。

下载地址:https://github.com/goharbor/harbor/releases/download/v1.10.6/harbor-offline-installer-v1.10.6.tgz

在两台机器中执行下面的步骤进行安装:

首先将离线包解压至 /opt 目录下,进入解压后的目录,编辑 harbor.yml 文件,修改 Harbor 的 hostname 为 harbor.mrd.com ,访问的域名一定要和证书中设置的域名一致:

hostname: harbor.mrd.com

配置 HTTPS 证书路径:

https:
  port: 443
  certificate: /opt/harbor_data/ssl/harbor.mrd.com.crt
  private_key: /opt/harbor_data/ssl/harbor.mrd.com.key

设置 Harbor 管理员用户的密码:

harbor_admin_password: Harbor_admin_for_ops

将 Harbor 默认配置的数据库访问信息注释,这部分内容是用于 Harbor 访问内部数据库的设置,注释后 Harbor 将不会单独启动数据库容器:

#database:.
  #password: root123
  #max_idle_conns: 50
  #max_open_conns: 100

修改 Harbor 的数据存储路径,将其设置为两个 Harbor 使用的共享存储路径:

data_volume: /opt/harbor_data

设置 Harbor 日志的存储路径,可以将其改为共享存储目录下,为了避免两个节点的日志打到同一个日志文件中,可以为每个节点单独设置一个目录,例如 /opt/harbor_data/logs/harbor_node1 和 /opt/harbor_data/logs/harbor_node2,然后修改如下配置项:

log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /opt/harbor_data/logs/harbor_node1

添加外部 PostgreSQL 数据库配置:

external_database:
   harbor:
     host: pg.mrd.com
     port: 5432
     db_name: harbor
     username: harbor
     password: harbor_admin
     ssl_mode: disable
     max_idle_conns: 50
     max_open_conns: 200
   clair:
     host: pg.mrd.com
     port: 5432
     db_name: harbor_clair
     username: harbor
     password: harbor_admin
     ssl_mode: disable
   notary_signer:
     host: pg.mrd.com
     port: 5432
     db_name: harbor_notary_signer
     username: harbor
     password: harbor_admin
     ssl_mode: disable
   notary_server:
     host: pg.mrd.com
     port: 5432
     db_name: harbor_notary_server
     username: harbor
     password: harbor_admin
     ssl_mode: disable

添加外部 Redis 数据库配置:

external_redis:
   host: redis.mrd.com
   port: 6379
   password: redispass_for_harbor
   # 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

修改完成后保存退出,执行 ./prepare 脚本初始化 Harbor 配置文件:

[root@localhost harbor]# ./prepare
Generated configuration file: /config/log/logrotate.conf
Generated configuration file: /config/log/rsyslog_docker.conf
Generated configuration file: /config/nginx/nginx.conf
Generated configuration file: /config/core/env
Generated configuration file: /config/core/app.conf
Generated configuration file: /config/registry/config.yml
Generated configuration file: /config/registryctl/env
Generated configuration file: /config/db/env
Generated configuration file: /config/jobservice/env
Generated configuration file: /config/jobservice/config.yml
Generated and saved secret to file: /secret/keys/secretkey
Generated certificate, key file: /secret/core/private_key.pem, cert file: /secret/registry/root.crt
Generated configuration file: /compose_location/docker-compose.yml
Clean up the input dir

初始化完成后,执行 ./install.sh 脚本开始安装 Harbor,安装完成后可以使用如下命令查看服务状态:

[root@localhost harbor]# docker-compose ps
      Name                     Command                  State                          Ports
---------------------------------------------------------------------------------------------------------------
harbor-core         /harbor/harbor_core              Up (healthy)
harbor-jobservice   /harbor/harbor_jobservice  ...   Up (healthy)
harbor-log          /bin/sh -c /usr/local/bin/ ...   Up (healthy)   127.0.0.1:1514->10514/tcp
harbor-portal       nginx -g daemon off;             Up (healthy)   8080/tcp
nginx               nginx -g daemon off;             Up (healthy)   0.0.0.0:80->8080/tcp, 0.0.0.0:443->8443/tcp
registry            /home/harbor/entrypoint.sh       Up (healthy)   5000/tcp
registryctl         /home/harbor/start.sh            Up (healthy)

八、配置 KeepAlived

在两台机器中安装 Harbor 后,继续配置 Keepalived ,将域名 harbor.mrd.com 解析到 VIP 上,这样就可以保证 Harbor 集群的高可用。Keepalived 的搭建过程这里不做描述,可以参考其他资料。关于 Keepalived 中的服务健康检查脚本,其实可以参考 Harbor 容器中设置的健康检查策略,例如查看 harbor-core 镜像中设置的健康检查策略,可以使用如下命令:

[root@localhost ~]# docker images | grep harbor-core | awk '{print $3}' | xargs docker inspect | grep -A5 "Healthcheck"
            "Healthcheck": { 
                "Test": [
                    "CMD-SHELL",
                    "curl --fail -s http://127.0.0.1:8080/api/ping || exit 1"
                ]
            },

所以在 Keepalived 中设置服务健康检查脚本时,可以使用如下脚本内容:

#!/bin/bash

curl --fail -s http://127.0.0.1:80
if [ $? -ne 0 ];then
	docker-compose -f /opt/harbor_compose/docker-compose.yml down -v
	docker-compose -f /opt/harbor_compose/docker-compose.yml up -d
	sleep 15

	curl --fail -s http://127.0.0.1:80/api/ping || systemctl stop keepalived.service;ps aux | grep "/usr/sbin/keepalived" | grep -v grep | awk '{print $2}' | xargs kill -9
fi

本文原文链接:https://blog.csdn.net/xzk9381/article/details/110819978,转载请注明出处。如有发现文章中的任何问题,欢迎评论区留言。

    原文作者:店伙计
    原文地址: https://blog.csdn.net/xzk9381/article/details/110819978
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞