如何优雅的在 Zadig 上实践交付物溯源流程
云原生服务的开发迭代,Docker 镜像作为最终的交付产物,其生命周期中存在多个环节的流转:从镜像构建开始,到开发、测试环境的更新验证,再到交付制品生成,交付到生产环境。在这一整套的流转过程中,镜像作为流转物,只要中间的一个流程出现失误,很容易导致交付到生产环境的镜像出现问题。
(资料图片)
虽然 Tag 可以让镜像有一定的辨识度,但其可以修改的特性,并不能作为辨识身份的标准。 如果构建流程中有需要人工干预修改 Tag 的操作,在交付过程中也会引入更多的风险。镜像 ID 和 Digests 配合可以作为唯一身份标识确保交付物的一致性,但可读性比较差,出现交付物不一致的问题,溯源的成本也比较高。
docker images --digestsREPOSITORY TAG DIGEST IMAGE ID CREATED SIZEkoderover.tencentcloudcr.com/koderover-public/aslan 1.15.0-20220922-amd64 sha256:8af42b5dd2a8539c3a1ead4f7bcbcc0028f1ec84090ace6f853793151fc0a7d0 35331bf1ae55 22 hours ago 188MBkoderover.tencentcloudcr.com/koderover-public/zadig-portal 1.13.0-amd64 sha256:15d8207a3ab3573ea8e5a3e32be9fa9340dfb4a5fe0842d3ef848a92655c6f58 1cb89026c2c5 47 hours ago 133MBkoderover.tencentcloudcr.com/koderover-public/zadig-portal 1.14.0-amd64 sha256:1bdb47274a6cb6da12b5fb2d3a073e820a8d5a8be9dac48f8f624adb85ddcefd 63e46ebf3e11 3 weeks ago 133MBtailscale/docker-extension 0.0.13 sha256:5f957b07602dd9b8923664f9b6acf86081c5bfd60b86bf46ab56e3f323ca4de9 1ae72d777218 2 months ago 129MBalgolia/docsearch-scraper latest sha256:7bc1cd5aa4783bf24be9ddd6ef22a629b6b43e217b3fa220b6a0acbdeb83b8f8 04e04eaa5c7d 15 months ago 1.74GB
本文将举例说明使用 Tag 来辨识镜像的一般痛点,以及如何借助 Zadig 的能力来解决构建产物溯源的问题。
痛点私有化交付过程中,某开发人工误操作,不慎导致线上镜像仓库中某个服务的版本被本地推送的相同 Tag 的镜像所覆盖,其中包含未经验收测试的功能,用户端升级服务或者重新拉取该服务镜像后, 导致服务出现故障,比如:功能不 work、服务无法启动...等,只通过镜像无法追踪具体是何种误操作导致的,也不能定位到具体的代码变更。
版本迭代过程中,难免会同时维护多个版本,用户侧使用的版本五花八门,如何进行版本和代码信息的定位匹配,快速排查客户端反馈的问题也是一个头疼的工程难题。
下面将从构建产物为镜像以及非镜像两种场景,介绍涵盖前后端的实践方案:可以从构建产物中直接获取详细的构建链路流程信息,提高后续问题定位排查的效率。
场景一:镜像构建产物核心原理:修改 Dockerfile 添加 LABEL,利用 Zadig 内置构建变量的能力,构建镜像时将其动态注入。
背景知识关于 Docker 镜像构建、LABEL 能力以及构建参数相关可阅读以下资料:
Docker object labels[1]
Docker label / OCI image annotation metadata types[2]
Dockerfile LABEL[3]
Docker build ARG[4]
第一步:编写 Dockerfile修改 Dockfile 动态注入 Zadig 提供的构建变量,这里以开源的zadig-portal[5]为例,主要注入如下信息:
构建时间构建任务的 URL代码信息(代码库/分支/PR/Tag/Commit ID)如果需要注入其他参数,可以根据实际的项目需求进行自定义。核心代码如下:
ARG repoName="zadig-portal"ARG branch=""ARG pr=""ARG tag=""ARG commit=""ARG buildTime=""ARG buildURL=""LABEL maintainer="Zadig Maintainers" \ description="Zadig is a cloud native, distributed, developer-oriented continuous delivery product." \ repoName=${repoName} \ branch=${branch} \ pr=${pr} \ tag=${tag} \ commit=${commit} \ buildTime=${buildTime} \ buildURL=${buildURL}
第二步:完成构建配置将 Zadig 提供的内置构建变量,透传到 docker build --build-arg,主要使用以下变量:
$BUILD_URL构建任务的 URL$由于 zadig-portal 使用的镜像构建,这里配置镜像构建的构建参数,将变量透传到Docker build ARG。如果不使用镜像构建也可以根据实际构建需求,在脚本中手动拼接 docker build 参数。
构建参数中内容如下:
--build-arg branch=$zadig_portal_BRANCH --build-arg pr=$zadig_portal_PR --build-arg tag=$zadig_portal_TAG --build-arg commit=$zadig_portal_COMMIT_ID --build-arg buildTime=$(date +%s) --build-arg buildURL=$BUILD_URL
第三步:效果验证至此,所有通过 Zadig 运行工作流产生的交付镜像,都会被打上自定义的 Label。
可以通过 docker pull 之后 docker inspect 查看注入的 Label。
尝试进行 docker tag 后,重新查看 Label,Label 并不会因为 Retag 而发生变化。
场景二:其他构建产物核心原理:利用 Zadig 的构建参数能力,动态传入来源信息。
对于暂时不便于迁移容器部署的场景,比如基础设施本身是可网络互通的设备:IoT 物联网场景下自动驾驶车辆主机端、工厂可连接设备...等,交付物可能是二进制或者是前端静态文件。上述通过镜像做追踪溯源的实践方法也就不再适用。下面分别介绍前端静态文件以及后端二进制程序的溯源方法。
前端静态文件现代化前端应用离不开模块打包工具,这里以 Webpack 为例,介绍一种通过环境变量透传的溯源方法。其他的工具 Vite、Parcel ...... 也可以参照该思路进行实践,具体配置可以参照相关打包工具的文档。
背景知识
Webpack Define Plugin[6]Webpack Environment Plugin[7]Process Env[8]第一步:代码实现1. 构建模板代码实现
该步骤主要依赖 Webpack Define Plugin ,创建一个需要的构建环境变量模板,方便后续构建时动态替换参数。
const env = require("./config/prod.env");.......//其他配置 plugins: [ new webpack.DefinePlugin({ "BUILDINFO": env }), ]
prod.env 文件内容如下:
"use strict"module.exports = { VERSION: ""${VERSION}"", BUILD_TIME: ""${BUILD_TIME}"", TAG: ""${TAG}"", COMMIT_ID: ""${COMMIT_ID}"", BRANCH: ""${BRANCH}"", PR: ""${PR}"",}
这里主要暴露以下参数,可以根据实际需求进行自定义。
VERSIONBUILD_TIMETAGCOMMIT_IDBRANCHPR2.在业务代码中读取并展示构建变量
这里以 Vue 项目为例,实现在终端中打印构建信息,其他项目可自行调整。核心代码如下:
computed: { processEnv () { return process.env }, }, mounted () { if (this.processEnv && this.processEnv.NODE_ENV === "production" && BUILDINFO) { console.log("%cHello ZADIG!", "color: #e20382;font-size: 13px;") const buildInfo = [] if (BUILDINFO.VERSION) { buildInfo.push(`${BUILDINFO.VERSION}`) } if (BUILDINFO.TAG) { buildInfo.push(`Tag-${BUILDINFO.TAG}`) } if (BUILDINFO.BRANCH) { buildInfo.push(`Branch-${BUILDINFO.BRANCH}`) } if (BUILDINFO.PR) { buildInfo.push(`PR-${BUILDINFO.PR}`) } if (BUILDINFO.COMMIT_ID) { buildInfo.push(`${BUILDINFO.COMMIT_ID.substring(0, 7)}`) } console.log( `%cBuild:${buildInfo.join(" ")}`, "color: #e20382;font-size: 13px;" ) if (BUILDINFO.BUILD_TIME) { console.log( `%cTime:${moment .unix(BUILDINFO.BUILD_TIME) .format("YYYYMMDDHHmm")}`, "color: #e20382;font-size: 13px;" ) } } }
第二步:完成构建配置将 Zadig 提供的内置构建变量,通过脚本实现动态替换 prod.env 的内容,主要使用以下变量:
$运行工作流,可以看到构建变量已经成功的透传,并且替换了预设的变量模板。
部署后查看控制台,可以看到 Zadig 的构建信息已经可以在 console 中显示。
后端二进制产物由于后端二进制交付物背后的项目类型比较多,这里主要介绍 Golang 项目一种实现思路,该部分涉及到的源码可以点击链接[9]查看,其他项目类型可以根据实际情况进行参考和配置。
背景知识go build -ldflags -X[10]Kubectl version[11]K8s version[12]Golang 中管理程序的版本信息[13]第一步:代码实现1. 定义版本信息
这里在项目中维护一份 version.go 文件,根据实际需求,定义需要暴露的参数。
package utilsimport ( "fmt" "runtime")var ( version string gitBranch string gitTag string gitCommit string gitPR string gitTreeState string buildDate string buildURL string)// Info contains versioning information.type Info struct { Version string `json:"version"` GitBranch string `json:"gitBranch"` GitTag string `json:"gitTag"` GitCommit string `json:"gitCommit"` GitPR string `json:"gitPR"` GitTreeState string `json:"gitTreeState"` BuildDate string `json:"buildDate"` BuildURL string `json:"buildURL"` GoVersion string `json:"goVersion"` Compiler string `json:"compiler"` Platform string `json:"platform"`}// String returns info as a human-friendly version string.func (info Info) String() string { return info.Platform}func GetVersion() Info { return Info{ Version: version, GitBranch: gitBranch, GitTag: gitTag, GitCommit: gitCommit, GitPR: gitPR, GitTreeState: gitTreeState, BuildDate: buildDate, BuildURL: buildURL, GoVersion: runtime.Version(), Compiler: runtime.Compiler, Platform: fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH), }}
2. main 函数调用
在入口处设置传入version参数调用GetVersion函数:
package mainimport ( "fmt" "os" "version/utils")func main() { args := os.Args if len(args) >= 2 && args[1] == "version" { v := utils.GetVersion() fmt.Printf("Version: %s\nBranch: %s\nCommit: %s\nPR: %s\nBuild Time: %s\nGo Version: %s\nOS/Arch: %s\nBuild URL: %s\n", v.Version, v.GitBranch, v.GitCommit,v.GitPR, v.BuildDate, v.GoVersion, v.Platform,v.BuildURL) } else { fmt.Printf("Version(hard code): %s\n", "0.1") }}
3. 构建工程文件编写
这里新建一个 Makefile 进行构建,使用ldflags -X透传 Zadig 构建内置变量,核心逻辑如下:
# build with verison infosversinotallow="version/utils"gitTag=$(version_TAG)gitBranch=$(version_BRANCH)gitPR=$(version_PR)buildDate=$(shell TZ=Asia/Shanghai date +%FT%T%z)gitCommit=$(version_COMMIT_ID)gitTreeState=$(shell if git status|grep -q "clean";then echo clean; else echo dirty; fi)buildURL=$(BUILD_URL)ldflags="-s -w -X ${versionDir}.gitTag=${gitTag} -X ${versionDir}.buildDate=${buildDate} -X ${versionDir}.gitCommit=${gitCommit} -X ${versionDir}.gitPR=${gitPR} -X ${versionDir}.gitTreeState=${gitTreeState} -X ${versionDir}.versinotallow=${VERSION} -X ${versionDir}.gitBranch=${gitBranch} -X ${versionDir}.buildURL=${buildURL}"PACKAGES=`go list ./... | grep -v /vendor/`VETPACKAGES=`go list ./... | grep -v /vendor/ | grep -v /examples/`GOFILES=`find . -name "*.go" -type f -not -path "./vendor/*"`default: @echo "build the ${BINARY}" @GOOS=linux GOARCH=amd64 go build -ldflags ${ldflags} -o build/${BINARY}.linux -tags=jsoniter @go build -ldflags ${ldflags} -o build/${BINARY}.mac -tags=jsoniter @echo "build done."
第二步:完成构建配置在 Zadig 中配置构建,在构建脚本中构建并打印输出,详细信息如下:
依赖的软件包go 1.16.13自定义构建变量配置 VERSION 变量构建脚本内容如下:set -ecd $WORKSPACE/zadig/examples/version-demoenvmake defaultcd build./version.linux version
第三步:效果验证运行工作流,可以看到构建变量已经成功的透传,并且该二进制程序通过version参数可以打印详细的构建来源信息。
结语以上,就是一些常见交付物类型在 Zadig 上的溯源思路总结,相比于通过原始的 Image ID 、Digest ....来反推进行追踪,该流程可以让用户以及开发人员通过更简单便捷的方式上报或者追踪交付物问题,提高问题排查定位的效率。
参考链接[1]https://docs.docker.com/config/labels-custom-metadata/
[2]https://github.com/opencontainers/image-spec/blob/main/annotations.md
[3]https://docs.docker.com/engine/reference/builder/#label
[4]https://docs.docker.com/engine/reference/builder/#arg
[5] https://github.com/koderover/zadig-portal/blob/main/Dockerfile
[6] https://webpack.js.org/plugins/define-plugin/
[7] https://webpack.js.org/plugins/environment-plugin/#root
[8]https://nodejs.org/api/process.html#process_process_env
[9]https://github.com/koderover/zadig/tree/main/examples/version-demo
[10] https://pkg.go.dev/cmd/link
[11]https://github.com/kubernetes/kubectl/blob/master/pkg/cmd/version/version.go
[12] https://github.com/kubernetes/component-base/blob/master/version/version.go
[13] https://zhuanlan.zhihu.com/p/150991555
标签:
推荐
- 如何优雅的在 Zadig 上实践交付物溯源流程
- 全球观焦点:中资美元债早报(4.25) | 漳州九龙江集团、长兴交投定价
- 张新成孙千《这么多年》终极预告发布 上映在即预售破千万
- 新华时评·首季经济形势|持续发力稳就业促民生 环球速讯
- 焦点快报!十几块也有智商税,这钱没省下
- 东北老工业基地佳木斯转型发展渐入“佳”境 当前速看
- 【天天速看料】现代俄汉双解词典_关于现代俄汉双解词典介绍
- 每日快报!选址日报:大众投363亿建超级工厂;赣锋锂电斥100亿建生产基地
- ChatGPT火了 人工智能会造就未来“最佳员工”吗? 当前快讯
- 2023《支付宝》蚂蚁庄园4月26日每日一题答案(2)|世界聚焦
- 世界观焦点:前绿军主帅乌度卡担任火箭新主教练
- 2023年,济南市审计局围绕“项目突破年”共安排审计项目29个 天天热点
- 当前关注:上海新国际博览中心在几号线地铁线_上海新国际博览中心地铁几号线
- 环球最新:唏嘘!高拉特此前采访表示希望为国足做贡献,如今零出场后退役
- 当前视点!预下载登顶全球超 110 地免费榜,米哈游新作能否再赢一次?
- 泡泡玛特低估了周期的力量|快报
- 当前热门:回暖之旅即将开启!5月前还有两股冷空气
- 阜阳赴衢州合肥开展招商引资活动
- 每日时讯!强化教育培训 促增工作质效——海南州公安机关文秘、财务综合素能提升班在苏州大学开班
- 女子曝光深夜一幕:赶紧避雷!网友气哭:太坑了|环球热文
- 老牌房企:因为拖欠工资,高管纷纷离职,距离暴雷更进一步
- 当前动态:美国第一共和银行一季度流失存款近720亿美元,宣布裁员25%
- 环球快消息!车间设备维修费计入什么科目2022_车间设备维修费计入什么科目
- 坦克世界兵工厂还有吗现在 坦克世界兵工厂
- 我的兄弟姐妹电影版高清_我的兄弟姐妹电影版 每日热门
- 棚改退场 深圳老旧住宅小区走向何方
- 光明日报:精心呵护学生身心健康|世界速看
- 寄人篱下石头与水笔趣阁_寄人篱下 天天百事通
- 成人正常体温是多少°c腋下_成人的正常体温是多少度之间
- 快消息!吉祥三宝歌词蒙古语_吉祥三宝歌词
- 场控和运营区别_场控
- 首届中国(郑州)乡村振兴高峰论坛 暨消费帮扶成果展新闻发布会在郑州隆重举行
- 全球今日报丨打造车内森林氧吧 极狐推出阿尔法S和阿尔法T森林版
- 格力地产上市后首次巨亏,地产年销售萎缩至40亿,前董事长去年被免 焦点要闻
- 光莆股份重磅亮相第81届教育装备展 环球观点
- 最新:石家庄市南高营小学开展野生动物保护宣传活动
- 书香校园
- 每日看点!白菜怎么做好吃凉拌_白菜怎么做好吃
- 天天日报丨云南曲靖市麒麟区两所学校主体结构全面封顶 将于9月投入使用
- 让数据开口说话 让监督事半功倍
- 古特雷斯:多边体系正承受自联合国成立以来前所未有的压力
- 全球观热点:邳州“好黄瓜”,全省金奖!
- 2023上海车展:豪华新能源的“天花板” 静态体验迈巴赫EQS SUV_环球热头条
- 英雄联盟之仙域纵横_关于英雄联盟之仙域纵横的简介
- 创意工作者直呼内行!华硕新品发布会将至,一文速览四款新品亮点-每日速看
- 秦刚会见俄罗斯第一副外长季托夫
- 消息:苹果MR设备已进入最后冲刺阶段
- 实时焦点:分享4款纯粮白酒,款款好喝实惠,都是酒友常喝的口粮酒
- 智慧药房悄然现身多地街头,一场智能化改革正涌向药店行业-今日报
- 葆真止泄丸_关于葆真止泄丸的简介
- 头顶两份对赌协议,珠海万达商管IPO延期,万达系年内筹资百亿
- 上海市青少年学生读书行动启动_世界热资讯
- 五一出境游必备!这些华为宝藏APP包办你的精彩旅程
- 热头条丨光峰科技:将成为比亚迪汽车的车载光学部件供应商
- 为什么地球上大多数人的DNA里面都有尼安德特人血统?
- 摆在超市角落的4款小众白酒,新手小白看不懂,行家却是爱不释口 全球快消息
- 科罗拉多州辣椒化石的发现可能会颠覆进化的时间线-世界资讯
- 四会富仕股东户数增加112户,户均持股10.89万元
- 热点!“五一”出境游抢闸开拔 中国游客组团赴西班牙
- 天天动态:利空因素共振,短期铁矿价格偏弱运行
- 文章生成器在线(狗屁不通文章生成器在线)
- 盛屯矿业股票_盛易传奇|今热点
- 每日看点!湖南隆回文旅势头猛 民宿产业发展驶入快车道
- “新课程阅读”乡村振兴读书活动举办,打造乡村阅读示范点
- 天地在线(002995)盘中异动 股价振幅达10.45% 上涨7.05%(04-24)|当前热闻
- 环球热门:廉隅细谨
- 铁科轨道等6只科创板股融资余额增幅超20%|环球百事通
- 晋城347户回迁居民选房现场!
- 科瓦西奇:克罗地亚用实力赢得尊重,伦敦的食物确实有些不同 全球热门
- 天舟文化4月24日快速上涨
- 孙铭徽23分,广东出局罪人揪出,打铁频频还闹脾气,辜负杜锋期待 快看点
- 焦点报道:中成药龙头股票是哪些(A股四大中成药龙头名单)
- 人社部:推进制造业技能根基工程 加强和改进中国特色企业新型学徒制 每日讯息
- 每日看点!森马投资新设医疗健康管理公司,注册资本2亿元
- B站男主播展示吧友热评:曼联又倒贴一个加时,体能储备更惨了-快看点
- 全球视点!旅游大巴一车难求!彻底爆单
- 热点在线丨国内商品期市早盘多数下跌 螺纹钢跌超3%
- 在澳门过世界读书日:书香满溢“阅读之城” 世界热点评
- 天天观焦点:日本央行将于4月27日和28日召开会议 对过去几十年的政策进行评估
- word怎么排列多张图片(word怎么排列多张图片)
- 大连技师学院是公办吗_大连技师学院
- 环球即时看!淄博烧烤大热,这类概念股也火了,龙头一季度业绩暴增
- 天天动态:赴八千年之约 邹城市郭里镇举行祭祀伏羲女娲大典
- 全球头条:从“资本江阴”到“科创江阴”“A股第一县”江阴以高质量转型引领县域经济发展
- 特斯拉股东不满马斯克分心,要求他全职当CEO
- 王源的qq号密码是什么 王源的qq号
- 速讯:呆河马mega进化_呆河马
- 有心者有所累无心者无所谓出处_有心者有所累无心者无所谓什么意思
- 中国地震台网正式测定:04月23日20时46分在云南德宏州芒市发生3.2级地震,震源深度8千米。
- 核裂变图片_核裂变 环球速讯
- 世界焦点!孕贝安
- 世界今日报丨副账户余额_副账户
- 汕尾美团骑手集体罢工?客服回应 情况到底怎么样的?
- 男式高跟鞋舞_男式高跟鞋-全球新要闻
- 中州古籍出版社有限公司_中州古籍出版社有限公司 天天时快讯
- 世界快讯:国铁集团回应软卧票性别分配需求:业务部门在研究
- 呼和浩特美女副局长李少莉公开露面,出席党风廉政建设工作会议-要闻速递
- 环球快资讯:摩托罗拉Razr2023即将发布 小折叠手机中极大外屏
- 海康威视携新品亮相第81届中国教育装备展示会 天天观热点
- 麟游县:完成“网上中介超市”首单交易
X 关闭
行业规章
X 关闭