Harbor 私有镜像仓库建设与 CI/CD 集成

一、架构选型与场景定位

在容器化落地过程中,私有镜像仓库是核心基础设施。根据业务规模与安全合规要求,通常面临两种选择:轻量级的官方 Docker Registry 与企业级的 Harbor

Docker Registry 适合作为学习实验、临时中转站或边缘节点的缓存层。它的优势在于极简部署,但功能单一,缺乏用户界面和细粒度的权限控制。特别是在生产环境中,其镜像清理机制存在明显短板——删除镜像后元数据仍驻留内存,往往需要重启容器才能释放空间,这种“中断式”维护在生产环境是不可接受的。此外,默认配置下它仅支持 HTTP 明文传输,存在数据泄露风险。

Harbor 则是云原生时代的企业级标准。它提供了完善的 Web UI、基于角色的访问控制(RBAC)、镜像漏洞扫描以及审计日志。对于核心业务集群,必须采用 Harbor 来保障供应链安全。它支持自动垃圾回收(GC),无需重启服务即可清理磁盘空间,并原生支持 HTTPS 和高可用架构。

结论:测试环境可快速搭建 Registry 验证流程,但生产环境必须部署 Harbor,且需严格配置 HTTPS 与外部存储,杜绝单点故障与明文传输。


二、轻量级 Registry 的标准化部署(测试/边缘场景)

虽然 Registry 不适合核心生产区,但在内网隔离区或 CI 测试环节仍有应用价值。部署时需重点解决数据持久化与清理机制问题。

1. 部署配置优化

直接使用 docker run 容易导致配置分散且难以维护,推荐采用 docker-compose 进行标准化管理。关键在于开启删除功能并挂载数据卷,防止容器移除后数据丢失。

# docker-compose-registry.yml
version: '3'
services:
  registry:
    image: registry:2.8.3
    container_name: local-registry
    restart: always
    ports:
      - "5000:5000"
    environment:
      # 必须显式开启删除功能,否则 API 拒绝删除请求
      - REGISTRY_STORAGE_DELETE_ENABLED=true
      - REGISTRY_HTTP_ADDR=0.0.0.0:5000
    volumes:
      - ./data:/var/lib/registry  # 数据持久化,解耦容器生命周期
      - ./config:/etc/docker/registry
    # 生产建议:实际使用中应前置 Nginx 反向代理,由 Nginx 处理 HTTPS 证书与基本认证

2. 镜像清理的正确姿势

在实际操作中,直接调用 API 删除镜像后,磁盘空间往往不会立即释放。这是因为 Registry 进程将元数据缓存在内存中。传统的“重启容器”方案会导致服务中断,不符合运维连续性要求。

标准的处理流程是执行垃圾回收(Garbage Collection)并触发配置重载。若版本不支持热重载,则采用滚动更新策略,确保服务不中断:

# 第一步:执行垃圾回收,清理未被引用的镜像层
docker exec -it local-registry registry garbage-collect --delete-untagged /etc/docker/registry/config.yml

# 第二步:若空间未释放,使用 docker-compose 进行滚动重启(而非直接 kill/restart)
# 这将重新拉起容器并加载最新的文件系统状态,实现零停机维护
docker-compose up -d --force-recreate --no-deps registry

三、Harbor 企业级部署与自动化实践

Harbor 的部署复杂度远高于 Registry,涉及数据库、Redis、核心服务及存储等多个组件。在生产环境落地时,版本稳定性、数据安全与网络配置是三大核心考量。

1. 关键配置策略

  • 版本锁定:避免盲目追求最新版。例如 v2.15.0 曾存在已知缺陷,生产环境建议锁定在 v2.14.x LTS 版本或经官方验证的最新稳定版。
  • 存储规划:默认配置将数据存放在 /var/lib/harbor,这极易导致宿主机根分区爆满。必须将 data_volume 挂载至独立的数据盘、NFS 或对象存储(如 S3/Ceph),确保镜像数据与系统盘分离。
  • 强制 HTTPS:生产环境严禁使用 insecure-registries 绕过证书验证。必须申请合法 SSL 证书(或企业内部 CA 签发的受信任证书),并在 harbor.yml 中启用 HTTPS 端口。

2. 自动化部署脚本

手动修改配置文件容易出错且难以复用。以下脚本实现了预检、备份、配置自动生成及安装的一体化流程,特别强化了密码管理与端口检查。

#!/bin/bash
set -e

HARBOR_VERSION="v2.14.0"
DATA_DIR="/data/harbor"
CERT_DIR="/etc/harbor/ssl"

echo ">>> 开始预检..."
# 检查关键端口占用,避免与现有 Nginx 或其他服务冲突
for port in 80 443 4443; do
    if ss -ntl | grep -q ":$port "; then
        echo "错误:端口 $port 已被占用,请先停止相关服务。"
        exit 1
    fi
done

# 备份旧配置(升级场景)
if [ -d "/usr/local/harbor" ]; then
    cp -r /usr/local/harbor/harbor.yml /usr/local/harbor/harbor.yml.bak.$(date +%F)
fi

echo ">>> 生成配置文件..."
cd /usr/local/harbor
cp harbor.yml.tmpl harbor.yml

# 自动化替换关键参数
sed -i "s/hostname: reg.mydomain.com/hostname: harbor.corp.local/" harbor.yml
sed -i "s|# https:|https:|" harbor.yml
sed -i "s|#   port: 443|  port: 443|" harbor.yml
sed -i "s|#   certificate:|  certificate: $CERT_DIR/server.crt|" harbor.yml
sed -i "s|#   private_key:|  private_key: $CERT_DIR/server.key|" harbor.yml

# 安全提示:生产环境严禁在脚本中硬编码密码。
# 此处建议使用环境变量传入,或在安装时交互式输入
ADMIN_PWD="${HARBOR_ADMIN_PWD:-StrongP@ssw0rd}" 
sed -i "s/harbor_admin_password: Harbor12345/harbor_admin_password: $ADMIN_PWD/" harbor.yml

echo ">>> 执行安装..."
./prepare
# 建议开启 Trivy 漏洞扫描与 Chartmuseum Helm 仓库支持
./install.sh --with-trivy --with-chartmuseum

echo "Harbor 部署完成,访问地址:https://harbor.corp.local"

四、初始化配置:从可视化操作到自动化交付

部署完成 Harbor 服务只是第一步。许多初学者习惯登录 Web 界面手动下载证书、点击创建项目,这种“手工坊”模式在测试环境尚可,但在生产环境中效率低下且难以审计。成熟的运维体系应将证书分发项目创建纳入自动化流程。

1. 根证书的分发与信任(替代手动下载)

若使用自签名证书,所有客户端(K8s 节点、CI 构建机)必须信任该证书。手动在网页下载 ca.crt 再逐台复制不仅繁琐,还容易遗漏。

自动化分发逻辑
直接从运行中的 Harbor Nginx 容器提取证书,并分发至客户端的标准信任目录 /etc/docker/certs.d/<域名>/,随后重启 Docker 守护进程。

# 在任意需要连接 Harbor 的客户端节点执行
HARBOR_DOMAIN="harbor.corp.local"
CERT_DIR="/etc/docker/certs.d/${HARBOR_DOMAIN}"

# 1. 创建证书目录
mkdir -p ${CERT_DIR}

# 2. 从 Harbor 服务器提取证书 (假设已配置 SSH 免密或直接在本机)
# 这里演示从本地运行的 harbor-nginx 容器直接拷贝,避免网页下载步骤
docker cp harbor-nginx:/etc/nginx/cert/server.crt ${CERT_DIR}/ca.crt

# 3. 重启 Docker 使证书生效
systemctl restart docker

# 4. 验证信任
docker login https://${HARBOR_DOMAIN}

注:若未执行此步,客户端将报 x509: certificate signed by unknown authority 错误。

2. 项目空间的自动化创建(替代网页点击)

Harbor 的核心概念是“项目(Project)”,用于隔离镜像资源。手动在网页点击“新建项目”无法适应微服务快速迭代的节奏,也无法通过代码管理权限变更。

API 自动化创建方案
利用 Harbor API 替代鼠标点击,可实现批量创建、权限预设及与 CI/CD 流水线的联动。

#!/bin/bash
# create-harbor-project.sh

HARBOR_URL="https://harbor.corp.local"
USER="admin"
PASSWORD="${HARBOR_ADMIN_PWD}" # 从环境变量获取,严禁硬编码
PROJECT_NAME="oldboyedu-lb"

echo "正在通过 API 创建项目:${PROJECT_NAME} ..."

# 调用 Harbor v2.0+ API 创建私有项目
curl -k -X POST "${HARBOR_URL}/api/v2.0/projects" \
  -u "${USER}:${PASSWORD}" \
  -H "Content-Type: application/json" \
  -d "{
    \"project_name\": \"${PROJECT_NAME}\",
    \"public\": false,
    \"metadata\": {
      \"auto_scan\": true, 
      \"enable_content_trust\": false
    },
    \"storage_limit\": -1, 
    \"registry_id\": null
  }"

if [ $? -eq 0 ]; then
  echo "项目 ${PROJECT_NAME} 创建成功,立即可用。"
  # 可选:在此处继续调用 API 创建 Robot Account 供 CI 使用
else
  echo "项目创建失败,请检查是否已存在或认证信息。"
fi

通过这种方式,我们将原本需要在可视化窗口进行的“下载文件”、“点击创建”等操作,转化为可版本控制的脚本,确保了环境的一致性。


五、CI/CD 集成与安全推送

在流水线中集成镜像推送时,安全性与脚本的健壮性至关重要。许多初级脚本习惯将密码明文写在命令中,或通过 docker login -p 直接传递密码,这会在 history 记录或进程列表中留下安全隐患。

1. 安全的推送脚本

最佳实践是利用 --password-stdin 参数,通过管道传递密码,避免密码出现在命令行参数中。同时,脚本应具备严格的错误退出机制(set -e),防止构建失败后仍执行推送。

#!/bin/bash
set -e

REGISTRY_URL="harbor.corp.local"
PROJECT="oldboyedu-lb"
IMAGE_NAME="homework"
# 优先使用 CI 环境变量作为版本号, fallback 到 latest
VERSION="${BUILD_VERSION:-latest}"

echo "正在登录镜像仓库..."
# 安全登录:密码通过 stdin 传入,不留痕迹
echo "${HARBOR_PASSWORD}" | docker login "$REGISTRY_URL" -u "${HARBOR_USERNAME}" --password-stdin

echo "正在构建镜像..."
docker build \
  --build-arg data="web-${BUILD_NUMBER}" \
  -f web.dockerfile \
  -t "$REGISTRY_URL/$PROJECT/$IMAGE_NAME:$VERSION" \
  .

echo "正在推送镜像..."
docker push "$REGISTRY_URL/$PROJECT/$IMAGE_NAME:$VERSION"

# 清理登录态
docker logout "$REGISTRY_URL"

echo "发布成功:$REGISTRY_URL/$PROJECT/$IMAGE_NAME:$VERSION"

2. Docker Compose 构建联动

在本地或测试环境,可利用 Docker Compose 进行构建验证。注意,生产环境的 push 动作应剥离到 CI 流水线的独立步骤中,Compose 文件主要负责定义构建上下文与镜像标签。

# docker-compose.ci.yml
services:
  app:
    build:
      context: .
      dockerfile: web.dockerfile
      args:
        data: ${DEPLOY_ENV}
    image: harbor.corp.local/oldboyedu-lb/homework:${CI_COMMIT_SHA}
    # 此处仅定义镜像元数据,实际推送由外部脚本控制

六、常见故障排查与避坑指南

在日常运维中,以下几类问题最为高频,需建立标准化的排查思路。

1. HTTP/HTTPS 协议冲突
当客户端配置了 HTTPS 而服务端仅开启 HTTP 时,会报错 http: server gave HTTP response to HTTPS client

  • 解决:若是内网测试环境,需在客户端 /etc/docker/daemon.json 中添加 "insecure-registries": ["ip:port"] 并重启 Docker 守护进程。但在生产环境,正确的做法是服务端配置合法的 SSL 证书,强制启用 HTTPS。

2. 镜像删除后空间未释放
这是 Registry 最常见的“假性”故障。表现为 API 返回删除成功,但 df -h 显示磁盘占用未变。

  • 原因:元数据缓存未刷新。
  • 解决:执行 registry garbage-collect 命令清理孤儿层,随后对容器进行滚动重启以刷新内存状态。切勿直接暴力重启导致服务不可用。

3. 权限拒绝 (Unauthorized)
推送时报 unauthorized to access repository

  • 排查:首先确认 docker login 是否成功;其次检查 Harbor 项目中该用户是否被赋予了 Push 权限(角色是否为 Developer 或 Maintainer);最后确认项目名称是否与 URL 路径完全匹配(Harbor 对项目名大小写敏感)。

4. 启动失败与端口冲突
Harbor 启动卡在 Starting Harbor ...

  • 排查:90% 的情况是 80/443/4443 端口被宿主机其他服务(如 Nginx)占用。使用 ss -ntl 检查端口,调整 Nginx 监听端口或修改 Harbor 配置映射。务必查看 docker-compose logs -f 定位具体报错组件。

生产环境红线

  • 严禁在脚本或配置文件中硬编码明文密码。
  • 严禁在生产集群使用 insecure-registries 绕过证书验证。
  • 严禁将 Harbor 数据目录放在根分区,必须挂载独立存储以防磁盘写满导致节点宕机。
  • 严禁忽略定期 GC 任务,否则软删除的镜像层会迅速耗尽存储空间。

七、高可用架构与监控体系

对于核心业务,单节点 Harbor 无法满足 SLA 要求,需构建高可用架构并纳入统一监控。

1. 高可用 (HA) 设计要点

经典的 HA 方案采用 Keepalived + Nginx 做负载均衡后端挂载多实例 Harbor。但需注意以下深层依赖:

  • 状态外置:Harbor 内部的 PostgreSQL 和 Redis 默认是有状态的。生产环境强烈建议外置数据库与缓存集群(如使用 Patroni 管理的 PG 集群、Redis Sentinel),避免容器重启导致元数据丢失。
  • 存储共享:所有 Harbor 实例必须挂载同一份后端存储(NFS/S3),确保任意节点拉取的镜像数据一致。
  • 会话保持:若未外置 Redis 存储 Session,Nginx 需配置 IP Hash 策略实现会话粘滞,防止用户登录后跳转节点导致鉴权失败。

2. 监控指标体系

利用 Harbor 暴露的 Prometheus 接口,重点关注以下指标并配置告警:

  • 存储容量sum(harbor_project_quota_usage_bytes),当使用率超过 85% 时触发告警,提前扩容。
  • 服务健康up{job="harbor-core"}up{job="harbor-registry"},任何组件宕机立即通知。
  • 推送失败率rate(harbor_http_request_total{status=~"5.."}),监控连续的错误请求,及时发现服务异常。

八、总结与运维口诀

为了便于团队记忆与执行,将上述经验浓缩为以下操作准则:

运维口诀

测试可用 Registry,生产必上 Harbor 站。
HTTPS 证书要配全,存储挂载独立盘。
密码莫写脚本里,Insecure 靠边站。
项目创建调 API,莫在网页点点看。
证书分发自动化,客户端信保平安。
登录善用 Stdin 传,构建标签版本换。
磁盘空间设告警,GC 定期跑一遍。

落地检查清单

  1. 确认 Harbor 版本为官方推荐的稳定版。
  2. SSL 证书已配置且被客户端信任(通过脚本自动分发)。
  3. 数据卷已挂载至大容量独立存储。
  4. 项目空间通过 API 自动创建,无手工遗留。
  5. CI/CD 密码已通过 Secret 管理,无明文泄露。
  6. 制定了镜像保留策略(如仅保留最近 10 个版本)。
  7. 监控大盘已上线,磁盘与宕机告警已测试生效。
记录~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇