本文主要是提供基于Jenkins的软件自动构建/部署相关的规则、约束、最佳实践,为软件研发流程的自动化提供指导和建议。
相关工具的更详细的使用和操作方法请参考:
软件研发涉及到项目管理、编码、测试、部署、文档等内容,借助相应的软件研发工具可以帮助研发团队更高效的完成工作。要完成自动构建/部署等流程,需要先准备以下工具:
以上工具的安装、配置、使用请参考:软件研发基础工具。研发团队根据实际场景和需求可以选择使用具体哪些工具。
对应线上(正式环境)的代码,版本上线由测试人员确认,通知开发人员将对应上线版本合并至master分支并打tag,准备部署或更新至生产环境。
当开发在开发环境测试完成以后,合并到内部测试分支:test-版本号,将功能移交给内部测试人员进行测试,内部测试人员部署到内部测试环境进行测试。
当内部测试完成后,合并到生产测试分支:release-test-版本号,将分支提交到测试组,由测试组负责部署到生产测试环境进行测试。
当测试组完成生产测试全部工作后,对生产测试分支进行tag操作,并根据产品发布计划,基于tag进行生产发布。
软件的不同版本,或者插件的不同版本,在使用起来都有可能带来不可预知的影响,因此需要统一整理,固定下来,不允许轻易变更。
软件版本:
插件:一些插件非常重要,在某些版本中未必好用,比如用户权限控制插件,因此验证了当前好用的版本之后及时保存,以备扩容的时候可以用。
注意
插件的安装或升级在运维团队需严格管控,管理员安装插件时,务必与组内同步,先做评估,经过验证,再行安装或升级。因为一些插件的升级可能带来未知问题与影响。
Jenkins新增slave不要单独从头部署,需要和原slave保持一致:
需要注意,JENKINS_HOME应该统一配置,例如:
$ tail -n1 /etc/profile
export JENKINS_HOME=/data/jenkins_home
严禁非此标准的情况。
需要注意,我们的 WORKSPACE 统一在:
$ grep workspaceDir config.xml
<workspaceDir>${JENKINS_HOME}/workspace/${ITEM_FULL_NAME}</workspaceDir>
严禁非此标准的情况。
因为根目录磁盘并不大,所以要修改缓存目录到数据目录中,缓存目录统一存放在/data/.cache 目录之下,下一层目录以语言栈为标识。
如下列举了常见语言编译过程中缓存目录的设置方法。
maven
vim /usr/local/maven/conf/settings.xml
# 修改
<localRepository>/data/.cache/java/.m2/repository</localRepository>
node
$ npm config get cache
/root/.npm
# 设置 npm 全局包下载路径
$ npm config set prefix "/data/.cache/node/node_global"
# 设置 npm 缓存路径
$ npm config set cache "/data/.cache/node/node_cache"
pip
$ cat ~/.config/pip/pip.conf
[global]
cache-dir = /data/.cache/pip
go
export GOPATH=/data/go
export GOCACHE=/data/.cache/go-build
构建过程中,我们会依赖一些公共组件,或者共享库,这些内容都应该使用统一的目录或者仓库,从而便于统一维护与管理。在说具体约定之前,首先说一个前置约定,亦即所有第三方需要统一固定的目录,例如都应该在 /data/.jenkins/other之下。
要实现回滚,有赖于本地版本目录,此目录我们统一约定在:
$ ls /jenkins_sync/version/
剧本是项目在发布过程中使用的ansible剧本等内容。
关于命名,我们约定如下规范:
关于使用,我们约定如下规范:
共享库是为我们将项目模板提取出来之后提供的一种高效率方案。
关于命名,我们约定如下规范:
关于使用,我们约定如下规范:
我们约定统一的pipeline风格为声明式
,声明式是固定语法,接近原生shell的使用方式,对运维也更加友好。事实上这不仅仅是风格统一的问题,还可以做到研究成果共享。
项目命名规范,决定了权限配置的便利以及可用。项目命名原则上与gitlab仓库中项目命名保持一致,然后在前边添加环境作为区隔,如果项目名为admin,那么不同环境的命名应该为:
如果一个项目仓库将会部署多个子项目,那么命名风格应该保持队形:test-admin-(a/b/c)
,以此类推。
建议人员通过对接openLDAP、Gitlab等进行同步。
授权统一使用openLDAP用户分组绑定Jenkins权限角色的方式进行,不通过个人绑定角色。发布权限类似如下分类:
准确简洁的变量名是可读性及易维护性的重要保障,针对脚本的变量名应当至少遵循以下规范:
// 套娃式定义
def pathA = "path1"
def paraZ = "${pathA}/path2"
def paraB = "${pathZ}/path3"
def paraY = "${pathB}/path4"
def paraX = "${pathY}/path5"
// 展开嵌套, 具有更好的可读性
def paraX = "path1/path2/path3/path4/path5"
stage定义了每个节点的任务内容,应该使用简洁清晰的文字对该阶段任务进行注释。名字不能超过7个字,失败原因也要做到简单清晰。
如果使用容器,那么容器镜像的命名规则如下:
server_name commit date build_id
hub.hos.com/multienv/hos-back-admin:16c525_20201013114449_10
在实际使用中变量定义为:
BASE_IMAGE_NAME = "hub.hos.com/hos/${SERVICE_NAME}"
env.IMAGE_NAME = sh(script: "echo ${BASE_IMAGE_NAME}:" + "${COMMIT_ID}_" + "`date '+%Y%m%d%H%M%S'`" + "_${BUILD_ID}", returnStdout: true).trim() //构建版本号
建议尽可能的利用变量来组建项目镜像的tag,这在不影响构建稳定的情况尽可能地提供出有利于我们快速定位的信息,这将在后续问题排查中受益。