k8s随笔-Jenkins+发布系统

为了实现PHP业务快速对接K8S系统,需要配套相关的构建与发布流程。

背景

公司原有一个发布系统(运维研发),是基于ansible批量分发代码到虚拟机,提供一个django实现的web console点鼠标发布程序。

基于设施现状以及人力情况,我对K8S发布项目的拆解如下:

  • 研发负责建设Jenkins的构建流程
  • 运维负责改造现有发布系统,对接Jenkins实现镜像打包,支持K8S应用发布

架构

关键在于对构建流程的抽象设计,以便用同一套构建流程适应所有应用。

下图是整体流程,在新窗口打开查看:

人为操作入口收敛在发布系统,Jenkins仅仅作为一个隐藏在背后的backend服务提供镜像打包流程。

为了打通两个系统,我选择以发布系统的一次构建任务ID为线索,通过Jenkins API传参到Jenkins内部的构建任务。Jenkins任务则可以调用发布系统获取对应构建任务的详细信息(发布系统配置的业务描述信息),就可以实现同一套CI流程适配多个项目的目的,即共享pipeline。

实现原理

针对PHP项目来说,整个Jenkins只需要创建一个pipeline项目,它们使用同一套构建流程,通过发布系统获取任务数据,以便实现多项目构建。

发布系统只需要传递本次构建的任务ID到Jenkins即可:

Pipeline定义非常简单,所有与发布系统、代码仓库、镜像仓库的交互逻辑全部实现在shell脚本中,部分逻辑用到了Python实现:

这里需要注意,因为所有PHP项目共享同一个Jenkins pipeline项目,所以需要调整1个重要参数:

  • quitePeriod:静默时间,也就是连续触发同一个pipeline可能受到静默处理,这里设置为0秒即可避免静默。

Jenkins对于一个pipeline的多个并发构建来说,会创建不同的workspace作为上下文环境,所以不需要担心并发冲突:



业务编译的deploy.tar.gz会解压到镜像内,在容器启动时会拉起业务脚本完成部署。

通用dockerfile:

prepare.sh完成服务拉起前的准备工作:

发布系统

发布系统在产生构建任务的时候需要填写本次构建任务是什么项目、什么分支、什么理由等关键信息。

因此,在Jenkins构建的末尾,会把构建任务ID与产生的镜像名回传给发布系统,这样发布系统就可以在mysql中按关系存储该镜像,并且明确记录该镜像属于什么项目、什么分支、什么理由。

其他

在定义镜像tag的时候,我选择了:业务代码commit id+timestamp的形式。

如果仅仅用commit id作为标识的话,当我们升级底层基础image并重新构建项目image的时候,就会覆盖掉之前的同名image,万一升级底层出现问题希望回滚就很麻烦了,所以引入了时间加以区分。

如果文章帮助您解决了工作难题,您可以帮我点击屏幕上的任意广告,或者赞助少量费用来支持我的持续创作,谢谢~