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

news2024/11/24 2:37:56

在云原生领域,无论使用哪种编排调度平台,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 ARCH

ARG BUILD_IMAGE

ARG BASE_IMAGE

FROM ${BUILD_IMAGE} as builder


ARG ARCH

ENV GOPATH=/go


COPY go.mod go.mod

COPY go.sum go.sum

COPY main.go main.go

COPY api/ api/

COPY controllers/ controllers/

COPY pkg/ pkg/

COPY vendor/ vendor/


# Build

RUN CGO_ENABLED=0 GO111MODULE=on GOOS=linux GOARCH=${ARCH} go build --mod=vendor -a -o manager main.go


ARG ARCH

ARG BASE_IMAGE

FROM ${BASE_IMAGE}


ENV PIP3_SOURCE=https://pypi.tuna.tsinghua.edu.cn/simple

ENV DEFAULT_FORKS=50

ENV DEFAULT_TIMEOUT=600

ENV DEFAULT_GATHER_TIMEOUT=600

ENV TZ=Asia/Shanghai

ENV PYTHONWARNINGS=ignore::UserWarning


WORKDIR /

COPY --from=builder /manager .


COPY inventory/ inventory/

COPY roles/ roles/

COPY etcd-restore.yml etcd-restore.yml

COPY facts.yml facts.yml

COPY requirements.txt requirements.txt

COPY inventory.tmpl.ini inventory.tmpl.ini

COPY ansible.cfg ansible.cfg


RUN 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 all


ENV LANG=zh_CN.UTF-8

ENV LC_ALL=zh_CN.UTF-8


RUN 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_SOURCE


USER root


ENTRYPOINT ["/manager"]



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

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

再看dockerfile.kylinv10


ARG BASE_IMAGE

FROM ${BASE_IMAGE}


ENV PIP3_SOURCE=https://pypi.tuna.tsinghua.edu.cn/simple

ENV DEFAULT_FORKS=50

ENV LANG=en_US.UTF-8

ENV DEFAULT_TIMEOUT=600

ENV DEFAULT_GATHER_TIMEOUT=600

ENV TZ=Asia/Shanghai

ENV PYTHONWARNINGS=ignore::UserWarning


WORKDIR /

COPY --from=jdos-etcd-restore-helper:latest /manager /


COPY inventory/ inventory/

COPY roles/ roles/

COPY etcd-restore.yml etcd-restore.yml

COPY facts.yml facts.yml

COPY requirements.txt requirements.txt

COPY inventory.tmpl.ini inventory.tmpl.ini

COPY ansible.cfg ansible.cfg


RUN 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_SOURCE


USER root


ENTRYPOINT ["/manager"]



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

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

再看Dockerfile.oel22


ARG BASE_IMAGE

FROM ${BASE_IMAGE}


ENV PIP3_SOURCE=https://pypi.tuna.tsinghua.edu.cn/simple

ENV DEFAULT_FORKS=50

ENV LANG=en_US.UTF-8

ENV DEFAULT_TIMEOUT=600

ENV DEFAULT_GATHER_TIMEOUT=600

ENV TZ=Asia/Shanghai

ENV PYTHONWARNINGS=ignore::UserWarning


WORKDIR /

COPY --from=jdos-etcd-restore-helper:latest /manager /


COPY inventory/ inventory/

COPY roles/ roles/

COPY etcd-restore.yml etcd-restore.yml

COPY facts.yml facts.yml

COPY requirements.txt requirements.txt

COPY inventory.tmpl.ini inventory.tmpl.ini

COPY ansible.cfg ansible.cfg


RUN 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_SOURCE


USER root


ENTRYPOINT ["/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进行多阶段构建时直接copy

sudo docker tag ${new_image_repo}:${image_tag} jdos-etcd-restore-helper:latest


# 条件性选择构建基于kylinv10OS的镜像

if [[ -f Dockerfile.kylinv10 ]];then

    echo "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_output

fi


# 条件性选择构建基于欧拉OS的镜像

if [[ -f Dockerfile.oel22 ]];then

    echo "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_output

fi


# 清理builder镜像,避免产生none垃圾镜像。

sudo docker rmi jdos-etcd-restore-helper:latest --force



提升

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

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

讨论

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

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

作者:京东科技 王晓飞

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1161911.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

HT3163 免电感滤波 音频功率放大器工作原理

HT3163是一款G效AB/D类音频功率放大器。在D类模式,18V供电、THDN10%条件下,能够持续提供40W/4Ω功率输出。在AB类模式,12V供电、THDN10%条件下,能够持续输出17W/4Ω功率。 HT3163具有防削顶失真(ACF)输出控…

第02章-变量与运算符

1 关键字 关键字:被Java语言赋予了特殊含义,用作专门用途的字符串(或单词)。如class、public、static、void等,这些单词都被Java定义好了,称为关键字。 特点:关键字都是小写字母;官…

中国长城-安全防护-硬件,软件,细粒度权限划分-等级保护,人员意识

目录 等级保护 安全防护 中国长城-安全防护 硬件,软件,细粒度权限划分-等级保护,人员意识 等级保护 安全防护 建立安全管理制度:制定信息安全政策,明确安全管理职责,建立安全培训和考核机制&#xff0c…

Mgeo:multi-modalgeographic language model pre-training

文章目录 question5.1 Geographic Encoder5.1.1 Encoding5.1.2 5.2 multi-modal pre-training 7 conclusionGeo-Encoder: A Chunk-Argument Bi-Encoder Framework for Chinese Geographic Re-Rankingabs ERNIE-GeoL: A Geography-and-Language Pre-trained Model and its Appli…

开发第一个flutter app的六个关键步骤

Flutter这些年发展的很快,特别是在 Google 持续的加持下,Flutter SDK 的版本号已经来到了 3开头,也正式开始对 Windows、macOS 和 Linux 桌面环境提供支持。如果从 Flutter 特有的优势来看,我个人认为主要是它已经几乎和原生的性能…

【嵌入式项目应用】__UART自定义通信协议代码实现方法

目录 前言 一、什么是通信协议 二、简单通信协议的问题 三、通信协议的常见内容 1. 帧头 2. 设备地址/类型 3. 命令/指令 4. 命令类型/功能码 5. 数据长度 6. 数据 7.帧尾 8.校验码 四、通信协议代码实现 1. 消息数据发送 a. 通过串口直接发送每一个字节 b. 通过…

16. 机器学习 - 决策树

Hi,你好。我是茶桁。 在上一节课讲SVM之后,再给大家将一个新的分类模型「决策树」。我们直接开始正题。 决策树 我们从一个例子开始,来看下面这张图: 假设我们的x1 ~ x4是特征,y是最终的决定,打比方说是…

十年JAVA搬砖路——Linux搭建Ldap服务器。

1.安装命令 yum -y install openldap compat-openldap openldap-clients openldap-servers openldap-servers-sql openldap-devel2.启动ldap systemctl start slapd systemctl enable slapd3.修改密码 slappasswd Aa123456获得返回的密码加密密码串: {SSHA}DkSw0…

SQLServer数据库透明加密 安当加密

安当TDE透明加密组件是一种用于数据保护的解决方案,它对数据进行加密,以防止未经授权的访问和数据泄露。 以下是安当TDE透明加密组件的主要功能介绍: 数据保护:安当TDE透明加密组件可以对数据库中的敏感数据进行加密,…

软件无线电处理平台解决方案:330-基于FMC接口的Kintex-7 XC7K325T PCIeX4 3U PXIe接口卡

基于FMC接口的Kintex-7 XC7K325T PCIeX4 3U PXIe接口卡 一、板卡概述 本板卡基于Xilinx公司的FPGAXC7K325T-2FFG900 芯片,pin_to_pin兼容FPGAXC7K410T-2FFG900 ,支持PCIeX8、64bit DDR3容量2GByte,HPC的FMC连接器,北京太速科…

TypeScript之命名空间与模块

一、模块 TypeScript 与ECMAScript 2015 一样,任何包含顶级 import 或者 export 的文件都被当成一个模块 相反地,如果一个文件不带有顶级的import或者export声明,那么它的内容被视为全局可见的 例如我们在在一个 TypeScript 工程下建立一个…

Linux 网络流量监控利器 iftop命令详解及实战

简介 iftop 是什么 在 Linux 系统下即时监控服务器的网络带宽使用情况,有很多工具,比如 iptraf、nethogs 等等,但是推荐使用小巧但功能很强大的 iftop 工具。 iftop 是 Linux 系统一个免费的网卡实时流量监控工具,类似于 top 命令…

智能防雷浪涌保护器的行业应用

智能浪涌保护器是一种能够自动监测和控制电涌保护器(SPD)的工作状态,实现SPD的自我保护和远程管理的设备。智能防雷是一种将云计算、移动互联网和物联网技术引入到综合防雷措施中,实现雷电预警、智能化防雷、智能化监测的系统。这…

群晖 | Synology Directory Server 批量导入用户 文件模板格式

目录 错误写法 正确写法 错误写法 在网上找到过类似的教程,但是一律都以失败告终: 正确写法 其实并不是只要写上前面的属性即可, 就算后面不写也需要使用 tab 补齐 ,所有的属性: 1.名称 2.密码 3.描述 4…

开源问答平台网站源码系统商业运营版源码系统 带完整的搭建教程

在我们现在的日常生活中,人们对于获取信息的需求越来越大,而问答平台作为一种快速、有效的信息获取方式,受到了广泛的关注和使用。同时,随着开源技术的普及和成熟,越来越多的开发者选择使用开源技术进行网站的开发和维…

几种常见的接地类型详解

接地作为一种应用最为广泛的电气安全措施,是指电力系统和电气装置的中性点、电气设备的外露导电部分和装置外导电部分经由导体与大地相连。接地的作用主要是防止人身遭受电击、设备和线路遭受损坏、预防火灾和防止雷击、防止静电损害和保障电力系统正常运行。按其功…

关于 iOS 报Multiple commands produceMultiple 错误的解决方案

今天在运行一个RN老项目的时候,报了一个下面的错误。 对应的信息如下: Multiple commands produce /Users/xzh/RN/work/cgv_app/ios/build/Debug-iphonesimulator/cgv_app.app/Entypo.ttf Multiple commands produce /Users/xzh/RN/work/cgv_app/ios/bu…

EASYX实现多物体运动

eg1:单个物体运动使用easyx实现单个小球的运动 #include <stdio.h> #include <easyx.h> #include <iostream> #include <math.h> #include <stdlib.h> #include <conio.h> #include <time.h> #define PI 3.14 #define NODE_WIDTH 4…

应用在阀门控制中的直流有刷驱动芯片

控制阀又称阀门&#xff0c;是流体运送系统中的控制部件&#xff0c;具有导流、截流、调节、节流、防止倒流、分流或溢流卸压等功能。阀门是一种用于控制流体&#xff08;液体、气体、粉体等&#xff09;流动的装置&#xff0c;广泛应用于工业生产、建筑、农业、能源等领域。 …

提高效率!5个顶级网页开发工具助你事半功倍!

1.WordPress–一站式网站建设工具 价格&#xff1a;基本版终身免费&#xff0c;个人版HK$30&#xff0c;高级版HK$63&#xff0c;商务版HK$1993 推荐指数&#xff1a;★★★★ WordPress是一个使用PHP语言开发的博客平台。它可以在PHP和MySQL数据库的服务器上设置自己的网站&…