Harbor 私有镜像仓库搭建 + Prometheus 监控完整实践笔记

一、项目概述

企业容器化运维场景中,直接使用公网 Docker Hub 存在网络访问缓慢、镜像权限无隔离、业务源码镜像泄露、缺乏漏洞安全扫描等诸多痛点。为解决上述问题,本方案基于 CentOS 系统离线部署私有镜像仓库 Harbor v2.14.2,完成 HTTPS 自签证书加密、系统开机自启托管、多客户端镜像推拉全流程调通;同时配套搭建Prometheus+Grafana+cAdvisor+node-exporter一体化监控体系,对接 Harbor 内置 Exporter 采集仓库业务指标,实现宿主机硬件资源、容器运行负载、Harbor 仓库业务数据统一可视化观测。整套方案适配中小企业生产环境,兼顾镜像私有化管理、安全准入、全链路可观测三大核心需求,也可作为云原生监控学习完整落地案例。

二、整体架构说明
  1. 底层底座:Docker Engine 29.1.5 + Docker Compose v2.3+,统一承载 Harbor 镜像仓库、整套监控组件的容器化运行,标准化编排、一键启停,降低环境维护成本

  2. 镜像仓库层:核心能力:镜像持久化存储、多项目用户权限分级管理、Trivy 镜像漏洞自动扫描、RBAC 账号权限管控;内置 harbor-exporter 原生暴露仓库 Metrics 监控接口,无需额外二次开发。

  3. 指标采集层:

    node-exporter:采集宿主机 CPU、内存、磁盘、IO、网络、系统负载等硬件底层指标;

    cAdvisor:采集服务器上所有容器的 CPU 占用、内存消耗、磁盘读写、网络流量、容器生命周期状态;

    harbor-exporter:对接 Harbor 仓库,采集仓库总存储容量、镜像数量、镜像推拉 QPS、漏洞扫描结果、项目访问频次等业务维度指标。

  4. 存储与可视化层

    Prometheus:时序数据库,统一持久化存储所有采集指标,支持灵活 PromQL 查询、告警规则定义;

    Grafana:可视化大屏平台,统一接入 Prometheus 数据源,自定义监控面板,一站式展示主机、容器、私有仓库全部监控数据。

三、Harbor 私有仓库部署流程

完整流程见前期harbor私有化镜像仓库搭建细节,此次项目在其基础上搭建Prometheus +Grafana可视化升级,并适配docker容器化环境,采用docker-compose一键编排部署。

1、操作流程梗概如下:

1.环境准备:克隆一台虚拟机(harbor),CPU 至少 2 核,Memory 至少 4G,磁盘 100G。

2.修改主机名,修改ip地址,并配置主机映射: cat /etc/hosts : 192.168.110.165 hb.reg.com harbor

3.安装docker,修改 /etc/docker/daemon.json,添加加速器同时,增加 insecure-registries 配置来指定我们自己的私有仓库访问地址。: “insecure-registries”: [“https://hb.reg.com”],

4.刷新配置,重启docker服务

5.软件清单:

Docker Engine Version > 20.10 用于运行Harbor环境
Docker Compose Docker compose > 2.3 用于管理Harbor服务
OpenSSL Latest (optional) 用于生成Harbor访问的私钥和证书

6.下载harbor安装包,解压至/usr/local/

2、证书配置:进入/usr/local/harbor/目录

1.生成CA证书:mkdir certs存放证书目录,通过生成CA证书私钥文件来生成证书文件 ca.crt ca.key

2.生成服务证书:ssl目录下生成服务私钥,然后生成服务证书 hb.reg.com.csr hb.reg.com.key

3.生成x509 v3扩展文件,并使用其为harbor主机生成证书:v3.ext hb.reg.com.crt

4.配置仓库证书:生成 ca.crt、hb.reg.com.crt 和 hb.reg.com.key 密钥文件后,您必须将它们提供给Harbor和Docker,并重新配置Harbor以使用它们。将服务器证书和密钥复制进/data/cert,利用x509转换hb.reg.com.crt 为 hb.reg.com.cert,供 Docker 使用

5.将服务器证书,私钥文件和 CA 文件复制到 Harbor 主机上的 Docker 证书文件夹中:

# 查看最终结构

[root@harbor cert]# tree /etc/docker/certs.d/
/etc/docker/certs.d/
└── hb.reg.com:443
    ├── ca.crt
    ├── hb.reg.com.cert
    └── hb.reg.com.key

1 directory, 3 files

6.启动docker服务,systemctl restart docker

3、部署配置Herbor

1.从配置文件模板中复制出配置文件并部分修改:

hostname: hb.reg.com, 
http:
  port: 80
https:
  port: 443
certificate: /usr/local/harbor/certs/hb.reg.com.crt
private_key: /usr/local/harbor/certs/hb.reg.com.key
......
harbor_admin_password: Harbor12345
......
data_volume: /opt/data
.......

2.创建数据卷目录:mkdir -p /opt/data

3.加载harbor镜像,导入镜像文件;docker load -i harbor.v2.14.2.tar.gz并检查安装环境

[root@harbor harbor]# pwd
/usr/local/harbor/
[root@harbor harbor]# ls
common.sh  harbor.v2.14.2.tar.gz  harbor.yml  harbor.yml.tmpl  install.sh  LICENSE  prepare  ssl

[root@harbor harbor]# ./prepare 

执行完后目录中会生成 docker-compose.yml 文件

4.执行./install.sh进行启动,并可查看运行容器,并为harbor配置启动服务,加入开机自启动

4、定制本地私有化镜像仓库及监控系列镜像推送

1.配置windows主机映射,为了使用域名来访问,我们需要在 windows 中C:\Windows\System32\drivers\etc\hosts文件配置 IP 和域名的映射。

192.168.110.165   hb.reg.com

2.在浏览器中输入 https://hb.reg.com 来访问,成功可达,并在页面创建标签目录,monitor

3.在主机192.168.110.165上登入harbor仓库,并将提前准备好的 node_exporter、 prometheus、cadvisor、alermanage、grafana镜像包 load -i 导入images镜像库,然后为镜像打标签tag;并进行推送push;

四、搭建Prometheus+Grafana可观测监控体系
1、环境准备

1.新配置一台主机:192.168.110.146 并安装好docker服务,以及配置好镜像加速器,同时增加 insecure-registries 配置来指定我们自己的私有仓库访问地址。: “insecure-registries”: [“https://hb.reg.com”],

2.安装docker-compose,并赋可执行权限 chmod +x /usr/bin/docker-compose

3.配置主机映射:cat /etc/hosts: 192.168.110.165 hb.reg.com

确保访问通畅:尝试ping 192.168.110.165 hb.reg.com

[root@localhost ~]# ping 192.168.110.165 
PING 192.168.110.165 (192.168.110.165) 56(84) bytes of data.
64 bytes from 192.168.110.165: icmp_seq=1 ttl=64 time=6.03 ms
64 bytes from 192.168.110.165: icmp_seq=2 ttl=64 time=0.414 ms
64 bytes from 192.168.110.165: icmp_seq=3 ttl=64 time=0.721 ms
^C
--- 192.168.110.165 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2032ms
rtt min/avg/max/mdev = 0.414/2.389/6.034/2.579 ms
[root@localhost ~]# 

4.登入harbror;docker login hb.reg.com,并尝试拉取和推送镜像,发现报错:本地客户端服务器未信任 Harbor 自建的 CA 根证书,Docker 拉取镜像发起 HTTPS 请求时,系统无法识别自签证书颁发机构,直接阻断 TLS 连接。

5.解决办法:

Harbor 服务端(192.168.110.165)根证书真实路径 /etc/docker/certs.d/hb.reg.com:443/ca.crt,在 146 客户端执行如下命令拉取证书到本地 /tmp 目录:

scp root@192.168.110.165:/etc/docker/certs.d/hb.reg.com:443/ca.crt /tmp/

将 CA 根证书加入系统全局信任库:

cp /tmp/ca.crt /etc/pki/ca-trust/source/anchors/hb-reg-ca.crt 

update-ca-trust

创建 Docker 标准证书目录,带:443 端口,匹配仓库域名端口

mkdir -p /etc/docker/certs.d/hb.reg.com:443
cp /tmp/ca.crt /etc/docker/certs.d/hb.reg.com:443/

重载系统配置并重启 Docker 服务生效

systemctl daemon-reload
systemctl restart docker

登录私有 Harbor 仓库(私有 monitor 项目必须鉴权),重新拉取监控镜像测试;

docker login hb.reg.com
docker pull hb.reg.com/monitor/node-exporter:v1.10.2
2、配置监控环境
2.1创建目录
[root@localhost  ~]# mkdir /opt/jk/{grafana,prometheus,alertmanager,node_exporter} -p

[root@localhost  jk]\# cd /opt/jk
2.2创建alertmanager配置文件(邮件通知)

alertmanager/config.yml实现告警分组、冷却、邮件推送、告警抑制(严重告警屏蔽同类型警告告警),配置 163 邮箱作为发件端,QQ 邮箱接收告警;支持告警恢复通知推送。

内容如下:

[root@monitor jk]# cat  alertmanager/config.yml 

global:
  smtp_smarthost: 'smtp.163.com:465'   #163服务器
  smtp_from: '135****2724@163.com'
  smtp_auth_username: '135****2724@163.com'  #发邮件的邮箱用户名,也就是你的邮箱
  smtp_auth_password: '***V33B2fGybxn7z'    #发邮件的邮箱密码
  smtp_require_tls: false      #进行tls验证

route:
group_by: ['alertname']
# 当收到告警的时候,等待group_wait配置的时间,看是否还有告警,如果有就一起发出去
group_wait: 10s
# 如果上次告警信息发送成功,此时又来了一个新的告警数据,则需要等待group_interval配置的时间才可以发送出去
group_interval: 10s
# 如果上次告警信息发送成功,且问题没有解决,则等待 repeat_interval配置的时间再次发送告警数据
repeat_interval: 10m
# 全局报警组,这个参数是必选的
receiver: email

receivers:

- name: 'email'   #收邮件的邮箱
  email_configs:
  - to: '287****156@qq.com'    #当告警恢复后,是否发送邮件
    send_resolved: true

inhibit_rules:

- source_match:
  severity: 'critical'
  target_match:
    severity: 'warning'
  equal: ['alertname', 'dev', 'instance']
2.3创granfana配置文件

配置 grafana 管理账号信息:

坑点说明:该配置仅容器首次初始化生效,容器已有持久化数据时,修改文件不会自动同步数据库密码;连续输错密码会触发 Grafana 暴力锁定机制,内网环境可新增GF_AUTH_MAX_LOGIN_ATTEMPTS=0关闭锁定限制。

[root@monitor jk]# cat > grafana/config.monitoring 

GF_SECURITY_ADMIN_USER=admin # 登录用户s

GF_SECURITY_ADMIN_PASSWORD=password # 登录密码

GF_USERS_ALLOW_SIGN_UP=false # 不允许注册
2.4 创建prometheus配置文件

prometheus/prometheus.yml定义全局抓取周期、Alertmanager 对接地址、多 Job 采集任务:Prometheus 自身、告警组件、容器指标、宿主机硬件、Harbor 私有仓库;为不同实例添加业务标签,方便面板筛选与告警区分。

[root@monitor jk]# cat  prometheus/prometheus.yml

# 全局配置
global:
  scrape_interval:     15s   # 将搜刮间隔设置为每15秒一次。默认是每1分钟一次
  evaluation_interval: 15s   # 每15秒评估一次规则。默认是每1分钟一次。

# Alertmanager 配置
alerting:
  alertmanagers:

  - static_configs:
    - targets: ['192.168.110.146:9093']

# 报警(触发器)配置
rule_files:

  - "alert.yml"


# 搜刮配置
scrape_configs:

  - job_name: 'prometheus'
    static_configs:
    - targets: ['192.168.110.146:9090']
  - job_name: 'alertmanager'
    static_configs:
    - targets: ['192.168.110.146:9093']
  - job_name: 'cadvisor'
    static_configs:
    - targets: ['192.168.110.146:8080']
      labels:
        instance: Prometheus服务器
  - job_name: 'node-exporter'
    static_configs:
    - targets: ['192.168.110.146:9100']
      labels:
        instance: Prometheus服务器
  - job_name: 'harbor'
    static_configs:
    - targets: [192.168.110.165:9090]
      labels:
        instance: Harbor
2.5创建alert报警文件

核心规则:检测所有 exporter、服务实例存活状态,实例失联 10 秒触发 Critical 级邮件告警。

[root@monitor jk]# cat  prometheus/alert.yml 
groups:
- name: Prometheus alert
  rules:
  # 对任何实例超过10秒无法联系的情况发出警报
  - alert: 服务告警
    expr: up == 0
    for: 10s
    labels:
      severity: critical
    annotations:
      summary: "服务异常,实例:{{ $labels.instance }}"
      description: "{{ $labels.job }} 服务10秒前已关闭"
                                                       
3、编写docker-compose.yaml

此处配置文件中,镜像来源image 统一接入刚刚搭建的harbor镜像仓库,保证构建速率,以及镜像安全性,自主性,增强构建环境稳定性;

3.1存储声明:prometheus_datagrafana_data持久化卷,指标、Grafana 面板 / 账号配置永久保存,容器删除数据不丢失;

3.2自定义桥接网络monitoring:所有监控容器接入同一网络,容器间可通过服务名互相访问(如 grafana 直接使用 prometheus:9090 连接数据源);

3.3统一使用私有 Harbor 镜像hb.reg.com/monitor/*,保障环境镜像统一、离线可部署;

3.4容器永久重启策略restart: always,服务器重启自动拉起所有监控服务;

3.5时间挂载/etc/localtime统一容器与宿主机时区,避免日志、监控时间错乱;

3.6cAdvisor、node-exporter 挂载宿主机底层文件系统,授权 privileged 权限,完整采集硬件 / 容器指标;

3.7Prometheus 开启热加载--web.enable-lifecycle,修改采集规则无需重启容器;指标数据保留 30 天。

[root@monitor jk]# cat docker-compose.yaml
volumes:
  prometheus_data: {}
  grafana_data: {}

networks:
  monitoring:
    driver: bridge

services:
  prometheus:
    image: hb.reg.com/monitor/prometheus:v3.9.1
    container_name: prometheus
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./prometheus/:/etc/prometheus/
      - prometheus_data:/prometheus
    command:
      - --config.file=/etc/prometheus/prometheus.yml
      - --storage.tsdb.path=/prometheus
      - --web.console.libraries=/usr/share/prometheus/console_libraries
      - --web.console.templates=/usr/share/prometheus/consoles  #热加载配置
      - --web.enable-lifecycle
      - --storage.tsdb.retention.time=30d       #历史数据最大保留时间,默认15天
    networks:
      - monitoring
    ports:
      - 9090:9090
    depends_on:
      - cadvisor
      - node_exporter

  alertmanager:
    image: hb.reg.com/monitor/alertmanager:v0.31.1
    container_name: alertmanager
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - ./alertmanager/:/etc/alertmanager/
    command:
      - --config.file=/etc/alertmanager/config.yml
      - --storage.path=/alertmanager
    ports:
      - 9093:9093
    networks:
      - monitoring

  cadvisor:
    image: hb.reg.com/monitor/cadvisor:v0.57.0
    container_name: cadvisor
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker:/var/lib/docker:ro
    networks:
      - monitoring
    ports:
      - 8080:8080
    privileged: true

  node_exporter:
    image: hb.reg.com/monitor/node-exporter:v1.10.2
    container_name: node_exporter
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - --path.procfs=/host/proc
      - --path.sysfs=/host/sys
      - --collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc|rootfs/var/lib/docker)($|/)
    networks:
      - monitoring
    ports:
      - 9100:9100

  grafana:
    image: hb.reg.com/monitor/grafana:12.4.0
    container_name: grafana
    restart: always
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - grafana_data:/var/lib/grafana
      - ./grafana/provisioning:/etc/grafana/provisioning
    env_file:
      - ./grafana/config.monitoring
    networks:
      - monitoring
    ports:
      - 3000:3000
    depends_on:
      - prometheus
[root@localhost jk]# 
1、执行docker-compose,快速构建环境
[root@localhost jk]# docker-compose up -d
[+] up 6/6
 ✔ Network jk_monitoring   Created                                                                   0.1s
 ✔ Container alertmanager  Started                                                                   0.6s
 ✔ Container node_exporter Started                                                                   0.6s
 ✔ Container cadvisor      Started                                                                   0.6s
 ✔ Container prometheus    Started                                                                   0.8s
 ✔ Container grafana       Started                                                                   1.0s
[root@localhost jk]# 
2.查看运行状态
[root@localhost jk]# docker-compose ps
NAME            IMAGE                                      COMMAND                  SERVICE         CREATED          STATUS                    PORTS
alertmanager    hb.reg.com/monitor/alertmanager:v0.31.1    "/bin/alertmanager -…"   alertmanager    15 seconds ago   Up 15 seconds             0.0.0.0:9093->9093/tcp, [::]:9093->9093/tcp
cadvisor        hb.reg.com/monitor/cadvisor:v0.57.0        "/usr/bin/entrypoint…"   cadvisor        15 seconds ago   Up 15 seconds (healthy)   0.0.0.0:8080->8080/tcp, [::]:8080->8080/tcp
grafana         hb.reg.com/monitor/grafana:12.4.0          "/run.sh"                grafana         15 seconds ago   Up 14 seconds             0.0.0.0:3000->3000/tcp, [::]:3000->3000/tcp
node_exporter   hb.reg.com/monitor/node-exporter:v1.10.2   "/bin/node_exporter …"   node_exporter   15 seconds ago   Up 15 seconds             0.0.0.0:9100->9100/tcp, [::]:9100->9100/tcp
prometheus      hb.reg.com/monitor/prometheus:v3.9.1       "/bin/prometheus --c…"   prometheus      15 seconds ago   Up 14 seconds             0.0.0.0:9090->9090/tcp, [::]:9090->9090/tcp
[root@localhost jk]# 
五、页面及功能测试
1、Prometheus:**9090 ** 节点健康测试

Prometheus 页面 Status-Targets:所有 Job 状态为 UP,指标采集正常;
在这里插入图片描述

2.node_exporter:9100 节点探测功能测试

node-exporter 页面可直接查看宿主机 CPU、内存、磁盘原始监控数据;

在这里插入图片描述

3.cadvisor:8080 容器信息监控测试

cAdvisor 页面展示本机全部容器资源消耗、IO、网络详情;
在这里插入图片描述

4.Grafana:3000 可视化大屏测试

Grafana 登录后可添加 Prometheus 数据源,导入主机 / 容器监控大盘,可视化展示曲线;
在这里插入图片描述

5.altermanager告警测试

告警功能验证:手动停止 node-exporter 容器,等待 10 秒触发失联告警,QQ 邮箱收到 Critical 告警邮件;恢复容器后自动推送告警恢复通知,告警链路完全通。

在这里插入图片描述

通过事先设置的QQ邮箱可以看到,成功收到服务异常告警和恢复通知

至此全链路打通。

六、方案整体总结与拓展

架构完整性:本方案分为私有镜像仓库、指标采集、时序存储、可视化告警四层,覆盖容器镜像全生命周期管理 + 服务器 / 容器全维度监控,一套环境解决镜像私有化、系统观测、异常告警三大运维核心需求,无技术断层;

离线可落地:基于 Harbor 私有仓库统一托管所有业务与监控镜像,整套环境不依赖公网,内网隔离机房、无外网服务器均可完整部署;

运维轻量化:全部组件基于 Docker Compose 编排,标准化配置文件,一键启停、迁移便捷;内置邮件告警机制,故障主动推送,无需人工轮询巡检;

踩坑沉淀:文档完整记录自签证书信任、Grafana 账号锁定、持久化数据密码不同步、时区错乱等高频问题与修复方案,可直接复用至其他项目部署;

适用场景:中小企业私有云、内网测试环境、等保合规机房(禁止公网镜像源、需要漏洞扫描、日志监控审计)。

**Harbor 监控能力:**当前仅采集仓库基础指标,拓展优化:

  1. 对接 Harbor 漏洞扫描指标,新增镜像高危漏洞告警;
  2. 配置镜像存储容量阈值告警,仓库磁盘占比超 80% 触发邮件提醒;

方案横向拓展场景:

Kubernetes 集群适配:当前基于宿主机静态采集,对接 K8s 可新增 kube-state-metrics,自动发现 Pod、Node、Deployment,替换静态 target 配置;

多机房统一监控:多机房各部署一套采集 exporter,远端写入中心 Prometheus/Thanos,实现多机房监控数据统一大屏查看;

业务应用监控:新增应用侧 Exporter(Java Micrometer、Python Prometheus Client),采集业务接口 QPS、响应耗时、错误率,实现基础设施 + 业务全链路监控。

更多推荐