实验环境:
业务 | ip | 系统 |
harbor1 | 192.168.11.11 | kylin-sp1-0518-x86 |
harbor2 | 192.168.11.12 | kylin-sp1-0518-x86 |
nginx、keepalived | 192.168.11.21 | kylin-sp2-0524-x86 |
nginx、keepalived | 192.168.11.22 | kylin-sp2-0524-x86 |
Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry服务器,由 vmware 开源,其通过添加一些企业必需的功能特性,例如安全、标识和管理等,扩展了开源 Docker Distribution。作为一个企业级私有 Registry 服务器,Harbor 提供了更好的性能和安全。提升用户使用 Registry 构建和运行环境传输镜像的效率。Harbor 支持安装在多个 Registry 节点的镜像资源复制,镜像全部保存在私有 Registry 中, 确保数据和知识产权在公司内部网络中管控,另外,Harbor 也提供了高级的安全特性,诸如用户管理,访问控制和活动审计等。
vmware 官方开源服务列表地址:https://github.com/vmware/ (现在已经捐献给了CNCF)
云原生基金会:https://www.cncf.io/
harbor 官方 github 地址:https://github.com/goharbor/harbor
harbor 官方网址:https://goharbor.io/

基于角色的访问控制:用户与 Docker 镜像仓库通过“项目”进行组织管理, 一个用户可以对多个镜像仓库在同一命名空间(project)里有不同的权限。
镜像复制:镜像可以在多个 Registry 实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景。
图形化用户界面:用户可以通过浏览器来浏览,检索当前Docker 镜像仓库,管理项目和命名空间。
AD/LDAP 支持:Harbor 可以集成企业内部已有的AD/LDAP,用于鉴权认证管理。
审计管理:所有针对镜像仓库的操作都可以被记录追溯,用于审计管理。
国际化:已拥有英文、中文、德文、日文和俄文的本地化版本。更多的语言将会添加进来。
RESTful API :提供给管理员对于 Harbor 更多的操控, 使得与其它管理软件集成变得更容易。
部署简单:提供在线和离线两种安装工具, 也可以安装到vSphere 平台(OVA 方式)虚拟设备。
nginx:harbor 的一个反向代理组件,代理 registry、ui、token 等服务。这个代理会转发 harbor web 和docker client 的各种请求到后端服务上。
harbor-adminserver:harbor 系统管理接口,可以修改系统配置以及获取系统信息。
harbor-db:存储项目的元数据、用户、规则、复制策略等信息。
harbor-jobservice:harbor 里面主要是为了镜像仓库之间同步使用的。
harbor-log:收集其他 harbor 的日志信息。
harbor-ui:一个用户界面模块,用来管理 registry。
registry:存储 docker images 的服务,并且提供pull/push 服务。
redis:存储缓存信息webhook:当 registry 中的image 状态发生变化的时候去记录更新日志、复制等操作。
token service:在 docker client 进行 pull/push的时候负责 token 的发放。
4.1 安装 Harbor
下载地址:https://github.com/goharbor/harbor/releases
安装文档:https://goharbor.io/docs/2.3.0/
4.1.1 安装 docker
本次使用当前 harbor 稳定版本 2.3.5 离线安装包 ,具体名称为 harbor-offline-installer-v2.3.5.tgz
在两台主机上设置主机名,域名解析
[root@localhost ~]# hostnamectl set-hostname harbor1.kylin.com
[root@harbor1 ~]# cat <<EOF>> /etc/hosts
192.168.11.11 harbor1.kylin.com harbor1
192.168.11.12 harbor2.kylin.com harbor2
192.168.11.100 img.kylin.com
EOF
[root@harbor1 ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://yydlt76u.mirror.aliyuncs.com"],
"insecure-registries": [
"http://img.kylin.com",
"http://harbor1.kylin.com",
"http://harbor2.kylin.com"
]
}
[root@harbor1 ~]# systemctl daemon-reload
[root@harbor1 ~]# systemctl restart docker.service
[root@harbor1 ~]# docker info
...
...
Insecure Registries:
harbor1.kylin.com
harbor2.kylin.com
img.kylin.com
127.0.0.0/8
Registry Mirrors:
https://yydlt76u.mirror.aliyuncs.com/
Live Restore Enabled: true
4.1.2 下载 Harbor 安装包
链接:https://pan.baidu.com/s/1VjLbTRVadJBZeXGBo0cVDw
提取码:1111
[root@harbor1 ~]# ls harbor-offline-installer-v2.3.5.tgz
harbor-offline-installer-v2.3.5.tgz
4.2 配置 Harbor
4.2.1 解压并编辑 harbor.yml 配置文件
之前的版本配置文件名称为 harbor.cfg
[root@harbor1 ~]# tar xf harbor-offline-installer-v2.3.5.tgz -C /usr/local/
[root@harbor1 ~]# cd /usr/local/harbor/
[root@harbor1 harbor]# ls
common.sh harbor.v2.3.5.tar.gz harbor.yml.tmpl install.sh LICENSE prepare
[root@harbor1 harbor]# cp harbor.yml.tmpl harbor.yml
[root@harbor1 harbor]# vim harbor.yml
修改以下5行
hostname: harbor1.kylin.com
#开启https需要生成证书 ,但是自己生成的证书不可信,还是需要加入不安全的惊醒仓库,所以此处建议关闭
#https:
# port: 443
#certificate: /your/certificate/path 公钥证书
#private_key: /your/private/key/path 私钥证书
[root@harbor1 harbor]# grep -vEn "#|^$" harbor.yml
5:hostname: harbor1.kylin.com
8:http:
10: port: 80
34:harbor_admin_password: Harbor12345
37:database:
39: password: root123
41: max_idle_conns: 100
44: max_open_conns: 900
47:data_volume: /data
71:trivy:
73: ignore_unfixed: false
79: skip_update: false
82: insecure: false
95:jobservice:
97: max_job_workers: 10
99:notification:
101: webhook_job_max_retry: 10
103:chart:
105: absolute_url: disabled
108:log:
110: level: info
112: local:
114: rotate_count: 50
118: rotate_size: 200M
120: location: /var/log/harbor
132:_version: 2.3.0
189:proxy:
190: http_proxy:
191: https_proxy:
192: no_proxy:
193: components:
194: - core
195: - jobservice
196: - trivy
4.3 启动 Harbor
4.3.1 安装 docker-compose
启动之前先确保,本机已经安装 docker-compose 命令,如未安装会报错,请先安装。
[root@harbor1 harbor]# ls
common.sh harbor.v2.3.5.tar.gz harbor.yml harbor.yml.tmpl install.sh LICENSE prepare
[root@harbor1 harbor]# ./install.sh
[Step 0]: checking if docker is installed ...
Note: docker version: 20.10.22
[Step 1]: checking docker-compose is installed ...
✖ Need to install docker-compose(1.18.0+) by yourself first and run this script again.
docker-compose下载链接
链接:https://pan.baidu.com/s/1yh_CSiO6wXouqbpp4N5pkg
提取码:1111
[root@harbor1 ~]# mv docker-compose-Linux-x86_64 /usr/local/bin/docker-compose
[root@harbor1 ~]#
[root@harbor1 ~]# docker-compose
[root@harbor1 ~]# docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.7.10
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
如果联网状态下直接进行安装
[root@localhost ~]# yum -y install docker-compose.noarch
[root@localhost ~]# docker-compose version
docker-compose version 1.22.0, build f46880f
docker-py version: 4.0.2
CPython version: 3.7.9
OpenSSL version: OpenSSL 1.1.1f 31 Mar 2020
4.3.2 安装
[root@localhost harbor]# pwd
/usr/local/harbor
[root@localhost harbor]# ls
common.sh harbor.v2.3.5.tar.gz harbor.yml harbor.yml.tmpl install.sh LICENSE prepare
[root@localhost harbor]# ./install.sh
[root@localhost harbor]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
goharbor/harbor-exporter v2.3.5 1730c6f650e2 12 months ago 81.9MB
goharbor/chartmuseum-photon v2.3.5 47004f032938 12 months ago 179MB
goharbor/redis-photon v2.3.5 3d0cedc89a0d 12 months ago 156MB
goharbor/trivy-adapter-photon v2.3.5 5c0212e98070 12 months ago 133MB
goharbor/notary-server-photon v2.3.5 f20a76c65359 12 months ago 111MB
goharbor/notary-signer-photon v2.3.5 b9fa38eef4d7 12 months ago 108MB
goharbor/harbor-registryctl v2.3.5 7a52567a76ca 12 months ago 133MB
goharbor/registry-photon v2.3.5 cf22d3e386b8 12 months ago 82.6MB
goharbor/nginx-photon v2.3.5 5e3b6d9ce11a 12 months ago 45.7MB
goharbor/harbor-log v2.3.5 a03e4bc963d6 12 months ago 160MB
goharbor/harbor-jobservice v2.3.5 2ac32df5a2e0 12 months ago 211MB
goharbor/harbor-core v2.3.5 23baee01156f 12 months ago 193MB
goharbor/harbor-portal v2.3.5 bb545cdedf5a 12 months ago 58.9MB
goharbor/harbor-db v2.3.5 9826c57a5749 12 months ago 221MB
goharbor/prepare v2.3.5 a1ceaabe47b2 12 months ago 255MB
[root@harbor1 harbor]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
77f43df29d33 goharbor/harbor-jobservice:v2.3.5 "/harbor/entrypoint.…" About a minute ago Up About a minute (healthy) harbor-jobservice
351b0196198a goharbor/nginx-photon:v2.3.5 "nginx -g 'daemon of…" About a minute ago Up About a minute (healthy) 0.0.0.0:80->8080/tcp nginx
1cf642be8bda goharbor/harbor-core:v2.3.5 "/harbor/entrypoint.…" About a minute ago Up About a minute (healthy) harbor-core
7fcca6701a7d goharbor/redis-photon:v2.3.5 "redis-server /etc/r…" About a minute ago Up About a minute (healthy) redis
8527925dd844 goharbor/harbor-portal:v2.3.5 "nginx -g 'daemon of…" About a minute ago Up About a minute (healthy) harbor-portal
b3d56391077e goharbor/registry-photon:v2.3.5 "/home/harbor/entryp…" About a minute ago Up About a minute (healthy) registry
35c744075364 goharbor/harbor-registryctl:v2.3.5 "/home/harbor/start.…" About a minute ago Up About a minute (healthy) registryctl
b114a64763e2 goharbor/harbor-db:v2.3.5 "/docker-entrypoint.…" About a minute ago Up About a minute (healthy) harbor-db
a280a5d3962a goharbor/harbor-log:v2.3.5 "/bin/sh -c /usr/loc…" About a minute ago Up About a minute (healthy) 127.0.0.1:1514->10514/tcp harbor-log
[root@harbor1 harbor]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 512 127.0.0.1:1514 0.0.0.0:*
LISTEN 0 128 0.0.0.0:111 0.0.0.0:*
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
LISTEN 0 128 *:9090 *:*
LISTEN 0 128 [::]:111 [::]:*
LISTEN 0 512 *:80 *:*
LISTEN 0 128 [::]:22 [::]:*
[root@harbor1 harbor]# docker-compose ps
Name Command State Ports
---------------------------------------------------------------------------------------------
harbor-core /harbor/entrypoint.sh Up (healthy)
harbor-db /docker-entrypoint.sh 96 13 Up (healthy)
harbor-jobservice /harbor/entrypoint.sh 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)
nginx nginx -g daemon off; Up (healthy) 0.0.0.0:80->8080/tcp
redis redis-server /etc/redis.conf Up (healthy)
registry /home/harbor/entrypoint.sh Up (healthy)
registryctl /home/harbor/start.sh Up (healthy)
[root@harbor1 harbor]#
[root@harbor1 harbor]# ls -lh /data/
总用量 0
drwxr-xr-x 2 10000 10000 6 1月 5 14:20 ca_download
drwx------ 3 unbound input 18 1月 5 14:20 database
drwxr-xr-x 2 10000 10000 6 1月 5 14:20 job_logs
drwxr-xr-x 2 unbound input 6 1月 5 14:20 redis
drwxr-xr-x 2 10000 10000 6 1月 5 14:20 registry
drwxr-xr-x 5 root root 46 1月 5 14:20 secret
data目录包含的文件夹和相应的作用
模块 | 说明 |
ca_download | 存放用户访问Harbor时所需的CA。 |
database | 存放数据库的目录,Harbor、Clair和Notary 数据库的数据都在此目录 |
job_logs | 存放JobService的日志信息 |
redis | 缓存数据 |
registry | 存放 OCI Artifacts数据(对于大部分用户来说是镜像数据) |
secret | 存放Harbor内部组件通信所需的加密信息 |
#chart_storage | 存放Helm v2版本的Chart数据。 |
4.3.3 登录web页面
win电脑需要在hosts文件添加域名才可以使用域名访问,也可以直接使用IP地址访问
账号:admin
密码:Harbor2345

4.4 停止与启动和重启Harbor
cd /usr/local/harbor
#停止harbor
docker-compose stop
docker ps -a
#启动harbor
docker-compose start
#重启harbor
docker-compose restart
#如果重启不成功,则直接使用 install.sh 脚本
# docker-compose down
# ./install.sh
4.5 harbor https 配置
[root@harbor1 harbor]# docker-compose down
[root@harbor1 harbor]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@harbor1 ~]# mkdir /etc/certs
[root@harbor1 ~]# cd /etc/certs/
#生成自签证书
[root@harbor1 certs]# openssl genrsa -out harbor-ca.key 2048
[root@harbor1 certs]# openssl req -x509 -new -nodes -key harbor-ca.key -subj "/CN=harbor1.kylin.com" -days 7120 -out harbor-ca.crt
[root@harbor1 certs]# ls
harbor-ca.crt harbor-ca.key
[root@harbor1 certs]# cd /usr/local/harbor/
#修改harbor配置文件
[root@harbor1 harbor]# vim harbor.yml
13 https:
14 # https port for harbor, default is 443
15 port: 443
16 # The path of cert and key files for nginx
17 certificate: /etc/certs/harbor-ca.crt #注意修改保存公钥的路径
18 private_key: /etc/certs/harbor-ca.key #注意修改保存私钥的路径
#重新执行安装脚本
./install.sh
#注意自签名证书是不被信任的所以,还是需要配置 --insecure-registry harbor1.kylin.com 才可以使用,或者直接使用授权证书
4.6 配置 docker 使用 harbor 仓库上传下载镜像
4.6.1 编辑 docker 配置文件
可以编写daemon或者一下文件,本文开篇已经写过daemon这里可以不用在写
vim /lib/systemd/system/docker.service
"insecure-registries": [
"https://harbor1.kylin.com",
"https://harbor2.kylin.com",
"https://img.kylin.com"
]
#配置dns解析
cat >> /etc/hosts <<EOF
192.168.11.11 harbor1.kcc.com
192.168.11.12 harbor2.kcc.com
192.168.11.100 harbor.kcc.com
EOF
#重启服务
systemctl daemon-reload
systemctl restart docker
4.6.2 验证能否登录 harbor
可以现在界面创建一个项目,添加一个成员并设置为项目的管理员

[root@harbor1 harbor]# docker login harbor1.kylin.com
Username: user1
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 #出现这个表示登录成功
4.6.3 测试上传和下载镜像
将之前构建的镜像打标签上传到 harbor 服务器用于测试
4.6.3.1 导入镜像
#先给镜像打tag
[root@harbor1 ~]# docker tag busybox:latest harbor1.kylin.com/kylin1/bbox:v1
[root@harbor1 ~]# docker images | grep bbox
harbor1.kylin.com/kylin1/bbox v1 beae173ccac6 12 months ago 1.24MB
#上传如果提示project imagesbase not found表示没有这个项目需要先去web端创建项目
[root@harbor1 harbor]# docker push harbor1.kylin.com/kylin1/bbox:v1
Using default tag: latest
The push refers to repository [harbor1.kylin.com/kylin1/bbox]
tag does not exist: harbor1.kylin.com/kylin1/bbox:latest

#创建后再次上传
[root@harbor1 ~]# docker push harbor1.kylin.com/kylin1/bbox:v1
The push refers to repository [harbor1.kylin.com/kylin1/bbox]
01fd6df81c8e: Pushed
v1: digest: sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee size: 527

新建项目时,勾选公开表示可以匿名下载本项目中镜像,但是上传必须登录,如果不勾选表示上传和下载都得登录

4.6.3.2 下载镜像
下载镜像的 docker 主机需要配置 insecure-registries,如果使用可信的证书,则不需要
在harbor2上进行下载测试
#下载时可以写IP地址,如写域名需要配置dns
[root@harbor2 ~]# docker login harbor1.kylin.com
#拉去命令可以登录网页版进行复制
[root@harbor2 ~]# docker pull harbor1.kylin.com/kylin1/bbox@sha256:62ffc2ed7554e4c6d360bce40bbcf196573dd27c4ce080641a2c59867e732dee
[root@harbor2 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
harbor1.kylin.com/kylin1/bbox <none> beae173ccac6 12 months ago 1.24MB

4.7 实现 harbor 高可用
高可用实现方式

Harbor 支持基于策略的 Docker 镜像复制功能,这类似于MySQL 的主从同步,其可以实现不同的数据中心、不同的运行环境之间同步镜像,并提供友好的管理界面,大大简化了实际运维中的镜像管理工作,已经有用很多互联网公司使用harbor 搭建内网 docker 仓库的案例,并且还有实现了双向复制的案列
4.7.1 实现双向同步复制的高可用
架构图

4.7.1.1 部署harbor的同步集群
#安装俩台harbor主机 harbor1 harbor2
#配置文件harbor.yml
vim harbor.yml
hostname: 192.168.11.11/12
#这里只能写的IP地址,写域名会导致创建目标仓库测试失败
#配置 Harbor 复制必须使用 https
#启动
./install.sh
在 harbor1 的 web 页面配置

这里目标名称可以随便写,访问ID访问密码按自己的情况填写,验证证书不要勾选,之后点测试连接,然后点确定
配置复制规则

名称:随便写
复制模式:选择推送模式,还是拉取模式
触发模式:事件驱动 (如果要将同步之前的旧镜像推送到远程,设置为手动)
其他:默认
###同样的操作在harbor2上进行配置
测试
能从 harbor1 上传下载镜像
能从 harbor2 下载从 harbor1 同步过来的镜像
反之亦然,如果全部成功说明同步没有问题
[root@harbor2 harbor]# docker tag goharbor/nginx-photon:v2.3.5 harbor2.kylin.com/kylin1/harbortest:v1
[root@harbor2 harbor]# docker login harbor2.kylin.com
[root@harbor2 harbor]# docker push harbor2.kylin.com/kylin1/harbortest:v1
本来原有的镜像使用手动复制进行同步


4.7.1.2 安装 nginx
在开启两台虚拟机11.21和11.22
两台都执行
[root@localhost ~]# yum -y install nginx
#如果 nginx 需要监听 VIP,需要配置下面内核参数
#vim /etc/sysctl.conf
#net.ipv4.ip_nonlocal_bind = 1
#此参数表示是否允许服务绑定一个本机不存在的IP地址
#sysctl -p
[root@localhost ~]# cp /etc/nginx/nginx.conf{,.bak}
[root@localhost ~]# vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
stream {
upstream harbor_server {
hash $remote_addr consistent;
server 192.168.11.11:443 max_fails=3 fail_timeout=30s;
server 192.168.11.12:443 max_fails=3 fail_timeout=30s;
}
server {
listen 80;
listen 443;
proxy_connect_timeout 3s;
proxy_timeout 30s;
proxy_pass harbor_server;
}
}
[root@localhost ~]# nginx -t
[root@localhost ~]# systemctl enable --now nginx
[root@localhost ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:*
LISTEN 0 511 0.0.0.0:443 0.0.0.0:*
4.7.1.3 安装keepalive
#俩台都执行
[root@localhost ~]# vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_DEVEL
}
vrrp_script check-nginx {
script "/etc/keepalived/chnginx.sh"
weight -30
timeout 2
fall 2
rise 3
interval 2
}
vrrp_instance VI_1 {
state MASTER
interface ens160
virtual_router_id 80
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.11.100/24
}
track_script {
check-nginx
}
}
~
[root@localhost ~]# vim /etc/keepalived/chnginx.sh
#!/bin/bash
/usr/bin/killall -0 nginx
[root@localhost ~]# chmod +x /etc/keepalived/chnginx.sh
#ke2配置修改相关内容和脚本
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 80
priority 80
#启动全部
[root@localhost keepalived]# systemctl start keepalived.service
[root@localhost keepalived]# systemctl enable keepalived.service
[root@localhost ~]# ip a
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 00:0c:29:63:07:0f brd ff:ff:ff:ff:ff:ff
inet 192.168.11.21/24 brd 192.168.11.255 scope global noprefixroute ens160
valid_lft forever preferred_lft forever
inet 192.168.11.100/24 scope global secondary ens160
valid_lft forever preferred_lft forever
inet6 fe80::4bfd:424c:d8e:a76/64 scope link noprefixroute
valid_lft forever preferred_lft forever
4.7.1.4 docker测试
在harbor1上传镜像,之后在harbor2上使用vip进行登录下载或者上传测试
[root@harbor2 docker]# docker login img.kylin.com
Login Succeeded
[root@harbor2 ~]# docker images | grep bbox
[root@harbor2 ~]#
[root@harbor2 harbor]# docker pull img.kylin.com/kylin1/bbox:v1
[root@harbor2 harbor]# docker images | grep bbox
harbor1.kylin.com/kylin1/bbox v1 beae173ccac6 12 months ago 1.24MB