GitLab 运维与 CI 实践
GitLab 运维与 CI 实践
围绕 GitLab 攒的几块运维笔记:Releases 发布、Geo 副站、UI 解冲突、CI 分支过滤、Jenkins 拉 Shared Library。
GitLab Releases 发布流程
GitLab 的 Release 里挂版本包链接时,要求是 https 协议。所以如果自己搭了个内网下载服务器(比如 Tomcat),得先给它配上 https,否则链接填不进去。整体三步:搭 Tomcat → 配自签名证书走 https → 在 GitLab 上建 Release。
搭 Tomcat 当下载服务器
- 装 JDK,配好
JAVA_HOME、Path(加%JAVA_HOME%\bin)、CLASSPATH环境变量。java -version能输出版本就算装好。 - 下 Tomcat 免安装压缩包解压,配
CATALINA_HOME并把%CATALINA_HOME%\bin加进Path。 - 双击
bin\startup.bat启动(窗口别关),shutdown.bat停。浏览器开http://localhost:8080/能出页面就 OK。 - 把版本发布目录(例:
D:\MyProject_Release)设成共享文件夹并配好权限,再在 Tomcat 里建一个映射这个目录的配置,这样局域网里就能http://<server-ip>:8080/shareFolder/...访问到包了。
配 https
第一步搭的 Tomcat 是 http,而 Release 链接必须 https,所以要给 Tomcat 配自签名证书走 https。具体证书生成和 server.xml 配置网上 Tomcat https 教程很多,这里不展开。
在 GitLab 上建 Release
GitLab 官方文档:https://gitlab.example.com/help/user/project/releases/index
- 进项目的 Releases 页面创建 Release。
- 没有 tag 的话可以现场建一个新 tag,并选好对应分支。
- 填说明。上传版本包有两种方式:notes 里直接拖入文件,或在 URL 处填版本包的 https 链接(就是上面 Tomcat 提供的那个)。
- 保存即发布。
GitLab Geo 副站
Geo 是 GitLab 的异地副站方案,文档见 https://docs.gitlab.com/ee/administration/geo/index.html。副站支持 pull 和 push,但推大文件时必须切回主站(Primary Site),这是用 Geo 时最容易踩的坑。
申请副站
走 IT 工单要一台服务器,参考配置:
- CPU 4C8T
- 内存:16GB 物理 + 12GB swap
- 磁盘:50G 系统盘 + 500G 数据盘(可扩)
- 系统:AlmaLinux 8.6
拿到机器后再开一张工单给 IT,把这台机器和主站信息给他们,让他们把 Geo 副站搭起来。
本地在主站/副站之间切换
副站离自己近,日常拉代码快;但推大文件要切回主站。切换靠 git config 的 url.insteadOf 做地址改写。
全局切到副站(以下用占位符,换成自己环境的真实地址):
git config --global url."<Geo 副站>".insteadOf <主站 SSH 地址>
git config --global url."<Geo 副站>".insteadOf <主站 https 地址>
# 示例(占位地址):
git config --global url."git@gitlab-cd.example.com".insteadOf git@gitlab.example.com
git config --global url."https://gitlab-cd.example.com/".insteadOf https://gitlab.example.com/
全局切回主站(把上面加的改写规则删掉):
git config --global --remove-section url."<副站 SSH 地址>"
git config --global --remove-section url."<副站 https 地址>"
如果只想对单个仓库切换,不动全局,直接改 <your_repo_path>\.git\config 里对应的 url 段即可。
提醒一句:push 大文件前,务必确认当前指向的是主站。
在 GitLab UI 里解合并冲突
两个分支改了同一文件的同一部分,Git 没法自动合并时就产生冲突,文档见 https://docs.gitlab.com/ee/user/project/merge_requests/resolve_conflicts.html。
UI 上能解冲突的前提条件(任一文件不满足就只能本地解):
- 文件是文本,不是二进制
- 编码兼容 UTF-8
- 文件本身还没有冲突标记
- 加上冲突标记后文件不超过 200 KB
- 文件在两个分支里路径相同
操作逻辑是给每段冲突选 ours 或 theirs,全部标记完就能 resolve。resolve 等价于把目标分支合进源分支——若源分支是 feature、目标是 main,相当于本地执行 git checkout feature; git merge main。
一个限制:在 UI 上解冲突,结果只能提交到源分支,不能提交到目标分支,这是为了防止把目标分支搞不稳定。如果非要把解冲突后的结果落到目标分支,得在本地切到目标分支合并、解冲突、测试通过后再提交。
另外 GitLab 检测不到"重命名到不同路径"这类冲突。比如分支 a 做 git mv file1 file2、分支 b 做 git mv file1 file3,合并后两个文件都会存在,不报冲突。
CI Pipeline 按分支过滤 Job
用 only:refs 和 except:refs 控制 job 在什么分支或什么触发类型下才加进 pipeline,文档见 https://docs.gitlab.com/ee/ci/yaml/index.html(only / except 一节)。它是 job 级关键字,只能写在 job 里。
输入可以是:
- 分支名,如
main、my-feature-branch - 匹配分支名的正则,如
/^feature-.*/ - 下面这些预定义关键字:
| 值 | 含义 |
|---|---|
api | 由 pipelines API 触发的 pipeline |
branches | Git 引用是分支时 |
chat | 由 GitLab ChatOps 命令创建 |
external | 使用 GitLab 之外的 CI 服务时 |
external_pull_requests | GitHub 上外部 PR 创建或更新时 |
merge_requests | MR 创建或更新时触发(启用 MR pipeline、merged results、merge trains) |
pipelines | 通过 API 或 trigger 关键字创建的多项目 pipeline |
pushes | git push 事件触发(含分支和 tag) |
schedules | 定时 pipeline |
tags | Git 引用是 tag 时 |
triggers | 用 trigger token 创建的 pipeline |
web | 在 GitLab UI 里点 Run pipeline 创建的 |
only/except现在算是老语法,新项目更推荐用rules,但维护老.gitlab-ci.yml时还是会经常碰到。
Jenkins 用 GitLab 拉 Shared Library
让 Jenkins 从 GitLab 拉 Pipeline Shared Library,走 SSH 密钥认证,流程是生成密钥 → 上传 → 测试。
生成密钥
在 Jenkins master 机器上用 Git Bash 执行 ssh-keygen 生成公私钥。
上传密钥
- 把公钥上传到个人 GitLab 账号的 SSH Keys。
- 把私钥上传到 Jenkins 的 Credentials,注意类型要选 SSH(而不是 username/password)。
测试
- 在 Jenkins master 上
git clone一下目标仓库,目的是生成known_hosts(否则首次连接会卡在 host key 确认)。 - 如果用 TortoiseGit 拉,SSH client 要手动指向
C:\Program Files\Git\usr\bin\ssh.exe,别用它默认的 Plink——Plink 和上面生成的 OpenSSH 密钥格式对不上。