一个gitlab的镜像草案

·

1 min read

Table of contents

背景

笔者所在的团队(目前已离职)是服务于移动客户端团队的一个CI/CD平台,内部叫做mPaaS,负责移动客户端从源码到App上架到应用市场的整个生命周期。mPaaS团队用的CI平台是Jenkins,Jenkins master部署在腾讯云上,Jenkins agent部署在笔者所在公司;源码使用公司自托管的gitlab,部署在腾讯云上,公司办公网与腾讯云使用专线打通。

问题

因为一些历史原因,有一些项目的repo达到GB级别,虽然挺无语但确是真实存在的,而且这还不是个案,百MB级别也有不少,虽然公司办公网有专线加持,但是gitlab是公司自己维护的,会有一些不稳定的情况发生,加之公司的出口带宽是有限的、gitlab是全公司共用的,这就导致有时候pull源码会非常慢,进而影响到构建效率。这个问题笔者也琢磨挺久的了,如果没有离职,下一Q应该会解决

草案

其实还挺容易想到的:用空间换时间,做一个gitlab的镜像。因为gitlab是共用的,而移动端的源码仓库是有限的,所以用gitlab这种重量级的方案做镜像并不划算,于是轻量级的git自托管平台gogs就进入了我的视野,当然,gogs需要部署在公司,因为构建节点也是在公司。思路明确,实现方案也就清晰了

image.png

  1. checkout

    由于源码的checkout使用的是团队自己编写的shell脚本,自然可以在checkout时判断repo是否有在gogs中存在对应的镜像副本,如果是,转到步骤2;如果不是则转到步骤3

  2. gogs

    虽然没有实际测过,但同在办公网中,git clone from gogs 自然是飞快,考虑到镜像存在同步不及时的问题,需要增加 git remote set-url origin gitlab这一步,因为git是增量下载,所以同步不及时的情况下,理论上下载也会比直接从gitlab上更快

  3. sync

    既然镜像仓库不存在,触发一次同步就好了,这次用不上,下次也用的着。

  4. 定时

    作为补充,gogs可以每隔一小时自动触发一次同步,这么做是为了最小化影响业务方,最大化借力gogs的镜像功能。

总结

其实还想过其它方案,比如架设一个p2p式的git文件系统,调研过d7y,总觉得过于复杂了,这个主要是给容器镜像用的,虽然文档上支持文件系统,但没有找到相关的最佳实践,而且终究还是跳不开镜像这一步,所以就放弃了。也考虑过给gitlab的目标repo增加webhook,用于触发gogs的同步,但始终需要业务方去支持,还存在不可控的风险。综合来看,从checkout脚本入手,再加上gogs加持,理论上源码pull这一步在时效上肯定会有所提高的,投入也不算大,不侵入业务,而且可以灰度进行,进一步降低了业务上的风险。可惜的是该草案还没来得及评审落地……不过到目前为止,笔者依然相信该草案是可行的。