GitLab 二次开发
GitLab 是常见的开源研发平台,很多企业有进行二次开发的需求,这里从开发、部署、维护三个阶段总结了一些实际经验,希望对你有帮助。
开发阶段
官方流程
要二次开发,首先需要一个源码修改的开发流程,要保证后续能轻松与上游同步,这个流程最好是跟上游一致。首先我们来看一下 GitLab 官方的开发迭代流程:
- 开发任务日常都在默认分支 master 下
- 当达到版本条件(比如 GitLab 每月版本)时,切出版本分支(命名
xxx-stable-ee
)供发版使用,每个次要版本一个分支 - 版本分支中会处理一些版本特有的任务,比如修改版本号和部署配置
- 所有提交默认分支仍然是 master,有需要则会同步到已有的版本分支中,这里可能会有冲突需要处理
二开流程
综上,我们想做二次开发并保持上游同步,我们需要这么做:
- 先定义两个上游一样的分支:主分支(
master-my
),版本分支(17-10-stable-my
) - 企业二次开发直接在主分支上进行(
master-my
),例如图里的三个功能提交 my feature x,主分支需要每个版本开始前同步上游:- 同步上游主分支: 这里需要找到上游版本分支切出来的那个 commit,就是图里的
17-10-base
,可以通过以下 git 命令找到:git merge-base --all master 17-10-stable-ee
- 同步上游主分支: 这里需要找到上游版本分支切出来的那个 commit,就是图里的
- 当需要发布我们版本时,切出版本分支(
17-10-stable-my
),然后同步上游对应版本代码:- 同步上游版本分支:比如你要二次开发的版本为 17.10.0,那就直接合并上游的 v17.10.0-ee
- 在我们版本分支上继续处理类似上游的发布任务,验证全部完成后打上我们的版本标签
v17.10.0-my
进行发布 - 上述的 my feature 3 可以并行在我们主分支上进行,由于这次发布是在之前切出来的,因此不包含这个功能
上述流程第一次见会觉得有点复杂?但实际上这已经是最精简的了,我们可能见过很多团队将各种不同源的分支进行相互合并,最终导致出现非预期的冲突甚至丢失代码的问题。仔细观察你会发现我们二开流程中的合并都是同源的,未来出现冲突也是很清晰容易解决的。
如果你做到上述流程,恭喜你实现了与 GitLab 官方中国版一致、稳定可靠的开发流程,他们的主分支和版本分支分别叫 main-jh
, 17-10-stable-jh
开发环境
确定好了开发流程,现在还需要搭建好一个开发环境。GitLab 组件较多,因此开发环境也比较复杂,官方单独为开发环境创建了两个项目:
官方推荐的仍然是 GDK 环境,对容器比较熟有能力自己处理一些问题的人也可以尝试用 GCK,我的体验是基本也是可以完成开发工作的。
对于 GDK 环境,建议直接从官方提供的虚拟机项目开始,不需要从零开始搭建,也不用担心弄坏你的主机环境。
部署阶段
对于二开这种需要长期修改源码的构建部署方案有 Omnibus 和云原生两种,以下是总结的一些对比:
Omnibus 方案
Omnibus 方案就是构建 Linux 安装包的方式,要从源码开始构建我们自己的包,可以参考官方文档 Building your own package。构建安装包完成后如果你使用容器部署,可以再使用官方 Dockerfile 构建镜像:omnibus-gitlab/docker
这个方案的优点有:
- 生成单一安装包,部署简单
- 支持功能最全,所有组件都可以通过这种方式进行配置
云原生方案
云原生方案就是 Kubernates 各组件分开定义维护的方式。要构建我们自己定制源码的包,可以参考官方文档:Building Images
这个方案的优点有:
- 精细化定制,构建发版时长大大缩短,比如二次开发只修改了 rails 组件,那么只重新构建 rails CNG 镜像即可发布
- 云原生支持最好,如果你是 K8s 部署环境,使用这个方案可以直接复用官方的部署配置,后续维护升级更可靠
维护阶段
开发和部署都解决了之后,剩下是考虑如何让系统更稳定可靠。在维护阶段,主要从热修复、自动化测试、容灾备份三个方面讲解。
热修复
首先 GitLab 是基础的研发平台,在工作时间对系统可靠性要求是很高的。如果出现一些紧急问题,完全走一遍上述的构建部署流程来修复,时间上可能不能接受。这里我们可以利用二次开发的好处,直接引入一个热修复功能。可以这样做:
- 修改 GitLab 源码,在布局页面中引入外部 JS 文件:haml
%script{src: "https://oss-server/index.js", defer: true}
- 上述的 oss-server 是一个公开的对象存储服务,用来存储实际热修复代码
- GitLab 安全策略有可能会禁止加载外部脚本,如果遇到控制台报错,可以对 GitLab 进行相关配置解决
自动化测试
GitLab 功能复杂,每次发版需要确保功能运行正常,实际上 GitLab 官方有完善的 QA 自动化测试,具体见项目 GitLab QA。
我们在二次开发之后,一个是希望修改的功能有效,还一个是要保证不能影响现有的功能。这个可以通过预发布环境加自动化测试来解决:
- 增加一个预发布环境,做为正式环境前的验证和跑自动化测试
- 根据官方指引,搭建 GitLab QA 项目,对预发布环境每日定时运行自动化测试,遇到错误及时通知到系统管理员
- GitLab QA 项目本身有完善的测试用例,对于我们修改了的功能,需要同步修改这些测试用例
容灾备份
根据对系统的要求和实际情况,可以逐步引入以下机制,增强系统的可靠性:
- 添加全量备份能力:
- 备份和恢复都需要做到自动化完成,减少人为操作造成的问题
- 恢复的自动化可以结合部署,添加一个容灾环境,实现最新备份的自动化还原。线上数据丢失或者遇到不可恢复问题,可以快速切换到该环境。
- 搭建 GEO 架构:
- 添加一个新的地理城市,全新搭建一个同样的 GitLab 系统,参考官方文档配置两个系统之间的 GEO 架构
- 如果你 GitLab 使用了外部数据库增强数据安全,则需要配合云厂商的数据库容灾使用,例如阿里云 PG 异地容灾
- 搭建了 GEO 架构后,升级版本时需要多注意 GEO 相关影响,比起单站点架构升级流程会复杂一些,请参考文档:Upgrading the Geo sites
一般的系统要求建议完成全量备份即可,继续进一步搭建 GEO 架构,会增加需要维护成本。不过如果以下功能的确很吸引你或者你的团队,就可以尝试了:
- 线上需要做到无延时故障恢复(这是 GEO 多站点最大的优势,多一套环境)
- 我的 GitLab 系统并发很高,需要区分主备流量,保证核心服务的稳定(可以将非核心的流量导向 GEO 备站点)
- 重大升级故障支持快速回滚(这个可以在重大升级前,暂停 GEO 备站点的同步来实现)
总结
以上就是 GitLab 二次开发的所有内容,我们先来回顾一下:
总结起来,就是对 GitLab 做二次开发,需要有一套健壮的开发流程,一个方便快捷的部署方案以及有一些可靠稳健的维护手段。