← Back to list
2026-06-26T09:48:47.928ZHarboarLinuxDocker

Harboar双主复制+Redis+PostgreSQL,搭建企业级私有镜像库

搭建企业级私有镜像库

生产环境落地的 Harbor 高可用方案:两台 Harbor 节点共享外部 PostgreSQL、Redis 与 NFS 存储,前端由 Nginx 做负载均衡。

一、架构概览

Harbor 的数据分为两类:

数据类型 存储位置 说明
元数据(项目、用户、权限、Artifact 索引等) PostgreSQL 可外部化
镜像 Blob(层文件、Chart 包等) NFS / MinIO / S3 不能存入 PostgreSQL

推荐拓扑如下:

                    ┌─────────────────┐
                    │  Docker Nginx   │
                    │  (负载均衡入口)   │
                    └────────┬────────┘
                             │
              ┌──────────────┴──────────────┐
              │                             │
     ┌────────▼────────┐           ┌────────▼────────┐
     │   Harbor Node 1 │           │   Harbor Node 2 │
     └────────┬────────┘           └────────┬────────┘
              │                             │
              └──────────────┬──────────────┘
                             │
         ┌───────────────────┼───────────────────┐
         │                   │                   │
  ┌──────▼──────┐    ┌───────▼───────┐   ┌──────▼──────┐
  │ PostgreSQL  │    │     Redis     │   │  NFS 共享存储 │
  │  (Docker)   │    │   (Docker)    │   │  (Blob)     │
  └─────────────┘    └───────────────┘   └─────────────┘

核心原则:

  • 两台 Harbor 使用相同域名相同证书
  • 连接同一套 PostgreSQL、Redis、NFS
  • 客户端只访问 Nginx VIP/域名,不直连 Harbor 节点

二、环境规划

角色 主机名 IP 示例
Nginx LB lb01 192.168.121.175
Harbor-1 harbor01 192.168.121.176
Harbor-2 harbor02 192.168.121.177
PostgreSQL + Redis db01 192.168.121.176(可与 Harbor 同机,生产建议独立)
NFS 存储 storage01 192.168.121.178

域名:harbor.example.com → 解析到 Nginx 节点 IP


三、使用 Docker 部署 PostgreSQL + Redis

3.1 创建目录

sudo mkdir -p /opt/redis+postgres
cd /opt/redis+postgres

sudo mkdir -p /opt/redis+postgres/conf

conf/redis.conf

bind 0.0.0.0
port 6379
protected-mode yes
requirepass Redis@StrongPass
appendonly yes
appendfsync everysec
dir /data
maxmemory 1024gb
maxmemory-policy allkeys-lru

3.2 初始化脚本 init/01-init-harbor.sql

CREATE USER harbor WITH PASSWORD 'HarborDB@StrongPass';
CREATE DATABASE registry OWNER harbor ENCODING 'UTF8';
GRANT ALL PRIVILEGES ON DATABASE registry TO harbor;

\c registry
GRANT ALL ON SCHEMA public TO harbor;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON TABLES TO harbor;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT ALL ON SEQUENCES TO harbor;

3.3 docker-compose.yml

services:
  postgres:
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/postgres:14-alpine
    container_name: harbor-postgres
    restart: always
    environment:
      POSTGRES_PASSWORD: Postgres@RootPass  # 默认 postgres 用户密码
    ports:
      - "5432:5432"
    volumes:
      - ./postgres/data:/var/lib/postgresql/data
      - ./postgres/init:/docker-entrypoint-initdb.d  # 初始化脚本目录
    networks:
      - harbor-backend

  redis:
    image: swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/redis:7-alpine
    container_name: harbor-redis
    restart: always
    ports:
      - "6379:6379"
    volumes:
      - ./redis/data:/data
      - ./conf/redis.conf:/usr/local/etc/redis/redis.conf  # 自定义配置文件
    command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
    networks:
      - harbor-backend

networks:
  harbor-backend:
    driver: bridge

3.4 启动与验证

docker compose up -d
docker exec -it harbor-postgres psql -U harbor -d registry -c "SELECT 1;"

docker exec -it harbor-redis redis-cli -a Redis@StrongPass ping
# 返回 PONG

五、配置 NFS 共享存储

镜像 Blob 必须放在共享存储上,两台 Harbor 挂载同一个 NFS 路径

5.1 NFS 服务端(storage01)

sudo apt install -y nfs-kernel-server
sudo mkdir -p /data/harbor/registry
sudo chown -R 10000:10000 /data/harbor/registry

echo "/data/harbor/registry 192.168.121.176(rw,sync,no_subtree_check,no_root_squash) \
192.168.121.177(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports

sudo exportfs -ra
sudo systemctl enable --now nfs-kernel-server

5.2 Harbor 节点挂载(两台都执行)

sudo apt install -y nfs-common
sudo mkdir -p /data/harbor

# storage01 替换为 NFS 服务器 IP 或能解析的主机名
sudo mount -t nfs 192.168.121.178:/data/harbor/registry /data/harbor

# 开机自动挂载
echo "192.168.121.178:/data/harbor/registry  /data/harbor  nfs  defaults,_netdev  0  0" | sudo tee -a /etc/fstab

验证:

df -h | grep harbor

六、安装 Harbor(双节点)

6.1 安装依赖

sudo apt update
sudo apt install -y docker.io docker-compose-v2 docker-compose openssl
sudo systemctl enable --now docker

6.2 下载 Harbor

cd /opt
wget https://github.com/goharbor/harbor/releases/download/v2.10.3/harbor-offline-installer-v2.10.3.tgz
tar xzf harbor-offline-installer-v2.10.3.tgz
cd harbor
cp harbor.yml.tmpl harbor.yml

6.3 生成 SSL 证书

第一台 Harbor 生成,然后复制到第二台(两台必须用同一套证书):

sudo mkdir -p /data/cert
openssl req -newkey rsa:4096 -nodes -sha256 \
  -keyout /data/cert/harbor.key \
  -x509 -days 3650 \
  -out /data/cert/harbor.crt \
  -subj "/CN=harbor.example.com" \
  -addext "subjectAltName=DNS:harbor.example.com"

sudo chmod 600 /data/cert/harbor.key

复制到第二台:

scp /data/cert/harbor.{crt,key} root@192.168.121.177:/data/cert/

6.4 配置 harbor.yml(关键)

⚠️ 常见坑external_database 必须嵌套 harbor: 字段,否则会报 KeyError: 'harbor'

hostname: harbor.example.com

https:
  port: 443
  certificate: /data/cert/harbor.crt
  private_key: /data/cert/harbor.key

# 内置数据库必须注释掉
# database:
#   password: root123

external_database:
  harbor:
    host: 192.168.121.176
    port: 5432
    db_name: registry
    username: harbor
    password: HarborDB@StrongPass
    ssl_mode: disable
    max_idle_conns: 100
    max_open_conns: 900

external_redis:
  host: 192.168.121.176
  port: 6379
  password: Redis@StrongPass

data_volume: /data/harbor

harbor_admin_password: Harbor12345

log:
  level: info
  local:
    rotate_count: 50
    rotate_size: 200M
    location: /var/log/harbor

错误写法(会报错):

external_database:
  host: 192.168.121.176    # ❌ 缺少 harbor: 层级
  port: 5432

正确写法:

external_database:
  harbor:                  # ✅ 必须有这一层
    host: 192.168.121.176
    port: 5432

6.5 安装顺序

先装第一台,确认正常后再装第二台:

cd /opt/harbor
sudo ./install.sh

验证:

docker compose ps
curl -k https://127.0.0.1/api/v2.0/health

七、Docker Compose 部署 Nginx 负载均衡

7.1 目录结构

/opt/harbor-nginx/
├── docker-compose.yml
├── conf.d/
│   └── harbor.conf
├── ssl/
│   ├── harbor.crt
│   └── harbor.key
└── logs/

7.2 docker-compose.yml

services:
  nginx:
    image: nginx:1.25-alpine
    container_name: harbor-lb
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./conf.d:/etc/nginx/conf.d:ro
      - ./ssl:/etc/nginx/ssl:ro
      - ./logs:/var/log/nginx
    healthcheck:
      test: ["CMD", "wget", "-q", "--spider", "http://127.0.0.1/healthz"]
      interval: 10s
      timeout: 5s
      retries: 3
    networks:
      - harbor-lb

networks:
  harbor-lb:
    driver: bridge

7.3 conf.d/harbor.conf

upstream harbor_backend {
    ip_hash;
    server 192.168.121.176:443 max_fails=3 fail_timeout=30s;
    server 192.168.121.177:443 max_fails=3 fail_timeout=30s;
}

server {
    listen 80;
    server_name _;

    location = /healthz {
        access_log off;
        return 200 "ok\n";
        add_header Content-Type text/plain;
    }
}

server {
    listen 80;
    server_name harbor.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name harbor.example.com;

    ssl_certificate     /etc/nginx/ssl/harbor.crt;
    ssl_certificate_key /etc/nginx/ssl/harbor.key;
    ssl_protocols       TLSv1.2 TLSv1.3;

    client_max_body_size 0;
    proxy_buffering off;
    proxy_request_buffering off;

    location / {
        proxy_pass https://harbor_backend;
        proxy_ssl_verify off;
        proxy_ssl_server_name on;

        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;

        proxy_connect_timeout 300;
        proxy_send_timeout 300;
        proxy_read_timeout 300;
    }

    location /v2/ {
        proxy_pass https://harbor_backend;
        proxy_ssl_verify off;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        client_max_body_size 0;
    }
}

8.4 启动

cd /opt/harbor-nginx
cp /data/cert/harbor.crt ssl/
cp /data/cert/harbor.key ssl/
chmod 600 ssl/harbor.key

docker compose up -d
docker compose logs -f nginx

《Harboar双主复制+Redis+PostgreSQL,搭建企业级私有镜像库》文章正文配图 — STARBUCKET BLOG

九、生产建议

  1. 密码:替换文中所有示例密码
  2. PostgreSQL:建议独立部署并做主从 + VIP,Harbor 只连主库
  3. Redis:生产环境使用 Sentinel 或 Cluster
  4. 证书:使用企业 CA 或 Let's Encrypt,避免自签
  5. 备份:每日备份 PostgreSQL + NFS 快照
  6. 升级:滚动升级,先停一台 → 升级 → 验证 → 再升级另一台
  7. 防火墙:5432、6379、NFS 端口仅内网开放

十、总结

Harbor 高可用的关键不在于「双主写数据库」,而在于:

  • 元数据集中:外部 PostgreSQL
  • 会话缓存集中:外部 Redis
  • 镜像数据共享:NFS / 对象存储
  • 入口统一:Nginx 负载均衡
  • 配置一致:两台 Harbor 使用相同域名、证书和后端地址

Comments & discussion

The first comment in each thread opens a topic. Signed-in readers can keep the conversation going under that topic.

No comments yet. Sign in to start a topic.

Start a new topic

Sign in to start a topic or join the discussion.