【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队

本文主要是介绍【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在云原生领域,无论使用哪种编排调度平台,Kubernetes,DockerSwarm,OpenShift等,业务都需要基于镜像进行交付,我们在内部实践“Source-to-image”和链式构建,总而总结出“OneBuild”模式。

其核心思想是:一处构建,多处使用。

问题

一般,我们会使用类似Jenkins CI系统来构建镜像,以满足持续集成,持续开发,持续交付等场景。事实上,如果我们在某一方面能够提升效率或者解决镜像交付实践。

长期来看,将能够带来不少的成本收益,并且对于平台来讲,这种收益是一种可度量收益。假设我们在当前交付(git)分支中,需要fix或者feature已经release分支的,如何进行?如果在已经交付给用户的镜像中存在漏洞,需要批量交付,如何进行?为了解决这些问题,我们的团队必须重新构建镜像,并且找出基本镜像,构建过程有那些依赖关系。然后基于这些成熟的流程和规范进行快速交付。

解决方案

Docker build是大家比较常用的镜像构建方法,并且在构建中只需要声明自己的Dockerfile即可,就可以实现快速构建。但是这并不满足大型企业实践以及快速交付。

所以需要一套规范且能够直接生产的流程,帮助在云原生下进行快速交付。下面我们讲结合行云平台进行“OneBuild”方法的实践。

悬衡而知乎,没规而知圆。因此,我们在团队的流水线建立和改造的过程中,尤其注重标准化。

包括dockerfile的命名和设计,构建代码的设计。由此新项目加入时,我们只需复制,然后做小工作量的改造即可。

行云Build

行云是JDT生产效率的标准化产品,是一个比较成熟的产品。用于支撑内部研发,测试,交付的平台。

Build是行云中一个子系统,用于研发过程中的持续集成,持续测试,持续构建等任务。

团队日常开发语言主要是以golang为主,并且在上线或交付制品中,也以Docker镜像为主。并且由于大多数时间,我们必须在真实的K8S环境中运行。

所以稳定的构建平台,高效,快速的构建,对我们的日常开发和交付都是至关重要,在构建中往往需要构建多版本镜像。所以围绕行云流水线,主要就是发掘功能,适配改造。

Dockerfile标准化

接下来,我们设计的流程,将会使用上一级构建的产品,对下级镜像进行快速装箱。

Dockerfile命名


Dockerfile            # 标准版Dockerfile.kylinv10   # kylinv10 base 版本Dockerfile.oel22      # openeuler base 版本

下面我们继续看dockerfile中的细节。

首先是 Dockerfile


ARG ARCHARG BUILD_IMAGEARG BASE_IMAGEFROM ${BUILD_IMAGE} as builderARG ARCHENV GOPATH=/goCOPY go.mod go.modCOPY go.sum go.sumCOPY main.go main.goCOPY api/ api/COPY controllers/ controllers/COPY pkg/ pkg/COPY vendor/ vendor/# BuildRUN CGO_ENABLED=0 GO111MODULE=on GOOS=linux GOARCH=${ARCH} go build --mod=vendor -a -o manager main.goARG ARCHARG BASE_IMAGEFROM ${BASE_IMAGE}ENV PIP3_SOURCE=https://pypi.tuna.tsinghua.edu.cn/simpleENV DEFAULT_FORKS=50ENV DEFAULT_TIMEOUT=600ENV DEFAULT_GATHER_TIMEOUT=600ENV TZ=Asia/ShanghaiENV PYTHONWARNINGS=ignore::UserWarningWORKDIR /COPY --from=builder /manager .COPY inventory/ inventory/COPY roles/ roles/COPY etcd-restore.yml etcd-restore.ymlCOPY facts.yml facts.ymlCOPY requirements.txt requirements.txtCOPY inventory.tmpl.ini inventory.tmpl.iniCOPY ansible.cfg ansible.cfgRUN yum -y install kde-l10n-Chinese && \yum -y reinstall glibc-common && \localedef -c -f UTF-8 -i zh_CN zh_CN.UFT-8 && \echo 'LANG="zh_CN.UTF-8"' > /etc/locale.conf && \source /etc/locale.conf && \yum clean allENV LANG=zh_CN.UTF-8ENV LC_ALL=zh_CN.UTF-8RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \echo $TZ > /etc/timezone && \yum install python3 python3-devel sshpass openssh-clients -y && \yum clean all && \/usr/bin/python3 -m pip --no-cache-dir install pip==21.3.1 -U -i $PIP3_SOURCE && \/usr/bin/python3 -m pip --no-cache-dir install -r requirements.txt -i $PIP3_SOURCEUSER rootENTRYPOINT ["/manager"]

上述dockerfile中,分为两个阶段构建,第一个阶段builder构建出需要的二进制。这与正常的dockerfile相同。

唯一不同的是,我们讲构建镜像和base镜像进行了参数化,这也使得当变更构建镜像和base镜像,我们只需要在构建时控制参数即可。

再看dockerfile.kylinv10


ARG BASE_IMAGEFROM ${BASE_IMAGE}ENV PIP3_SOURCE=https://pypi.tuna.tsinghua.edu.cn/simpleENV DEFAULT_FORKS=50ENV LANG=en_US.UTF-8ENV DEFAULT_TIMEOUT=600ENV DEFAULT_GATHER_TIMEOUT=600ENV TZ=Asia/ShanghaiENV PYTHONWARNINGS=ignore::UserWarningWORKDIR /COPY --from=jdos-etcd-restore-helper:latest /manager /COPY inventory/ inventory/COPY roles/ roles/COPY etcd-restore.yml etcd-restore.ymlCOPY facts.yml facts.ymlCOPY requirements.txt requirements.txtCOPY inventory.tmpl.ini inventory.tmpl.iniCOPY ansible.cfg ansible.cfgRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \echo $TZ > /etc/timezone && \yum install python3 python3-devel python3-pip sshpass openssh-clients -y && \/usr/bin/python3 -m pip --no-cache-dir install pip==21.3.1 -U -i $PIP3_SOURCE && \/usr/bin/python3 -m pip --no-cache-dir install -r requirements.txt -i $PIP3_SOURCEUSER rootENTRYPOINT ["/manager"]

发现了什么?在dockerfile.kylinv10中少了builder这一步,COPY --from=jdos-etcd-restore-helper:latest 是从一个指定的临时镜像中直接做了拷贝。这就直接复用了第一步dockerfile中构建出的产物。效率提升比较明显。

在dockerfile设计中,COPY是可以从一个指定的镜像中,copy指定的文件的。

再看Dockerfile.oel22


ARG BASE_IMAGEFROM ${BASE_IMAGE}ENV PIP3_SOURCE=https://pypi.tuna.tsinghua.edu.cn/simpleENV DEFAULT_FORKS=50ENV LANG=en_US.UTF-8ENV DEFAULT_TIMEOUT=600ENV DEFAULT_GATHER_TIMEOUT=600ENV TZ=Asia/ShanghaiENV PYTHONWARNINGS=ignore::UserWarningWORKDIR /COPY --from=jdos-etcd-restore-helper:latest /manager /COPY inventory/ inventory/COPY roles/ roles/COPY etcd-restore.yml etcd-restore.ymlCOPY facts.yml facts.ymlCOPY requirements.txt requirements.txtCOPY inventory.tmpl.ini inventory.tmpl.iniCOPY ansible.cfg ansible.cfgRUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \echo $TZ > /etc/timezone && \yum install python3 python3-devel python3-pip sshpass openssh-clients -y && \/usr/bin/python3 -m pip --no-cache-dir install pip==21.3.1 -U -i $PIP3_SOURCE && \/usr/bin/python3 -m pip --no-cache-dir install -r requirements.txt -i $PIP3_SOURCEUSER rootENTRYPOINT ["/manager"]

是不是与dockerfile.kylinv10的思路非常相似,事实上,这两个文件已经可以合并了(内部为了向后兼容,没有合并这两个文件)。

脚本标准化

还需要在行云流水线中将shell脚本进行固化,与dockerfile进行配合。


# 支持shell语言代码的多行输入cd  /sudo docker login -u $IMAGE_REPO_USER -p $IMAGE_REPO_PASSWD $(echo $IMAGE_REPO | awk -F '/' '{print $1}')git_commit=${output.Download_Code.GIT_LAST_COMMIT_SHA1}build_date=$(date -u +'%Y-%m-%dT%H:%M:%SZ')image_tag="${env.GenerateNewVersion}-${git_commit:0:6}"echo "start build image - standard"new_image_repo="${IMAGE_REPO}"sudo docker build -t ${new_image_repo}:${image_tag} -f Dockerfile --build-arg ARCH="amd64" . sudo docker login -u $IMAGE_REPO_USER -p $IMAGE_REPO_PASSWD $(echo $IMAGE_REPO | awk -F '/' '{print $1}')sudo docker push ${new_image_repo}:${image_tag}echo "end to build image - standard"echo "amd64ImageName=${new_image_repo}:${image_tag}" > ./amd64_output# 重新命名一个新镜像,供下级dockerfile进行多阶段构建时直接copysudo docker tag ${new_image_repo}:${image_tag} jdos-etcd-restore-helper:latest# 条件性选择构建基于kylinv10OS的镜像if [[ -f Dockerfile.kylinv10 ]];thenecho "start build image - security - kylin base"new_image_repo="${IMAGE_REPO}-kylinv10-amd64"sudo docker build -t ${new_image_repo}:${image_tag} -f Dockerfile.kylinv10 --build-arg ARCH="amd64" . sudo docker login -u $IMAGE_REPO_USER -p $IMAGE_REPO_PASSWD $(echo $IMAGE_REPO | awk -F '/' '{print $1}')sudo docker push ${new_image_repo}:${image_tag}echo "end to build image - security - kylin base"echo "amd64KylinImageName=${new_image_repo}:${image_tag}" >> ./amd64_outputfi# 条件性选择构建基于欧拉OS的镜像if [[ -f Dockerfile.oel22 ]];thenecho "start build image - security - openeuler22 base"new_image_repo="${IMAGE_REPO}-openeuler22-amd64"sudo docker build -t ${new_image_repo}:${image_tag} -f Dockerfile.oel22 --build-arg ARCH="amd64" . sudo docker login -u $IMAGE_REPO_USER -p $IMAGE_REPO_PASSWD $(echo $IMAGE_REPO | awk -F '/' '{print $1}')sudo docker push ${new_image_repo}:${image_tag}echo "end to build image - security - openeuler22 base"echo "amd64Oel22ImageName=${new_image_repo}:${image_tag}" >> ./amd64_outputfi# 清理builder镜像,避免产生none垃圾镜像。sudo docker rmi jdos-etcd-restore-helper:latest --force

提升

基于以上,构建时间从21min缩短至7min,构建效率提升66%👊。我们总结出“OneBuild”方法:即构建一次,多处使用的思路。

标准化的shell与dockerfile进行配合,能够做到一次构建,多处使用。提升了构建效率。

讨论

上述完整介绍了多个镜像构建的流程和设计规范,也说明“OneBuild”可以进行快速构建的优点。所以OneBuild的对于中大型组织或者有快速交付需求的团队来讲,是非常有帮助的。

并且对效率的提升是可以看得见的。

作者:京东科技 王晓飞

来源:京东云开发者社区 转载请注明来源

这篇关于【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/343810

相关文章

基于MySQL Binlog的Elasticsearch数据同步实践

一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

百度/小米/滴滴/京东,中台架构比较

小米中台建设实践 01 小米的三大中台建设:业务+数据+技术 业务中台--从业务说起 在中台建设中,需要规范化的服务接口、一致整合化的数据、容器化的技术组件以及弹性的基础设施。并结合业务情况,判定是否真的需要中台。 小米参考了业界优秀的案例包括移动中台、数据中台、业务中台、技术中台等,再结合其业务发展历程及业务现状,整理了中台架构的核心方法论,一是企业如何共享服务,二是如何为业务提供便利。

电脑桌面文件删除了怎么找回来?别急,快速恢复攻略在此

在日常使用电脑的过程中,我们经常会遇到这样的情况:一不小心,桌面上的某个重要文件被删除了。这时,大多数人可能会感到惊慌失措,不知所措。 其实,不必过于担心,因为有很多方法可以帮助我们找回被删除的桌面文件。下面,就让我们一起来了解一下这些恢复桌面文件的方法吧。 一、使用撤销操作 如果我们刚刚删除了桌面上的文件,并且还没有进行其他操作,那么可以尝试使用撤销操作来恢复文件。在键盘上同时按下“C

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测