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

九、生产建议
- 密码:替换文中所有示例密码
- PostgreSQL:建议独立部署并做主从 + VIP,Harbor 只连主库
- Redis:生产环境使用 Sentinel 或 Cluster
- 证书:使用企业 CA 或 Let's Encrypt,避免自签
- 备份:每日备份 PostgreSQL + NFS 快照
- 升级:滚动升级,先停一台 → 升级 → 验证 → 再升级另一台
- 防火墙:5432、6379、NFS 端口仅内网开放
十、总结
Harbor 高可用的关键不在于「双主写数据库」,而在于:
- 元数据集中:外部 PostgreSQL
- 会话缓存集中:外部 Redis
- 镜像数据共享:NFS / 对象存储
- 入口统一:Nginx 负载均衡
- 配置一致:两台 Harbor 使用相同域名、证书和后端地址