Harbor 复制策略手动触发全解析:基于 7-05 测试用例的操作验证与源码机理
Harbor 复制策略手动触发全解析基于 7-05 测试用例的操作验证与源码机理【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor本文围绕 Harbor 官方测试用例 7-05-Trigger-manual.md 展开完整解读管理员手动触发复制Replication的测试目的、前置环境、操作步骤与预期结果并结合本仓库复制模块的源码实现剖析手动触发从 UI 点击到执行流flow落地的完整调用链。读完本文你将能够在 Harbor 集群间正确配置并手动触发复制任务理解 Manual、Scheduled、Event Based 三种触发方式的本质区别并能借助执行Execution与任务Task记录验证复制是否成功。一、为什么需要手动触发复制Harbor 的复制Replication功能用于把源仓库中的制品镜像/Chart 等同步到目标仓库常被用于多集群容灾、镜像分发与跨环境发布。复制规则Replication Policy定义复制什么、复制到哪、怎么触发而触发方式决定了复制动作在什么时机发生。在 src/pkg/reg/model/policy.go 中触发类型被定义为三种常量触发类型常量值含义手动manual仅由用户在界面上点击或调用 API 触发定时scheduled依据 Cron 表达式周期触发事件驱动event_based源端推送新制品时即时触发其中手动触发是最可控、最直观的一种方式管理员掌握复制执行的主动权适合迁移数据、上线前的一次性同步、或在自动触发失败后的人工补救。测试用例 7-05 正是为了验证这一核心能力在系统级Administration与项目级Projects两个入口下均可用。二、测试用例 7-05 核心内容解读用例原文位于 tests/testcases/Group7-Replication/7-05-Trigger-manual.md其结构为目的 → 环境 → 步骤 → 预期结果 → 可能问题下面逐项解读并补足操作细节。2.1 测试目的To verify admin user can trigger a replication manually.即验证管理员用户能够手动触发一次复制任务。这里的管理员指具备系统级Replication资源操作权限的用户对应源码中的 RBAC 校验见下文第三节。2.2 环境前置条件用例要求以下环境就绪至少两台 Harbor 实例运行且可用复制本质是源 → 目标的双端协作因此需要源 Harbor 与目标 Harbor或 Harbor 与其他兼容 registry同时在线。两台实例的地址需要作为注册表Registry/Endpoint预先配置好相关用例参见同目录下的 7-12-Endpoints-endpoints-add.md 等 Endpoint 系列用例。创建一条触发条件为手动且未配置过滤器的复制规则规则必须显式选择触发方式为手动Manual并且不添加任何过滤器。这样做的目的是让复制覆盖项目下的全部制品从而验证所有镜像都被复制这一预期结果。过滤器如 name/tag/label 过滤的行为由 7-04-Proj-replication-rules-filter.md 与 7-10-Filter.md 单独覆盖此处刻意排除以隔离变量。至少推送一个镜像到该规则所应用的项目源端项目里必须有真实数据否则复制执行会因为没有待复制的资源而被提前标记为完成源码行为见 3.4 节。2.3 测试步骤用例给出两个操作入口均需以管理员身份登录 UI系统级入口进入Administration → Replications页面选中要执行的复制规则点击REPLICATE按钮。项目级入口进入Projects → Project_Name → Replication页面重复上述选择规则 → 点击 REPLICATE操作。两个入口验证的是同一功能的不同视图Administration 页面能看到全局所有复制规则而项目页面只展示作用于该项目或与该项目相关的规则方便项目成员在项目上下文中操作。从源码看两者的底层实现均调用同一个复制控制器replication.Ctl差异仅在于 API 层的资源定位与权限校验范围。2.4 预期结果In step 2, the operation should success and a few jobs should be started. All the images under the project should be replicated to the remote registry.点击REPLICATE后操作应立即成功接口返回创建成功并带出新执行记录的 Location随之启动若干任务jobs分别对应项目下每个需要复制的制品等待任务全部完成后项目下的所有镜像都应出现在远端 registry 中。2.5 可能问题用例标注None说明该场景在正常配置下不存在已知共性问题。但结合源码与常见运维经验手动触发仍可能遇到以下情形详见第五节排查建议规则被禁用、无制品可复制、单活跃复制限制、目标命名空间冲突等。三、源码级剖析手动触发背后的完整调用链手动触发并非仅是一个前端按钮其背后是一条完整的API → 控制器 → 执行流调用链。下面以本仓库源码为据逐步拆解。3.1 触发类型的底层定义复制规则的触发类型在数据模型中定义于 src/pkg/reg/model/policy.go// Trigger holds info for a trigger type Trigger struct { Type string json:type Settings *TriggerSettings json:trigger_settings } // TriggerSettings is the setting about the trigger type TriggerSettings struct { Cron string json:cron }Trigger.Type即上文所述的manual/scheduled/event_based。其中scheduled类型必须携带合法的 Cron 设置而manual与event_based无需额外设置。这一约束在策略校验逻辑中体现switch p.Trigger.Type { case model.TriggerTypeManual, model.TriggerTypeEventBased: case model.TriggerTypeScheduled: if p.Trigger.Settings nil || len(p.Trigger.Settings.Cron) 0 { return errors.New(nil).WithCode(errors.BadRequestCode). WithMessagef(the cron string cannot be empty when the trigger type is %s, model.TriggerTypeScheduled) } ... }见 src/controller/replication/model/model.go。同时该文件中还保留了旧版本策略的兼容解析逻辑parseTrigger老版本中Kind为Manual/Immediate/Scheduled的字段会被映射为新的Type值确保升级后手动规则依旧可用model.go。3.2 API 层StartReplication 接口手动触发的 HTTP 入口是POST /api/v2.0/replication/executions实现在 src/server/v2.0/handler/replication.gofunc (r *replicationAPI) StartReplication(ctx context.Context, params operation.StartReplicationParams) middleware.Responder { if err : r.RequireSystemAccess(ctx, rbac.ActionCreate, rbac.ResourceReplication); err ! nil { return r.SendError(ctx, err) } policy, err : r.ctl.GetPolicy(ctx, params.Execution.PolicyID) if err ! nil { return r.SendError(ctx, err) } trigger : task.ExecutionTriggerManual if params.HTTPRequest.URL.Query().Get(trigger) scheduled { trigger task.ExecutionTriggerSchedule } executionID, err : r.ctl.Start(ctx, policy, nil, trigger) ... return operation.NewStartReplicationCreated().WithLocation(location) }关键点权限控制接口先通过RequireSystemAccess(ctx, rbac.ActionCreate, rbac.ResourceReplication)校验调用者是否拥有系统级Replication资源的Create权限。这印证了用例以管理员用户登录的必要性——普通项目成员默认不具备系统级复制资源权限。默认触发标记正常情况下请求不携带trigger查询参数执行记录的触发方式即为task.ExecutionTriggerManual手动仅当请求来自旧版调度任务并显式携带triggerscheduled时才标记为定时触发。执行记录 Location成功后返回201 Created并在响应头Location中给出新执行记录的访问路径可用于后续轮询执行状态。3.3 控制器层Start 方法的执行语义API 层随后调用复制控制器全局实例replication.Ctl的Start方法src/controller/replication/execution.go。该方法做了几件重要的事规则启用检查若规则被禁用Enabled false直接返回PreconditionCode错误the policy X is disabled复制不会开始。执行记录创建以job.ReplicationVendorType作为厂商类型、规则 ID 作为 VendorID 创建一条执行记录并携带触发方式与操作者operator信息。单活跃复制约束如果规则开启了SingleActiveReplication单活跃复制会先统计该规则下处于 Running 状态的执行数若已有进行中的执行新执行会被标记为Execution skipped: active replication still in progress.避免同一规则并发复制造成资源浪费或数据竞争。后台异步执行真正的复制流程在 goroutine 中运行并通过lib.NewWorkerPool(10)限流最多 10 个并发复制执行。goroutine 内新建 ORM 上下文、对执行记录做重试等待再交给 flow 控制器执行任何 panic 都会被 recover 并标记执行失败。3.4 流程层CopyFlow 的资源发现与任务拆分复制流程控制器根据是否有Deleted资源决定走删除流还是复制流src/controller/replication/flow/controller.gofunc (c *controller) Start(ctx context.Context, executionID int64, policy *repctlmodel.Policy, resource *model.Resource) error { // deletion flow if resource ! nil resource.Deleted { return NewDeletionFlow(executionID, policy, resource).Run(ctx) } // copy flow resources : []*model.Resource{} if resource ! nil { resources append(resources, resource) } return NewCopyFlow(executionID, policy, resources...).Run(ctx) }手动触发时resource为nil因此走NewCopyFlow。复制流的核心逻辑在 src/controller/replication/flow/copy.gofunc (c *copyFlow) Run(ctx context.Context) error { srcAdapter, dstAdapter, err : initialize(c.policy) ... srcResources : c.resources if len(srcResources) 0 { srcResources, err fetchResources(srcAdapter, c.policy) ... } ... if len(srcResources) 0 { // no candidates, mark the execution as done directly if err : c.executionMgr.MarkDone(ctx, c.executionID, no resources need to be replicated); err ! nil { ... } return nil } ... }这段代码完美对应了用例的两个预期细节a few jobs should be started复制流会基于策略的过滤器从源适配器拉取待复制资源列表fetchResources未配置过滤器的规则将拉取项目下全部制品随后为每个资源创建复制任务task这就是界面上一批 job 的来源All the images under the project should be replicated因为用例刻意未配置过滤器资源列表覆盖全部制品逐个任务完成后即实现全量同步反向情况若项目下没有任何镜像fetchResources返回空列表执行会被直接MarkDoneno resources need to be replicated界面上不会产生复制任务——这解释了环境前置条件至少推送一个镜像的意义。此外task.Execution记录中包含Trigger字段UI 的执行列表页即据此展示每次执行是 Manual、Scheduled 还是 Event Based 触发execution.go便于管理员审计复制来源。3.5 复制任务与调度器的关联补充对比虽然 7-05 只验证手动触发理解它与定时触发的关系有助于把握整体架构。在 src/controller/replication/policy.go 中创建规则时若policy.IsScheduledTrigger()为真会通过scheduler.Schedule注册一个 Cron 回调REPLICATION_CALLBACK到期后由回调函数以task.ExecutionTriggerSchedule触发执行而手动规则不会注册任何调度器任务因此不点就不跑这正是手动触发区别于定时触发的本质。四、实操指南如何手动触发一次复制4.1 前置准备清单项说明两台 Harbor 实例源端与目标端均可达目标端可替换为其他兼容 registry目标注册表Endpoint在Administration → Registries中配置目标实例地址与凭证复制规则在Administration → Replications新建规则源注册表选择源实例或留空表示本 Harbor 为源、目标注册表选择目标实例、触发方式选择 Manual、不配置过滤器源端数据向规则应用的项目推送至少一个镜像确保有待复制资源4.2 操作步骤方式一系统级页面使用管理员账号登录 Harbor UI。进入Administration → Replications。在规则列表中找到目标规则点击行尾的REPLICATE按钮。系统提示操作成功页面自动切换到该规则的执行列表可看到新生成的执行记录及其子任务。方式二项目级页面进入Projects → Project_Name → Replication。选中作用于该项目的规则点击REPLICATE。观察执行列表与任务状态。方式三REST API等效做法手动触发同样可通过 API 完成等价于 UI 按钮的底层请求POST /api/v2.0/replication/executions Content-Type: application/json { policy_id: 1 }响应为201 CreatedLocation头携带执行 ID随后可查询执行与任务列表确认进度。4.3 结果验证在Administration → Replications → 规则名 → Executions中查看执行状态正常应依次经过 Running → Succeed或任务级 Success。展开执行记录查看各任务每个任务对应一个制品状态全部为 Success 即表示复制完成。登录目标 Harbor进入目标项目确认源端全部镜像含标签均已出现。若执行被标记为成功但任务数为 0请检查源项目是否确实存在制品见 3.4 节的空资源处理逻辑。五、常见问题与排查建议现象可能原因排查方向点击 REPLICATE 后提示规则被禁用规则Enabled为 false控制器直接拒绝在Administration → Replications中启用该规则执行成功但没有任何任务源项目无制品或过滤器把资源全部过滤掉确认源端有镜像检查规则的 name/tag/label 过滤器新执行被跳过skipped规则开启SingleActiveReplication且已有运行中的执行等待当前执行结束或关闭单活跃复制选项复制任务失败目标端凭证失效、命名空间冲突、网络不通查看任务日志GetTaskLog核对 Endpoint 配置与目标命名空间制品未出现在目标端覆盖策略Override关闭且目标已有同名标签调整规则中的覆盖override选项或清理目标端同名制品六、总结测试用例 7-05 用最简洁的方式验证了 Harbor 复制模块的手动触发能力以管理员身份、在系统级与项目级两个入口点击REPLICATE即可立即启动针对项目全部制品的复制任务。结合本仓库源码可以看到这一过程由StartReplicationAPI →replication.Ctl.Start→CopyFlow.Run三级调用完成期间涉及系统权限校验、规则启用检查、单活跃复制约束、异步执行与资源发现等关键机制。掌握手动触发就掌握了 Harbor 复制功能中按需同步的基础操作也为理解定时触发与事件触发可进一步参考 7-06-Trigger-immediate.md、7-07-Trigger-scheduled.md奠定了基础。【免费下载链接】harborAn open source trusted cloud native registry project that stores, signs, and scans content.项目地址: https://gitcode.com/GitHub_Trending/ha/harbor创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考