Harbor 私有镜像仓库
大约 11 分钟约 3161 字
Harbor 私有镜像仓库
简介
Harbor 是由 VMware 开源的企业级 Docker/OCI 镜像仓库,在原生 Docker Distribution 的基础上增加了 RBAC 权限控制、镜像复制、漏洞扫描、镜像签名等企业级功能。Harbor 通过 Docker Compose 或 Helm Chart 部署,广泛用于企业内部的容器镜像管理,是构建安全可靠的容器供应链的核心组件。
特点
安装部署
Docker Compose 方式安装
# 下载Harbor离线安装包
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
# 解压安装包
tar -zxvf harbor-offline-installer-v2.10.0.tgz
cd harbor
# 复制并编辑配置文件
cp harbor.yml.tmpl harbor.yml
# 编辑harbor.yml主要配置项
# hostname: harbor.example.com
# http:
# port: 80
# https:
# port: 443
# certificate: /data/cert/harbor.crt
# private_key: /data/cert/harbor.key
# harbor_admin_password: Harbor12345
# data_volume: /data/harbor
# 执行安装(包含Trivy扫描器)
./install.sh --with-trivy
# 查看Harbor组件运行状态
docker-compose ps
# 停止和启动Harbor
docker-compose down
docker-compose up -d生成 HTTPS 证书
# 创建证书目录
mkdir -p /data/cert
cd /data/cert
# 生成CA私钥
openssl genrsa -out ca.key 4096
# 生成CA证书
openssl req -x509 -new -nodes -sha512 -days 3650 \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=HarborCA" \
-key ca.key -out ca.crt
# 生成服务器私钥
openssl genrsa -out harbor.key 4096
# 生成证书签名请求(CSR)
openssl req -sha512 -new \
-subj "/C=CN/ST=Beijing/L=Beijing/O=MyCompany/CN=harbor.example.com" \
-key harbor.key -out harbor.csr
# 生成x509 v3扩展文件
cat > v3.ext << EOF
authorityKeyIdentifier=keyid,issuer
basicConstraints=CA:FALSE
keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names
[alt_names]
DNS.1=harbor.example.com
DNS.2=harbor
IP.1=192.168.1.100
EOF
# 签发服务器证书
openssl x509 -req -sha512 -days 3650 \
-extfile v3.ext -CA ca.crt -CAkey ca.key -CAcreateserial \
-in harbor.csr -out harbor.crt项目与镜像管理
项目管理操作
# 登录Harbor仓库
docker login harbor.example.com
# 创建项目(通过Harbor API)
curl -X POST "https://harbor.example.com/api/v2.0/projects" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"project_name": "myapp",
"public": false,
"metadata": {
"auto_scan": "true",
"reuse_sys_cve_allowlist": "true"
}
}'
# 查看所有项目
curl -X GET "https://harbor.example.com/api/v2.0/projects" \
-u "admin:Harbor12345" | python3 -m json.tool
# 推送镜像到指定项目
docker tag nginx:latest harbor.example.com/myapp/nginx:latest
docker push harbor.example.com/myapp/nginx:latest
# 拉取镜像
docker pull harbor.example.com/myapp/nginx:latest
# 查看项目中的镜像列表
curl -X GET "https://harbor.example.com/api/v2.0/projects/myapp/repositories" \
-u "admin:Harbor12345" | python3 -m json.tool镜像标签与垃圾回收
# 设置镜像标签保留策略(保留最近10个标签)
curl -X PUT "https://harbor.example.com/api/v2.0/projects/myapp/retention" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"algorithm": "or",
"rules": [{
"action": "retain",
"params": {"latest_pulled": 10},
"scope_selectors": {
"repository": [{"kind": "doublestar", "pattern": "**"}]
},
"tag_selectors": [{
"kind": "doublestar",
"pattern": "**",
"decoration": "matches"
}],
"template": "latestPulledN"
}],
"trigger": {"type": "Schedule", "trigger_setting": {"cron": "0 0 4 * * *"}}
}'
# 手动触发垃圾回收(需要先停止Harbor)
docker-compose stop
docker run -it --rm -v /data/harbor:/data -v /etc/docker/daemon.json:/etc/docker/daemon.json \
goharbor/registry-photon:v2.10.0 garbage-collect \
/etc/registry/config.yml
docker-compose up -dRBAC 权限管理
用户与角色配置
Harbor 的角色体系分为系统级和项目级两个层次:
| 角色级别 | 角色 | 权限说明 |
|---|---|---|
| 系统级 | 系统管理员 | 管理所有项目、用户、系统配置 |
| 系统级 | 审计员 | 查看所有操作日志 |
| 项目级 | 项目管理员 | 管理项目成员和配置 |
| 项目级 | 开发者 | 推送和拉取镜像 |
| 项目级 | 访客 | 仅拉取镜像 |
| 项目级 | 受限访客 | 仅拉取镜像(无法查看标签详情) |
# 创建用户(通过API)
curl -X POST "https://harbor.example.com/api/v2.0/users" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"username": "devuser",
"email": "dev@example.com",
"realname": "Dev User",
"password": "DevPass123!",
"comment": "开发环境用户"
}'
# 添加项目成员并分配角色
curl -X POST "https://harbor.example.com/api/v2.0/projects/myapp/members" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"role_id": 2,
"member_user": {"username": "devuser"}
}'
# role_id: 1=项目管理员, 2=开发者, 3=访客, 4=受限访客镜像复制
跨仓库同步配置
# 创建目标仓库(Registry端点)
curl -X POST "https://harbor.example.com/api/v2.0/registries" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "remote-harbor",
"type": "harbor",
"url": "https://harbor-dr.example.com",
"credential": {
"type": "basic",
"access_key": "admin",
"access_secret": "RemotePass123!"
}
}'
# 创建复制策略
curl -X POST "https://harbor.example.com/api/v2.0/replication/policies" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"name": "sync-to-dr",
"src_registry": {"id": 1},
"dest_registry": {"id": 2},
"trigger": {
"type": "scheduled",
"trigger_settings": {"cron": "0 0 2 * * *"}
},
"filters": [{"type": "name", "value": "myapp/**"}],
"deletion": false,
"override": true
}'
# 手动触发复制
curl -X POST "https://harbor.example.com/api/v2.0/replication/executions" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{"policy_id": 1}'漏洞扫描
配置与使用 Trivy 扫描
# 手动触发项目级漏洞扫描
curl -X POST "https://harbor.example.com/api/v2.0/projects/myapp/scanner" \
-u "admin:Harbor12345"
# 扫描指定镜像
curl -X POST "https://harbor.example.com/api/v2.0/projects/myapp/repositories/nginx/artifacts/latest/scan" \
-u "admin:Harbor12345"
# 查看扫描结果
curl -X GET "https://harbor.example.com/api/v2.0/projects/myapp/repositories/nginx/artifacts/latest/additions/vulnerabilities" \
-u "admin:Harbor12345" | python3 -m json.tool
# 查看扫描器状态
curl -X GET "https://harbor.example.com/api/v2.0/scanners" \
-u "admin:Harbor12345"
# 配置项目自动扫描(推送后自动扫描)
curl -X PUT "https://harbor.example.com/api/v2.0/projects/myapp" \
-H "Content-Type: application/json" \
-u "admin:Harbor12345" \
-d '{
"metadata": {
"auto_scan": "true",
"severity": "high"
}
}'Harbor 高可用部署
主从复制架构
# 主 Harbor 配置
# harbor.yml (主节点)
hostname: harbor-primary.example.com
https:
port: 443
certificate: /data/cert/harbor.crt
private_key: /data/cert/harbor.key
harbor_admin_password: Harbor12345
data_volume: /data/harbor
# 从 Harbor 配置
# harbor.yml (从节点)
hostname: harbor-secondary.example.com
https:
port: 443
certificate: /data/cert/harbor.crt
private_key: /data/cert/harbor.key
harbor_admin_password: Harbor12345
data_volume: /data/harbor
# 在主节点配置数据库外部访问
# 编辑 /data/harbor/docker-compose.yml 中的 postgresql 配置
# 确保 postgresql 监听外部连接数据库外部化(高可用前提)
# 1. 使用外部 PostgreSQL 替代内置数据库
# 编辑 harbor.yml
database:
type: external
host: postgres-ha.example.com
port: 5432
username: harbor
password: HarborDB123!
core_database: registry
notaryserver_database: notaryserver
notarysigner_database: notarysigner
sslmode: disable
# 2. 使用外部 Redis 替代内置 Redis
redis:
type: external
addr: redis-ha.example.com:6379
password: RedisPass123!
db_index: 0
# 3. 使用外部存储(S3/MinIO)
storage_service:
s3:
accesskey: minioadmin
secretkey: minioadmin123
region: us-east-1
regionendpoint: https://minio.example.com:9000
bucket: harbor
secure: true
v4auth: trueHarbor 备份与恢复
#!/bin/bash
# harbor_backup.sh — Harbor 完整备份脚本
BACKUP_DIR="/backup/harbor"
DATE=$(date +%Y%m%d_%H%M%S)
HARBOR_DIR="/data/harbor"
# 停止 Harbor 服务
cd /opt/harbor
docker-compose stop
# 备份数据目录
echo "备份 Harbor 数据..."
tar czf ${BACKUP_DIR}/harbor_data_${DATE}.tar.gz -C /data harbor
# 备份数据库(如果使用内置数据库)
echo "备份数据库..."
docker-compose start postgresql
sleep 10
docker exec harbor-db pg_dump -U postgres registry > ${BACKUP_DIR}/registry_${DATE}.sql
docker exec harbor-db pg_dump -U postgres notaryserver > ${BACKUP_DIR}/notaryserver_${DATE}.sql
docker exec harbor-db pg_dump -U postgres notarysigner > ${BACKUP_DIR}/notarysigner_${DATE}.sql
docker-compose stop
# 备份配置文件
cp /opt/harbor/harbor.yml ${BACKUP_DIR}/harbor.yml_${DATE}
# 启动 Harbor
docker-compose up -d
# 清理超过 7 天的备份
find ${BACKUP_DIR} -name "harbor_*" -mtime +7 -delete
echo "备份完成: ${BACKUP_DIR}/harbor_data_${DATE}.tar.gz"# 恢复步骤
# 1. 停止 Harbor
cd /opt/harbor
docker-compose down
# 2. 恢复数据目录
tar xzf /backup/harbor/harbor_data_20260414.tar.gz -C /data/
# 3. 恢复数据库(如果使用内置数据库)
docker-compose up -d postgresql redis
sleep 15
cat /backup/harbor/registry_20260414.sql | docker exec -i harbor-db psql -U postgres registry
cat /backup/harbor/notaryserver_20260414.sql | docker exec -i harbor-db psql -U postgres notaryserver
cat /backup/harbor/notarysigner_20260414.sql | docker exec -i harbor-db psql -U postgres notarysigner
# 4. 启动所有服务
docker-compose up -dHarbor 升级
# 升级步骤(以 2.9 升级到 2.10 为例)
cd /opt
# 1. 备份
./harbor_backup.sh
# 2. 下载新版本
wget https://github.com/goharbor/harbor/releases/download/v2.10.0/harbor-offline-installer-v2.10.0.tgz
tar -zxvf harbor-offline-installer-v2.10.0.tgz
# 3. 停止旧版本
cd harbor
docker-compose down
# 4. 迁移数据
# 先解压新版本的 harbor 目录
cd /opt/harbor
cp harbor.yml /opt/harbor-new/harbor.yml
cd /opt/harbor-new
./prepare
# 运行迁移工具
docker run -it --rm -v /data/harbor:/data \
goharbor/harbor-migrator:v2.10.0 --up
# 如果版本跨度大,可能需要先执行中间版本的迁移
# 5. 安装新版本
./install.sh --with-trivy
# 6. 验证
docker-compose ps
curl -k https://harbor.example.com/api/v2.0/systeminfo客户端配置
Docker 客户端信任 Harbor
# 方法一:将 Harbor CA 证书加入系统信任
cp /data/cert/ca.crt /etc/pki/ca-trust/source/anchors/
update-ca-trust
systemctl restart docker
# 方法二:配置 Docker daemon 信任 insecure registry
cat > /etc/docker/daemon.json << 'EOF'
{
"insecure-registries": ["harbor.example.com"],
"registry-mirrors": ["https://harbor.example.com"]
}
EOF
systemctl restart docker
# 方法三:在每台客户端上登录
docker login harbor.example.com -u admin -p Harbor12345
# 非交互式登录(适用于 CI/CD 脚本)
echo "Harbor12345" | docker login harbor.example.com -u admin --password-stdin
# 查看已登录的仓库
cat ~/.docker/config.jsonHelm Chart 管理(Harbor 支持)
# 推送 Helm Chart 到 Harbor
# 安装 helm-push 插件
helm plugin install https://github.com/chartmuseum/helm-push.git
# 添加 Harbor Helm 仓库
helm repo add myrepo https://harbor.example.com/chartrepo/myapp \
--username admin --password Harbor12345
# 推送 Chart
helm push mychart-1.0.0.tgz myrepo
# 搜索 Chart
helm search repo myrepoHarbor 运维排障
常见问题排查
# 查看 Harbor 各组件日志
cd /opt/harbor
docker-compose logs -f core # Harbor 核心服务
docker-compose logs -f registry # 镜像仓库
docker-compose logs -f portal # Web UI
docker-compose logs -f trivy # 漏洞扫描
docker-compose logs -f postgresql # 数据库
docker-compose logs -f redis # 缓存
# 常见问题 1:镜像推送失败 — 502 Bad Gateway
# 原因:registry 服务异常
docker-compose restart registry
docker-compose logs --tail=50 registry
# 常见问题 2:登录失败 — 401 Unauthorized
# 原因:密码错误或 LDAP 认证失败
docker-compose logs --tail=50 core
# 常见问题 3:证书问题 — x509: certificate signed by unknown authority
# 解决:将 CA 证书添加到系统信任存储
cp /data/cert/ca.crt /etc/pki/ca-trust/source/anchors/harbor-ca.crt
update-ca-trust
systemctl restart docker
# 常见问题 4:磁盘空间不足
# 执行垃圾回收
docker-compose stop
docker run -it --rm -v /data/harbor:/data \
goharbor/registry-photon:v2.10.0 \
garbage-collect /etc/registry/config.yml
docker-compose up -d
# 健康检查
curl -k https://harbor.example.com/api/v2.0/systeminfo | python3 -m json.toolHarbor 监控指标
# 通过 API 获取系统信息
curl -k -u admin:Harbor12345 \
https://harbor.example.com/api/v2.0/systeminfo
# 查看磁盘使用情况
curl -k -u admin:Harbor12345 \
https://harbor.example.com/api/v2.0/system/gc
# 获取项目统计
curl -k -u admin:Harbor12345 \
"https://harbor.example.com/api/v2.0/statistics"
# 查看最近的操作日志(审计)
curl -k -u admin:Harbor12345 \
"https://harbor.example.com/api/v2.0/audit-logs?page_size=20"优点
缺点
总结
Harbor 是目前最流行的企业级私有镜像仓库之一,凭借完善的项目管理、RBAC 权限、镜像复制和漏洞扫描功能,能够满足大多数企业的容器镜像管理需求。建议在生产环境中启用 HTTPS、配置自动扫描策略、定期执行垃圾回收,并结合镜像签名和不可变标签功能,构建安全的容器镜像供应链。
关键知识点
- 部署类主题的核心不是“装成功”,而是“稳定运行、可排障、可回滚”。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
- 部署主题通常要同时看镜像、容器、卷、网络和宿主机资源。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
- 固定镜像标签,记录端口、挂载目录、环境变量和自启动策略。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
- 使用 latest 导致结果不可复现。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
- 继续补齐 Compose 编排、镜像瘦身、安全扫描和镜像仓库治理。
适用场景
- 当你准备把《Harbor 私有镜像仓库》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
落地建议
- 固定版本号与镜像标签,避免“latest”带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
复盘问题
- 如果把《Harbor 私有镜像仓库》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《Harbor 私有镜像仓库》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《Harbor 私有镜像仓库》最大的收益和代价分别是什么?
