智能
助手
最大化  清空记录 停止  历史记录
翻译选中文本
选中一段文本后进行翻译
名词解释
选中一段文本后进行名词解释
知识图谱生成
通过图谱展示知识信息
登录用户在知识浏览页面可用
答案生成
AI自动回答一个问答功能中的问题
登录用户在问答浏览页面,且问题开放回答中可用
知识摘要
自动为当前知识生成摘要
知识浏览页面可用
知识问答
针对当前知识进行智能问答
知识浏览面可用
2025-12-26 12:17:03 版本 : 11. Harbor容器镜像仓库
作者: 文艺范儿 于 2025年12月26日 发布在分类 / Docker & K8S / docker进阶 下,并于 2025年12月26日 编辑
 历史版本

备注 修改日期 修改人
内容更新 2025-12-26 12:17:03[当前版本] 文艺范儿
创建版本 2025-12-26 11:33:56 文艺范儿

11. Harbor容器镜像仓库

11.1 简介

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 等存储后端;插件化扫描/通知机制

11.2 单实例部署

这里安装最新稳定版本: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)

登录系统后,我们可以看到系统各个模块如下:

  • 项目:新增/删除项目,查看镜像仓库,给项目添加成员、查看操作日志、复制项目等
  • 日志:仓库各个镜像create、push、pull等操作日志
  • 系统管理
    • 用户管理:新增/删除用户、设置管理员等
    • 复制管理:新增/删除从库目标、新建/删除/启停复制规则等
    • 配置管理:认证模式、复制、邮箱设置、系统设置等
  • 其他设置
    • 用户设置:修改用户名、邮箱、名称信息
    • 修改密码:修改用户密码

注意:非系统管理员用户登录,只能看到有权限的项目和日志,其他模块不可见。

11.3 Harbor镜像推送拉取删除

新建项目

我们新建一个名称为wyasw的项目,设置不公开。

默认有library项目,是公开的项目。

注意:当项目设为公开后,任何人都有此项目下镜像的读权限。命令行用户不需要“docker login”就可以拉取此项目下的镜像。

11.3.1 推送

新建项目完毕后,我们就可以用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了。

11.3.2 拉取

我们刚一直是用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

11.3.2 删除

除过以下介绍的方式,还可以通过API进行删除,2.14.1版本的还可以通过 Harbor CLI 删除(需要安装)

删除镜像的两种方式

删除类型 操作位置 实际效果 存储释放

软删除

删除标签/标记

从UI/API移除,数据仍存在

不释放

硬删除

垃圾回收(GC)

物理删除存储数据

释放存储空间

通过 Harbor Web UI 删除

  1. 登录 Harbor Web UI
  2. 进入项目 → 选择镜像仓库
  3. 点击镜像标签 → 删除按钮
  4. 确认删除(这只是软删除)

垃圾回收(释放存储空间)

在web页面,系统管理,清理服务。

11.4 Harbor的高可用部署

11.4.1 架构概览

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

11.4.2 Harbor的镜像同步

首先我们至少得配置两个Harbor服务:

  1. Harbor1:192.168.31.71 hostname: 192.168.31.71
  2. Harbor2:192.168.31.72 hostname: 192.168.31.72

我们已经往Harbor1上面push了一个镜像了,那么就把Harbor1当做主节点,Harbor2当做复制节点,我们要把Harbor1上的镜像自动复制到Harbor2上去。

登录Harbor1配置,点击仓库管理-》新建目标,输入提供者-Harbor,目标名-reg2,目标URL-http://192.168.31.72,访问ID-admin 访问密码-123456,点击测试连接。显示测试连接成功。则点击确定。

再点击复制规则,点击 系统管理-》复制管理-》新建复制规则,填写名称、目标仓库,触发模式选择定时,CRON:0 /1 * 表示每分钟复制一次,然后启用规则。注意:不要勾选覆盖。

然后再登录Harbor2,到一分钟就会看到Harbor1复制项目到Harbor2了。

11.4.3 Harbor高可用案例

使用keepalived实现高可用案例:

两个节点都先安装keepaliced服务:

apt-get update
apt-get install -y keepalived
11.4.3.1 主节点配置(192.168.31.71)
# 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配置完成"
11.4.3.2 备节点配置(192.168.31.72)
# 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配置完成"
11.4.3.3 验证

首先通过VIP访问Harbor:

web :http://192.168.31.100

停止主节点的harbor或者keepalived 看VIP是否漂移到备节点,

cd /opt/harbor/
docker compose stop

看web是否能正常访问。

再恢复主节点的harbor或者keepalived看VIP是否又切换到主节点。

cd /opt/harbor/
docker compose up -d

11.5 Harbor部署基于官方的https证书

从免费发放https的证书平台申请https证书然后部署即可。

这里不做介绍。

历史版本-目录  [回到顶端]
    文艺知识分享平台 -V 5.2.5 -wcp