每工作日一、三、五早上07:45
准时为你带来最新产品资讯
CI/CD是提高软件开发效率和质量的重要措施。客户A拥有自建的CI/CD平台,集团内的业务系统必须对接该平台进行代码发版,并采用镜像化管理技术,将代码包发布到苍穹容器进行应用的启动。
本期案例便带你了解项目上如何基于上述客户诉求,对接第三方CI/CD平台,实现苍穹代码自动构建与发布。
1 业务背景
CI/CD,即持续集成和持续交付或持续部署,是一种软件开发实践,旨在通过自动化的软件构建、测试和部署流程,从而提高开发效率和软件质量。
客户A拥有自建的CI/CD,属于一套完整的构建发布平台。全集团内重要的业务系统必须对接客户的CI/CD平台进行代码发版,且要求使用镜像化技术,将代码包制作成镜像文件,并发布到苍穹容器进行应用的启动,以达到统一管理和监控的要求。具体诉求如下:
1. 客户业务系统需要对接自建CI/CD平台进行代码构建并发布,实现版本发布、功能回退以及统一管理和运维的目标。
2. 舍弃常规在线拉包下载到容器的方式,采用最新的镜像化管理,把容器所需要加载的包提前拉取到镜像。
3. 客户的CI/CD平台需要对接在线发布,支持制作镜像文件后发布到对应苍穹的微服务中启动。
4. 上线代码需要进行代码扫描,提前发现业务缺陷,提升代码质量。
通过需求分析,我们梳理了方案需要解决的4个要点:
1. 基于苍穹标准lib包进行代码实时拉取构建
苍穹版本迭代快,项目后期会有大量私包和补丁的更新,需要对平台和业务的lib进行实时拉取构建。
2. 使用Dockerfile制作新的镜像包,放弃使用标品的镜像及在线拉取过程
通过dockerfile命令把苍穹所需要的标准的jar包以及二开的jar包提前拉取制作成镜像文件,同时更改苍穹微服务的yml文件,使启动该服务的时候不再在线拉取appstore下的jar包。
3. 客户构建平台需要对苍穹实例进行状态实时监控,对异常实例进行告警通知,避免系统异常影响用户使用。
4. 集成客户系统CI工具,实现代码扫描和自动构建。
2 解决方案
2.1 方案整体思路
针对以上问题,如何基于客户的CI/CD平台,实现自动化构建镜像并发布至苍穹,可以从以下三个方面入手:
代码构建:通过gPaaS的在线下载入口,下载/mservice/lib下的所有的jar包至客户的CI平台进行代码构建。
制作镜像:在线拉取苍穹标准的jar包以及非标准产品的包,通过dockerfile制作成新的镜像,镜像名称自定义版本,方便后续管理和故障回退。
在线发布:客户CD平台调用gPaaS接口,发布到苍穹的微服务中启动。同时获取实例状态,读取循环10次,否则提示发布失败。
2.2 关键实现步骤
1. 代码构建
登录gPaaS>服务管理>mservice>连接容器,进入到容器内部,如下图所示:
在/mservice/lib路径下压缩biz、bos、trd、cus四个文件夹并下载,提供至客户的CI平台,选择对应的代码分支进行代码构建。
2. 制作镜像
在构建平台执行dockerfile语句把苍穹标准的jar包与非标准的jar包制作成新的镜像文件。
#镜像来源,从苍穹原本的镜像文件中获取并上传到客户的镜像仓库,后续可以从镜像仓库在线下载,需要注意网络权限是否放通。
FROM xxxx.com.cn/kingdee-fms/mservice:6.0.001
#自定义APPSTORE_URL的值,通常跟微服务yaml文件里面的appstore的值保持一致。
ARG APPSTORE_URL=http://10.81.68.232:8090/appstore/cosmic
#libs文件读取,lib文件中记录xml,对应目录的zip包等内容,lib文件需要跟服务器上的biz,bos,trd,cus这四个文件目录保持同一层级(lib文件内容如下图所示)。
ARG libs=bos.lib,wfs.lib,isc.lib,rpac.lib,.bizcommon.lib,ai.lib,bamp.lib,data.lib,bsc.lib,bos-up.lib,fi.lib,pmgt.lib,scmc.lib,scm.lib,mpscmm.lib,hr.lib,hrmp.lib,odc.lib,swc.lib,sit.lib,wtc.lib,hros.lib,tsc.lib,epm.lib,tmc.lib,ebg.lib,mmc.lib,taxc.lib,occ.lib,drp.lib,qmc.lib,macc.lib,imc.lib,kye-trd.lib
需要注意的是,有一个特殊的隐藏文件.bizcommon.lib也需要放在当前目录下,否则dockerfile会执行失败。
#设置has_download_libs、libsconfigpath参数后,容器启动不再在线拉取appstore的内容,以镜像原有的文件启动。
ENV has_download_libs=true
ENV libsconfigpath=/appstore
#执行源镜像文件里面的kd-appstore-download-1.0.jar,实现在线拉取服务器上的原苍穹标准的jar包至镜像文件。
RUN cd /mservice/bin && java -jar ./kd-appstore-download-1.0.jar
#复制二开的jar包至cus目录下(客户场景是把dockerfile文件放在构建出来的二开代码包目录下执行,实际jar文件目录可根据实际情况自定义)。
COPY *.jar /mservice/lib/cus/
# docker build镜像制作,通过dockerfile文件制作镜像文件,可以自定义镜像名称,便于后续区分镜像版本。
docker build --no-cache=true -f bosbase_Dockerfile -t ${IMAGE_REGISTRY_URL}/${IMAGE_REGISTRY_PROJECT}/mservice-bos-base:${BASIC_IMAGE_TAG} .
#执行docker push命令,把制作成功的镜像推送至客户的镜像仓库
Docker push ${IMAGE_REGISTRY_URL}/${IMAGE_REGISTRY_PROJECT}/mservice-bos-base:${BASIC_IMAGE_TAG}
3. 在线发布
在客户的CD平台编写对应的脚本,实现点击发布后执行调用gPaaS接口的语句,使构建好的镜像发布至对应环境的微服务上。
脚本示例如下:
##替换镜像更新服务
KCS_EDIT_RESPONSE=(curl -k -g -i -X POST https://IP/kcs/capi/service/edit?pid=10000\®ion=ierp-cluster\&sname=mservice\&namespace=ierp-cluster\&image_url=xxxx.com.cn/kingdee-fms/mservice-bos-base:latest -H "X-Console-Ukey:fAhB3PxN3xHO5H7N0xKkk91u8u3y0hbSIhCrQTsWnf8=")
# 解析接口返回结果中的errcode段值
KCS_EDIT_ERROR_CODE=$(echo "$KCS_EDIT_RESPONSE" | grep -o '"errcode": [0-9]*' | cut -d' ' -f2)
if [ "$KCS_EDIT_ERROR_CODE" != "0" ]; then
# 输出description和更新失败信息
# description=$(echo "$KCS_EDIT_RESPONSE" | grep -o '"description": "[^"]*"' | cut -d'"' -f4)
echo "Restart service failed"
exit 1
fi
# 调 kcs 接口获取容器实例状态
POD_STATUS_RESPONSE=(curl -k -g -i -X GET https://IP/kcs/capi/service/containers?pid=10000\®ion=ierp-cluster\&sname=mservice\&namespace=ierp-cluster\&image_url=xxxx.com.cn/kingdee-fms/mservice-bos-base:latest -H "X-Console-Ukey:fAhB3PxN3xHO5H7N0xKkk91u8u3y0hbSIhCrQTsWnf8=")
POD_STATUS_ERROR_CODE=$(echo "$POD_STATUS_RESPONSE" | grep -o '"errcode": [0-9]*' | cut -d' ' -f2)
POD_STATUS=$(echo "$POD_STATUS_RESPONSE" | grep -o '"status": "[a-zA-Z]*"' | cut -d'"' -f4)
if [ "$POD_STATUS_ERROR_CODE" != "0" ]; then
# 输出description和更新失败信息
# description=$(echo "$POD_STATUS_RESPONSE" | grep -o '"description": "[^"]*"' | cut -d'"' -f4)
echo "Get containers status failed"
exit 1
fi
if [ "$POD_STATUS" != "Running" ] ;then
echo "ServerStatus = $POD_STATUS"
retry=`expr $retry + 1`
echo "retry = $retry times"
sleep 3
else
echo "Replace image success"
break;
fi
#重试10次
if [ $retry == 10 ];then
echo "retry exit"
exit 1
fi
done
3 方案效果
样例演示:
客户的CI/CD平台配置好脚本后,可在前端自动构建并发布至苍穹微服务启动。
4 方案的可复用价值
行业的普适程度
该方案通过脚本的形式融入客户的构建平台,实现苍穹的自动CI/CD,对客户的构建平台侵入性低,适配程度高,可扩展性强,但需要配合苍穹的gPaaS使用。
对客户的价值
可在自建的平台进行发版控制,显著缩短代码提交到生产环境的时间,通过自动化运维操作,减少人工干预,降低运维成本,提高整体工作效率,满足客户统一运维及管理的要求。
备注:该方案暂时无法支持元数据的CI/CD,只支持代码层面的自动构建。
#往期推荐#
对文章有任何疑问或建议,欢迎评论区留言~