前言 在上半年的这篇文章 中,我们对公司的发版流程进行了优化,通过结合使用阿里云、华为云的免费镜像仓库和加速服务,在改造多架构镜像的同时,大大加快的镜像分发的速度。但是这也带来一个问题,由于镜像不再直接推送到公司的 Harbor 仓库,而是通过一个本地的 Harbor 仓库往三个仓库推送,所以开发看到 Jenkins 任务完成了并不能说明镜像已经到达了仓库,对于镜像何时入仓这个问题变得不再透明,今天我们就来解决这个问题
方法 大概思路有两种
一种是调用各个平台的 SDK ,看云上有什么镜像,想部署的时候去找一下要部署的最新版本的在这个仓库里面有没有,这个做起来比较麻烦,但是对有历史查询需求的就比较友好
另一种是从本地的 Harbor 仓库获取镜像的推送情况,再想办法告知给开发和实施人员
因为没有对历史镜像的查询的需求,并且想要通过“推送”的方式去主动告知开发和实施人员,从标题也能看出来,我们选择了方法二
实现 从 Harbor 里面拿推送数据,可以通过 Harbor 的 SDK 或者通过 WebHook ,在上次的文章 中,我们就使用了 Harbor 的 Golang SDK,不过本次的需求就用 WebHook 轻松解决
打开 WebHook 在项目空间中,找到 WebHook 仅接受镜像复制状态改变事件,Endpoint 需要我们起一个 http 服务去接收,方法是 POST , payload 选择默认即可
解析 WebHook 数据 WebHook 里面的数据大致长这样
{ "type" : "REPLICATION" , "occur_at" : 1732347103 , "operator" : "admin" , "event_data" : { "replication" : { "harbor_hostname" : "xxx.xxx.xxx.xxx" , "job_status" : "Success" , "description" : "阿里仓" , "artifact_type" : "artifact" , "authentication_type" : "basic" , "override_mode" : true , "trigger_type" : "EVENT" , "execution_timestamp" : 1732346947 , "src_resource" : { "registry_type" : "harbor" , "endpoint" : "http://xxx.xxx.xxx.xxx:xxx" , "namespace" : "xxx" } , "dest_resource" : { "registry_name" : "Ali_ACR_yunzai" , "registry_type" : "ali-acr" , "endpoint" : "https://registry.cn-hangzhou.aliyuncs.com" , "namespace" : "xxx" } , "successful_artifact" : [ { "type" : "artifact" , "status" : "Success" , "name_tag" : "mars-xxx-xxx [1 item(s) in total]" , "references" : [ "sha256:xxx" ] } ] } } }
解析时需要注意以下问题:
job_status (任务结果) 不仅在成功或失败时触发,在任务开始时也会触发,需要过滤一下只推送成功或者失败的数据
里面的 timestamp 是 UNIX 时间
description 里面的内容,需要去复制任务里面填写描述
name_tag 里面只会显示项目名称
references 里面不仅会有 tag ,也会有镜像的 sha256 两种形式,需要过滤一下,只推送版本信息,具体可以看下图
sha256 是构建镜像产物 (artifact) 哈希计算出来的,无论镜像是否打了 tag ,都会有 sha256 的 references
企业微信推送 已经解析了数据,我们只需要推送给开发和实施的同学即可,根据公司 IM 的使用情况,选择了企业微信机器人
把相关的同学拉入群聊,然后添加一个机器人,务必注意保护里面的 key (也就是推送地址)
官方没有提供 SDK ,第三方有 Golang 的 SDK ,但是因为只调一个企业微信机器人接口,我们根据文档快速写一个即可
群机器人配置说明 - 文档 - 企业微信开发者中心
推送的结果有多种模板,最开始我选择了好看的卡片模板,但是卡片模板过于花哨,占用地方过多并且不方便查看和搜索,最后还是改成了文字模板,最后的效果如下图
附录 有类似开发需求的同学,这里提供 Harbor 的 WebHook 和 企业微信机器人 API 的 struct
企业微信机器人 API - 文字模板(MarkDown) type EnterpriseWechatMarkDownWebHook struct { Msgtype string `json:"msgtype"` Markdown Markdown `json:"markdown"` } type Markdown struct { Content string `json:"content"` }
Harbor WebHook type HarborWebHook struct { Type string `json:"type"` OccurAt int `json:"occur_at"` Operator string `json:"operator"` EventData struct { Replication struct { HarborHostname string `json:"harbor_hostname"` JobStatus string `json:"job_status"` Description string `json:"description"` ArtifactType string `json:"artifact_type"` AuthenticationType string `json:"authentication_type"` OverrideMode bool `json:"override_mode"` TriggerType string `json:"trigger_type"` ExecutionTimestamp int `json:"execution_timestamp"` SrcResource SrcResource `json:"src_resource"` DestResource DestResource `json:"dest_resource"` SuccessfulArtifact []SuccessfulArtifact `json:"successful_artifact"` } `json:"replication"` } `json:"event_data"` } type SrcResource struct { RegistryType string `json:"registry_type"` Endpoint string `json:"endpoint"` Namespace string `json:"namespace"` } type DestResource struct { RegistryName string `json:"registry_name"` RegistryType string `json:"registry_type"` Endpoint string `json:"endpoint"` Namespace string `json:"namespace"` } type SuccessfulArtifact struct { Type string `json:"type"` Status string `json:"status"` NameTag string `json:"name_tag"` References []string `json:"references"` }