| 备注 | 修改日期 | 修改人 |
| 内容更新 | 2025-12-26 12:17:03[当前版本] | 文艺范儿 |
| 创建版本 | 2025-12-26 11:33:56 | 文艺范儿 |
Harbor 是由 VMware 开源、CNCF 毕业的企业级容器镜像仓库,基于 Docker Distribution 扩展,提供安全合规、多租户管理、镜像复制等企业级能力,是容器化转型中镜像管理的核心基础设施。
| 类别 | 关键能力 |
|---|---|
镜像管理 |
支持 Docker V2/OCI 镜像、Helm Chart;多架构镜像(amd64/arm64)管理 |
安全合规 |
RBAC 权限控制、镜像签名(Notary v2/Cosign)、漏洞扫描(Trivy/Clair)、CVE 合规审计 |
高可用 |
镜像跨实例复制、多节点集群部署(Core/Registry/DB/Redis 独立扩展) |
可观测性 |
操作审计日志、Prometheus 监控指标(API 延迟、错误率、存储使用率) |
扩展性 |
支持本地存储、NFS、S3/GCS/Azure Blob 等存储后端;插件化扫描/通知机制 |
这里安装最新稳定版本:2.14.1
# 1.下载并解压
[root@docker-71 ~]# wget https://github.com/goharbor/harbor/releases/download/v2.14.1/harbor-offline-installer-v2.14.1.tgz
[root@docker-71 ~]# tar xf harbor-offline-installer-v2.14.1.tgz -C /opt/
# 2.复制并编辑配置文件,生产环境建议使用https
[root@docker-71 ~]# cd /opt/harbor/
[root@docker-71 harbor]# cp harbor.yml.tmpl harbor.yml
[root@docker-71 harbor]# cat harbor.yml
hostname: reg.wyasw.com
http:
port: 80
# https:
# port: 443
# certificate: /your/certificate/path
# private_key: /your/private/key/path
harbor_admin_password: 123456
database:
password: root123
max_idle_conns: 100
max_open_conns: 900
conn_max_lifetime: 5m
conn_max_idle_time: 0
data_volume: /home/deploy/harbor/data
trivy:
ignore_unfixed: false
skip_update: false
skip_java_db_update: false
offline_scan: false
security_check: vuln
insecure: false
timeout: 5m0s
jobservice:
max_job_workers: 10
max_job_duration_hours: 24
job_loggers:
- STD_OUTPUT
- FILE
logger_sweeper_duration: 1
notification:
webhook_job_max_retry: 3
webhook_job_http_client_timeout: 3
log:
level: info
local:
rotate_count: 50
rotate_size: 200M
location: /var/log/harbor
_version: 2.14.0
proxy:
http_proxy:
https_proxy:
no_proxy:
components:
- core
- jobservice
- trivy
upload_purging:
enabled: true
age: 168h
interval: 24h
dryrun: false
cache:
enabled: false
expire_hours: 24
# 3.准备安装环境初始化,完成以后会在目录下面生成docker-compose.yml,如修改其他配置可以修改compose文件。
[root@docker-71 harbor]# ./prepare
# 4.安装harbor
[root@docker-71 harbor]# ./install.sh
# 5.安装完成可以通过web访问 用户名:admin 密码:123456
http://192.168.31.71
# 6.查看harbor起的容器
[root@docker-71 harbor]# docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
harbor-core goharbor/harbor-core:v2.14.1 "/harbor/entrypoint.…" core 6 minutes ago Up 6 minutes (healthy)
harbor-db goharbor/harbor-db:v2.14.1 "/docker-entrypoint.…" postgresql 6 minutes ago Up 6 minutes (healthy)
harbor-jobservice goharbor/harbor-jobservice:v2.14.1 "/harbor/entrypoint.…" jobservice 6 minutes ago Up 6 minutes (healthy)
harbor-log goharbor/harbor-log:v2.14.1 "/bin/sh -c /usr/loc…" log 6 minutes ago Up 6 minutes (healthy) 127.0.0.1:1514->10514/tcp
harbor-portal goharbor/harbor-portal:v2.14.1 "nginx -g 'daemon of…" portal 6 minutes ago Up 6 minutes (healthy)
nginx goharbor/nginx-photon:v2.14.1 "nginx -g 'daemon of…" proxy 6 minutes ago Up 6 minutes (healthy) 0.0.0.0:80->8080/tcp, [::]:80->8080/tcp
redis goharbor/redis-photon:v2.14.1 "redis-server /etc/r…" redis 6 minutes ago Up 6 minutes (healthy)
registry goharbor/registry-photon:v2.14.1 "/home/harbor/entryp…" registry 6 minutes ago Up 6 minutes (healthy)
registryctl goharbor/harbor-registryctl:v2.14.1 "/home/harbor/start.…" registryctl 6 minutes ago Up 6 minutes (healthy)
登录系统后,我们可以看到系统各个模块如下:
注意:非系统管理员用户登录,只能看到有权限的项目和日志,其他模块不可见。
新建项目
我们新建一个名称为wyasw的项目,设置不公开。
默认有library项目,是公开的项目。
注意:当项目设为公开后,任何人都有此项目下镜像的读权限。命令行用户不需要“docker login”就可以拉取此项目下的镜像。
新建项目完毕后,我们就可以用admin账户提交本地镜像到Harbor仓库了。例如我们提交本地nginx镜像:
# 如果没有解析域名,需要添加hosts 192.168.31.71 reg.wyasw.com
# 1.添加hosts
[root@docker-72 ~]# cat /etc/hosts
...
192.168.31.71 reg.wyasw.com
...
# 2.因为Docker默认尝试使用HTTPS协议访问 registry,但我的registry使用的是HTTP,用以下方法解决
# 在daemon.json中添加 "insecure-registries": ["reg.wyasw.com"],添加完重启docker服务
[root@docker-72 ~]# vim /etc/docker/daemon.json
[root@docker-72 ~]# cat /etc/docker/daemon.json
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://docker.xuanyuan.me",
"https://docker.1ms.run"
],
"dns": ["223.5.5.5", "114.114.114.114"],
"exec-opts": ["native.cgroupdriver=systemd"],
"log-driver": "json-file",
"log-opts": {
"max-size": "100m"
},
"storage-driver": "overlay2",
"insecure-registries": ["reg.wyasw.com"]
}
[root@docker-72 ~]# systemctl restart docker
# 3.使用admin登录
[root@docker-72 ~]# docker login reg.wyasw.com
Username: admin
Password:
WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'.
Configure a credential helper to remove this warning. See
https://docs.docker.com/go/credential-store/
Login Succeeded
# 4.给镜像打tag
[root@docker-72 ~]# docker tag nginx:alpine reg.wyasw.com/wyasw/nginx:v1.0
# 5.push到仓库
[root@docker-72 ~]# docker push reg.wyasw.com/wyasw/nginx
Using default tag: latest
The push refers to repository [reg.wyasw.com/wyasw/nginx]
e6fe11fa5b7f: Pushed
67ea0b046e7d: Pushed
ed5fa8595c7a: Pushed
8ae63eb1f31f: Pushed
b3e3d1bbb64d: Pushed
48078b7e3000: Pushed
fd1e40d7f74b: Pushed
7bb20cf5ef67: Pushed
latest: digest: sha256:00e053577693e0ee5f7f8b433cdb249624af188622d0da5df20eef4e25a0881c size: 1989
上传完毕后,登录Web Harbor,选择项目,项目名称wyasw,就可以查看刚才上传的nginx image了。

我们刚一直是用admin操作,实际应用中我们使用每个人自己的账户登录。所以就需要新建用户,同时为了让用户有权限操作已经创建的项目,还必须将该用户添加到该项目成员中。
创建用户名为dongshufeng的测试用户,点击系统管理-》用户管理-》创建用户,输入用户名、邮箱、密码等信息。

将dongshufeng用户添加到wyasw项目成员中,点击项目-》wyasw-》成员-》新建成员,填写姓名,选择角色。

现在我们使用dongshufeng账户本地模拟操作pull刚上传的nginx镜像。
# 1.先移除tag(因为我本地刚上传了该nginx镜像,直接pull,检测本地存在就不会pull) [root@docker-72 ~]# docker images |grep nginx reg.wyasw.com/wyasw/nginx:v1.0 04da2b0513cd 53.7MB 0B [root@docker-72 ~]# docker rmi 04da2b0513cd # 2.退出admin账号,登录dongshufeng账号 [root@docker-72 ~]# docker logout admin Removing login credentials for admin [root@docker-72 ~]# docker login reg.wyasw.com -u dongshufeng Password: WARNING! Your credentials are stored unencrypted in '/root/.docker/config.json'. Configure a credential helper to remove this warning. See https://docs.docker.com/go/credential-store/ Login Succeeded # 3.拉取镜像从harbor仓库 [root@docker-72 ~]# docker pull reg.wyasw.com/wyasw/nginx Using default tag: latest latest: Pulling from wyasw/nginx 1074353eec0d: Already exists 25f453064fd3: Pull complete 567f84da6fbd: Pull complete da7c973d8b92: Pull complete 33f95a0f3229: Pull complete 085c5e5aaa8e: Pull complete 0abf9e567266: Pull complete de54cb821236: Pull complete Digest: sha256:00e053577693e0ee5f7f8b433cdb249624af188622d0da5df20eef4e25a0881c Status: Downloaded newer image for reg.wyasw.com/wyasw/nginx:latest reg.wyasw.com/wyasw/nginx:latest
除过以下介绍的方式,还可以通过API进行删除,2.14.1版本的还可以通过 Harbor CLI 删除(需要安装)
删除镜像的两种方式
| 删除类型 | 操作位置 | 实际效果 | 存储释放 |
|---|---|---|---|
软删除 |
删除标签/标记 |
从UI/API移除,数据仍存在 |
不释放 |
硬删除 |
垃圾回收(GC) |
物理删除存储数据 |
释放存储空间 |
通过 Harbor Web UI 删除
垃圾回收(释放存储空间)
在web页面,系统管理,清理服务。
graph TB
subgraph "当前环境"
Harbor1[Harbor1<br/>192.168.31.71<br/>现有服务]
Harbor2[Harbor2<br/>192.168.31.72<br/>现有服务]
end
subgraph "高可用改造后"
VIP[虚拟IP<br/>192.168.31.100]
LB1[Keepalived<br/>主节点]
LB2[Keepalived<br/>备节点]
DB[(PostgreSQL<br/>主从复制<br/>或者<br/>redis哨兵)]
Storage[(NFS/共享存储)]
end
VIP -->|健康检查| LB1
VIP -->|故障切换| LB2
LB1 --> Harbor1
LB2 --> Harbor2
Harbor1 --> DB
Harbor2 --> DB
Harbor1 --> Storage
Harbor2 --> Storage
首先我们至少得配置两个Harbor服务:
我们已经往Harbor1上面push了一个镜像了,那么就把Harbor1当做主节点,Harbor2当做复制节点,我们要把Harbor1上的镜像自动复制到Harbor2上去。
登录Harbor1配置,点击仓库管理-》新建目标,输入提供者-Harbor,目标名-reg2,目标URL-http://192.168.31.72,访问ID-admin 访问密码-123456,点击测试连接。显示测试连接成功。则点击确定。
再点击复制规则,点击 系统管理-》复制管理-》新建复制规则,填写名称、目标仓库,触发模式选择定时,CRON:0 /1 * 表示每分钟复制一次,然后启用规则。注意:不要勾选覆盖。
然后再登录Harbor2,到一分钟就会看到Harbor1复制项目到Harbor2了。
使用keepalived实现高可用案例:
两个节点都先安装keepaliced服务:
apt-get update apt-get install -y keepalived
# 1.生成Keepalived配置
cat > /etc/keepalived/keepalived.conf << 'KEEPALIVED'
! Configuration File for keepalived
! Harbor HA - Master Node
global_defs {
router_id harbor_master
script_user root
}
# 检测Harbor 80端口
vrrp_script chk_harbor {
script "/etc/keepalived/check_harbor.sh"
interval 3 # 每3秒检测一次
weight -60 # 权重失败时减少60权重,让优先级从150降到90(低于备节点的100)这里很重要,不然会导致无法漂移VIP
fall 3 # 连续3次失败认为故障
rise 2 # 连续2次成功认为恢复
timeout 2 # 检测超时2秒
}
vrrp_instance VI_HARBOR {
state MASTER # 初始状态:主节点
interface ens35 # 网卡名称
virtual_router_id 51 # 虚拟路由ID(0-255)
priority 150 # 优先级(主节点更高)
advert_int 1 # VRRP通告间隔1秒
authentication {
auth_type PASS
auth_pass harbor11 # 认证密码
}
virtual_ipaddress {
192.168.31.100/24 dev ens35 # 虚拟IP
}
track_script {
chk_harbor # 跟踪80端口检测
}
# 状态变化通知
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
KEEPALIVED
# 2. 创建健康检查脚本
cat > /etc/keepalived/check_harbor.sh<< 'CHECK_SCRIPT'
#!/bin/bash
# Harbor 80端口检测脚本 - 修复版
LOG_FILE="/var/log/keepalived-port-check.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 更严格的80端口检测
check_port() {
log "开始检测80端口..."
# 方法1: 检查端口监听
if netstat -tln 2>/dev/null | grep -q ':80 '; then
log "netstat检测到80端口监听"
else
log "netstat未检测到80端口"
return 1
fi
# 方法2: 检查HTTP响应(更可靠)
if curl -s --connect-timeout 3 --max-time 5 http://localhost:80/ >/dev/null 2>&1; then
log "HTTP响应检测通过"
return 0
else
log "HTTP响应检测失败"
return 1
fi
}
# 主函数
main() {
log "=== 开始80端口健康检查 ==="
if check_port; then
log "✅ 80端口检测成功"
log "=== 健康检查结束 ==="
exit 0
else
log "❌ 80端口检测失败"
# 尝试重启Harbor(可选)
log "=== 健康检查结束(失败)==="
exit 1
fi
}
# 执行检测
main
CHECK_SCRIPT
# 3. 设置脚本权限
chmod +x /etc/keepalived/check_harbor.sh
# 4. 创建通知脚本
cat > /etc/keepalived/notify.sh<< 'NOTIFY_SCRIPT'
#!/bin/bash
# 状态通知脚本
VIP="192.168.31.100"
NODE_IP="192.168.31.71"
BACKUP_IP="192.168.31.72"
case "$1" in
"master")
echo "Harbor节点 $NODE_IP 切换为MASTER,VIP: $VIP" | \
# mail -s "[Harbor HA] 主节点切换" admin@example.com 2>/dev/null || true
echo "[$(date)] MASTER切换: $NODE_IP" >> /var/log/harbor-ha.log
;;
"backup")
echo "[$(date)] BACKUP切换: $NODE_IP" >> /var/log/harbor-ha.log
;;
"fault")
echo "紧急:Harbor节点 $NODE_IP 故障!" | \
# mail -s "[Harbor HA] 故障告警" admin@example.com 2>/dev/null || true
echo "[$(date)] FAULT: $NODE_IP" >> /var/log/harbor-ha.log
;;
esac
NOTIFY_SCRIPT
# 设置权限
chmod +x /etc/keepalived/notify.sh
# 5. 启动服务
systemctl daemon-reload
systemctl restart keepalived
systemctl enable keepalived
# 6. 检查服务状态
systemctl status keepalived --no-pager
echo -e "IP地址信息:"
ip addr show | grep -A2 "ens35"
echo -e "检查VIP:"
ip addr show | grep "192.168.31.100" && echo "✅ VIP配置成功" || echo "❌ VIP未配置"
echo -e "\n✅ 主节点Keepalived配置完成"
# 1. 生成Keepalived配置
cat > /etc/keepalived/keepalived.conf << 'KEEPALIVED'
! Configuration File for keepalived
! Harbor HA - Backup Node
global_defs {
router_id harbor_backup
script_user root
}
vrrp_script chk_harbor {
script "/etc/keepalived/check_harbor.sh"
interval 3
weight -60
fall 3
rise 2
timeout 2
}
vrrp_instance VI_HARBOR {
state BACKUP # 初始状态:备节点
interface ens35
virtual_router_id 51 # 必须和主节点一致
priority 100 # 优先级低于主节点
advert_int 1
authentication {
auth_type PASS
auth_pass harbor11 # 必须和主节点一致
}
virtual_ipaddress {
192.168.31.100/24 dev ens35
}
track_script {
chk_harbor
}
notify_master "/etc/keepalived/notify.sh master"
notify_backup "/etc/keepalived/notify.sh backup"
notify_fault "/etc/keepalived/notify.sh fault"
}
KEEPALIVED
# 2. 创建健康检查脚本
cat > /etc/keepalived/check_harbor.sh<< 'CHECK_SCRIPT'
#!/bin/bash
# Harbor 80端口检测脚本 - 修复版
LOG_FILE="/var/log/keepalived-port-check.log"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" >> "$LOG_FILE"
}
# 更严格的80端口检测
check_port() {
log "开始检测80端口..."
# 方法1: 检查端口监听
if netstat -tln 2>/dev/null | grep -q ':80 '; then
log "netstat检测到80端口监听"
else
log "netstat未检测到80端口"
return 1
fi
# 方法2: 检查HTTP响应(更可靠)
if curl -s --connect-timeout 3 --max-time 5 http://localhost:80/ >/dev/null 2>&1; then
log "HTTP响应检测通过"
return 0
else
log "HTTP响应检测失败"
return 1
fi
}
# 主函数
main() {
log "=== 开始80端口健康检查 ==="
if check_port; then
log "✅ 80端口检测成功"
log "=== 健康检查结束 ==="
exit 0
else
log "❌ 80端口检测失败"
# 尝试重启Harbor(可选)
log "=== 健康检查结束(失败)==="
exit 1
fi
}
# 执行检测
main
CHECK_SCRIPT
# 3. 设置脚本权限
chmod +x /etc/keepalived/check_harbor.sh
# 4. 创建通知脚本
cat > /etc/keepalived/notify.sh<< 'NOTIFY_SCRIPT'
#!/bin/bash
# 状态通知脚本
VIP="192.168.31.100"
NODE_IP="192.168.31.72"
BACKUP_IP="192.168.31.72"
case "$1" in
"master")
echo "Harbor节点 $NODE_IP 切换为MASTER,VIP: $VIP" | \
# mail -s "[Harbor HA] 主节点切换" admin@example.com 2>/dev/null || true
echo "[$(date)] MASTER切换: $NODE_IP" >> /var/log/harbor-ha.log
;;
"backup")
echo "[$(date)] BACKUP切换: $NODE_IP" >> /var/log/harbor-ha.log
;;
"fault")
echo "紧急:Harbor节点 $NODE_IP 故障!" | \
# mail -s "[Harbor HA] 故障告警" admin@example.com 2>/dev/null || true
echo "[$(date)] FAULT: $NODE_IP" >> /var/log/harbor-ha.log
;;
esac
NOTIFY_SCRIPT
# 设置权限
chmod +x /etc/keepalived/notify.sh
# 5. 启动服务
systemctl daemon-reload
systemctl restart keepalived
systemctl enable keepalived
# 6. 检查服务状态
systemctl status keepalived --no-pager
echo -e "IP地址信息:"
ip addr show | grep -A2 ens35
echo -e "\n检查VIP:"
if ip addr show | grep -q "192.168.31.100"; then
echo "⚠️ VIP已配置(可能主节点故障)"
else
echo "✅ VIP未配置(正常状态)"
fi
echo -e "\n最近日志:"
journalctl -u keepalived --no-pager -n 10
echo -e "\n✅ 备节点Keepalived配置完成"
首先通过VIP访问Harbor:
停止主节点的harbor或者keepalived 看VIP是否漂移到备节点,
cd /opt/harbor/ docker compose stop
看web是否能正常访问。
再恢复主节点的harbor或者keepalived看VIP是否又切换到主节点。
cd /opt/harbor/ docker compose up -d
从免费发放https的证书平台申请https证书然后部署即可。
这里不做介绍。