ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

CentOS 7 离线部署 GitLab 13.1.2 实战:Omnibus 安装、汉化与性能调优

CentOS 7 离线部署 GitLab 13.1.2 实战:Omnibus 安装、汉化与性能调优

1. 为什么在 CentOS 7 上装 GitLab 13.1.2 这件事值得单独写一篇

CentOS 7 的生命周期已经进入尾声,但现实情况是,大量中小团队的内网服务器、离线机房、测试环境里跑的还是 CentOS 7。GitLab 13.1.2 这个版本发布于 2020 年年中,属于 13.x 系列里相对稳定的一版,很多团队当年就是拿它做代码托管和 CI 起步的。现在回头看,这个组合有点"老将配老枪"的意思,但它依然有非常实际的价值:内网代码托管、离线环境部署、老硬件复用、以及作为升级到更高版本的跳板。

我前后在三四套不同的 CentOS 7 环境里装过 GitLab,从最开始的"照着官方文档一路回车"到后来被各种报错教育,踩过的坑足够写满一页纸。这篇内容就是把这些经验整理出来,面向的是需要在 CentOS 7 上落地 GitLab 13.1.2 的运维和开发同学,不管你是第一次装还是装到一半卡住了,都能从里面找到能直接用的东西。

需要先明确一点:GitLab 13.1.2 的安装方式有好几种,源码编译、Docker、Omnibus 包。在 CentOS 7 上,Omnibus 包是唯一值得推荐的方式,原因后面会详细说。这篇内容围绕 Omnibus 展开,把环境准备、安装、配置、汉化、常见报错、性能调优这几块讲透。

2. 装之前必须想清楚的几件事:版本、硬件与安装方式

2.1 为什么锁定 13.1.2 而不是直接上最新版

很多人会问,既然要装,为什么不装最新的?这里有几个现实约束。

第一是系统兼容性。GitLab 从 14.x 开始逐步收紧对 CentOS 7 的支持,到 15.x、16.x 基本要求 CentOS 8 或 Rocky/Alma 这类替代品。CentOS 7 的内核是 3.10,glibc 版本也偏老,新版本 GitLab 依赖的一些组件在这个环境下会出问题。13.1.2 是最后一个在 CentOS 7 上"原生舒适"的大版本区间之一。

第二是资源占用。GitLab 是个"全家桶",它把 Nginx、PostgreSQL、Redis、Gitaly、Sidekiq、Prometheus 这些组件全打包在一起。13.1.2 相比后来的版本,内存占用要温和一些。我实测过,13.1.2 在 4GB 内存的机器上勉强能跑起来,而 15.x 在同样配置下基本会 OOM。

第三是升级路径。GitLab 的升级有严格的路径要求,不能跨大版本乱跳。如果你现在装 13.1.2,未来想升到 14、15,是有明确升级链的;但如果一开始就装个中间版本,反而可能卡在某个升级节点上。

2.2 硬件配置的最低线和推荐线

GitLab 官方给的最低配置是 2 核 4GB,但这是"能启动"的线,不是"能用"的线。我把实际经验整理成下面这张表:

使用场景CPU内存磁盘说明
个人测试/学习2 核4GB20GB必须配 swap,否则容易 OOM
5-10 人小团队4 核8GB50GB推荐配置,日常使用流畅
20 人以上团队8 核16GB100GB+需要额外调优,考虑拆分组件
带 CI/CD 的场景8 核起16GB 起按构建量定Runner 最好独立部署

这里有个容易被忽略的点:磁盘 IO 比磁盘容量更重要。GitLab 的 PostgreSQL 和 Gitaly 对随机读写很敏感,如果用机械硬盘,clone 大仓库的时候会明显卡顿。条件允许的话,数据盘用 SSD。

2.3 Omnibus、Docker、源码编译三条路的取舍

我把三种方式的对比列出来,方便你做决策:

  • Omnibus 包:官方维护,一条命令安装,所有组件版本经过验证,升级方便。缺点是"黑盒"感强,出问题要翻日志。CentOS 7 首选。
  • Docker 部署:隔离性好,迁移方便。但在 CentOS 7 上,老版本 Docker 和 GitLab 镜像的兼容性需要额外验证,而且数据卷管理、端口映射对新手不友好。
  • 源码编译:能深度定制,但依赖管理极其痛苦,Ruby、Node、Go 各版本要求严格,编译一次大半天。除非有特殊定制需求,否则不要碰。

结论很明确:CentOS 7 + GitLab 13.1.2,走 Omnibus。

3. 环境准备:那些装完才后悔没提前做的事

3.1 系统基础配置与依赖补齐

拿到一台干净的 CentOS 7,别急着装 GitLab,先把地基打好。第一步是更新系统并装基础工具:

yum update -y yum install -y curl policycoreutils-python openssh-server openssh-clients systemctl enable sshd systemctl start sshd

policycoreutils-python这个包很关键,GitLab 安装过程中会用到semanage命令来配置 SELinux 策略,缺了它安装脚本会报错。很多人卡在这一步,就是因为最小化安装的 CentOS 7 没带这个包。

接下来处理防火墙。GitLab 默认用 80 和 443 端口,如果你改了端口,记得同步放行:

firewall-cmd --permanent --add-service=http firewall-cmd --permanent --add-service=https firewall-cmd --reload

注意:如果你的环境里 SELinux 是 enforcing 状态,GitLab 的安装脚本会自动配置相关策略。但如果之前手动改过 SELinux 配置,建议先确认状态,避免安装后服务起不来。

3.2 主机名、时区与 swap 的隐藏影响

主机名这件事看起来小,但影响不小。GitLab 生成的仓库地址、clone URL 都会用到主机名。如果主机名是默认的localhost,后面改起来很麻烦。建议提前设置:

hostnamectl set-hostname gitlab.internal echo "127.0.0.1 gitlab.internal" >> /etc/hosts

时区也要设对,否则 GitLab 里的提交时间、日志时间全是 UTC,排查问题时会很别扭:

timedatectl set-timezone Asia/Shanghai

swap是 4GB 内存机器的救命稻草。GitLab 的组件多,内存峰值容易冲高,没有 swap 的话 OOM Killer 会直接把进程干掉。创建 swap 的方法:

dd if=/dev/zero of=/swapfile bs=1M count=4096 chmod 600 /swapfile mkswap /swapfile swapon /swapfile echo "/swapfile swap swap defaults 0 0" >> /etc/fstab

这里有个经验:swap 大小建议是物理内存的 1 到 2 倍,但不要超过 8GB,太大反而拖慢系统。另外,swappiness参数可以调低一点,让系统尽量用物理内存:

echo "vm.swappiness = 10" >> /etc/sysctl.conf sysctl -p

3.3 安装源配置与网络连通性检查

GitLab 的 Omnibus 包体积不小,13.1.2 的包大概 700MB 左右。如果你的服务器不能直连外网,需要提前把包下载好传进去。能联网的话,配置好 yum 源,然后安装 GitLab 的仓库配置脚本:

curl -sS https://packages.gitlab.com/install/repositories/gitlab/gitlab-ce/script.rpm.sh | sudo bash

这个脚本会自动配置 yum 源。但要注意,它会拉取最新的仓库配置,如果你要装特定版本,后面用yum install时指定版本号即可。

网络检查这块,重点确认两件事:一是服务器能不能访问 GitLab 的包仓库,二是安装完成后客户端能不能访问服务器的 80/443 端口。前者用curl -I测,后者装完再测。

4. 正式安装:从拉包到首次登录的完整链路

4.1 指定版本安装与依赖解析

配置好源之后,安装命令要指定版本,否则会装成最新版:

yum install -y gitlab-ce-13.1.2-ce.0.el7.x86_64

如果提示找不到这个版本,可以先看看仓库里有哪些版本:

yum list gitlab-ce --showduplicates | sort -r

安装过程中,yum 会自动解析依赖。GitLab 的 Omnibus 包依赖不多,主要是openssh-server、postfix这类基础组件。如果卡在依赖上,多半是 yum 源的问题,检查一下/etc/yum.repos.d/下的配置。

安装完成后,先别急着启动。GitLab 的配置文件在/etc/gitlab/gitlab.rb,第一次启动前最好先改好外部访问地址,否则启动后再改要重新配置,耗时更长。

4.2 gitlab.rb 里真正需要改的那几个参数

/etc/gitlab/gitlab.rb这个文件有几千行,但真正需要动的就那么几个。我把它整理成表格:

参数默认值建议值作用
external_urlhttp://gitlab.example.comhttp://你的域名或IP外部访问地址
gitlab_rails['time_zone']UTCAsia/Shanghai时区
unicorn['worker_processes']自动内存GB数+1Web 工作进程数
postgresql['shared_buffers']自动内存的 1/4数据库缓存
prometheus_monitoring['enable']true小内存机器设 false监控组件开关

改external_url是最关键的一步。如果你用 IP 访问,就写http://192.168.x.x;如果有域名,写域名。注意这里不要带端口,除非你确实改了端口。

对于 4GB 内存的机器,强烈建议关掉 Prometheus 监控,能省下几百 MB 内存:

prometheus_monitoring['enable'] = false

改完配置后,执行重配置:

gitlab-ctl reconfigure

这一步会跑很久,5 到 15 分钟都正常,因为它要初始化数据库、编译资源、启动所有组件。期间不要中断,中断了可能要清理状态重来。

4.3 首次登录与初始密码处理

reconfigure跑完之后,检查服务状态:

gitlab-ctl status

看到所有组件都是run状态,就说明起来了。然后浏览器访问你配置的external_url。

GitLab 13.1.2 的初始密码处理有个变化:早期版本会把初始密码写在一个文件里,13.x 开始要求首次访问时直接设置 root 密码。如果你访问页面后没看到设置密码的界面,可以手动重置:

gitlab-rails console -e production

进入控制台后:

user = User.where(id: 1).first user.password = '你的新密码' user.password_confirmation = '你的新密码' user.save! exit

注意:密码至少 8 位,且不能是弱密码,否则保存会失败。控制台里操作要小心,改错了可能影响其他数据。

登录进去之后,第一件事是创建普通用户、建组、建项目,验证 clone 和 push 是否正常。这一步能跑通,说明基础功能没问题。

5. 装完之后的高频报错与排查思路

5.1 502 错误:Unicorn 没起来还是超时

502 是装完 GitLab 后最常见的报错。它的本质是 Nginx 转发请求给 Unicorn(GitLab 的 Web 服务),但 Unicorn 没响应。原因通常有三类:

第一类是内存不足。Unicorn 启动需要一定内存,如果机器内存被占满,进程起不来。排查方法:

free -h gitlab-ctl status

看 Unicorn 的状态,如果是down或者反复重启,基本就是内存问题。解决办法是加内存或加 swap,或者减少unicorn['worker_processes']。

第二类是启动超时。GitLab 首次启动时,Unicorn 要加载大量 Ruby 代码,如果机器性能差,可能超过 Nginx 的等待时间。这种情况等几分钟再刷新通常就好了。

第三类是配置错误。比如external_url写错、端口冲突。检查/var/log/gitlab/unicorn/下的日志,能看到具体报错。

5.2 邮件不发送:Postfix 与 SMTP 的配置陷阱

GitLab 默认用本机的 Postfix 发邮件,但本机 Postfix 发出去的邮件基本会被当成垃圾邮件,而且很多环境根本没配 Postfix。实际使用中,建议直接配置外部 SMTP:

gitlab_rails['smtp_enable'] = true gitlab_rails['smtp_address'] = "smtp.example.com" gitlab_rails['smtp_port'] = 465 gitlab_rails['smtp_user_name'] = "gitlab@example.com" gitlab_rails['smtp_password'] = "你的密码" gitlab_rails['smtp_domain'] = "example.com" gitlab_rails['smtp_authentication'] = "login" gitlab_rails['smtp_enable_starttls_auto'] = true gitlab_rails['smtp_tls'] = true gitlab_rails['gitlab_email_from'] = "gitlab@example.com"

改完reconfigure之后,可以用控制台测试发信:

gitlab-rails console
Notify.test_email('test@example.com', 'Test Subject', 'Test Body').deliver_now

如果报错,重点看密码是不是授权码(很多邮箱服务要用授权码而不是登录密码)、端口对不对(465 是 SSL,587 是 STARTTLS)。

5.3 磁盘涨得比预期快:日志与备份的清理

GitLab 跑一段时间后,磁盘会莫名其妙涨得很快。主要来源有三个:

  • 日志:/var/log/gitlab/下的日志,尤其是 Nginx 和 Sidekiq 的,默认不轮转或轮转周期长。
  • 备份:如果你配了自动备份,/var/opt/gitlab/backups/会堆积。
  • Prometheus 数据:如果没关监控,/var/opt/gitlab/prometheus/会持续增长。

处理办法:在gitlab.rb里配置日志轮转,定期清理备份,小内存机器直接关掉 Prometheus。另外,/var/opt/gitlab/gitlab-rails/uploads/和shared/目录也会随使用增长,要纳入监控。

6. 汉化、调优与日常维护的实战经验

6.1 汉化包的获取与版本匹配

GitLab 官方不带中文,需要自己打汉化补丁。汉化包的版本必须和 GitLab 版本严格对应,13.1.2 就要找 13.1.2 的汉化包,差一个小版本都可能出问题。

汉化的基本流程是:下载对应版本的汉化包,覆盖到 GitLab 的安装目录,然后重新编译资源。具体路径和命令因汉化包而异,核心是先备份原文件,出问题能回滚。

注意:汉化后升级 GitLab 时,汉化会被覆盖,需要重新打。所以如果团队对中文界面不是刚需,建议直接用英文,省去维护成本。

6.2 针对小内存机器的参数调优

4GB 内存的机器要跑 GitLab,必须做减法。除了前面说的关 Prometheus,还有几个参数可以调:

unicorn['worker_processes'] = 2 unicorn['worker_timeout'] = 60 sidekiq['concurrency'] = 10 postgresql['shared_buffers'] = "512MB" postgresql['max_worker_processes'] = 4

sidekiq['concurrency']控制后台任务并发数,默认值偏高,小机器上降到 10 左右比较稳。postgresql['shared_buffers']设成内存的 1/4 左右,4GB 机器给 512MB 到 1GB。

调完这些,reconfigure一次,然后用free -h和gitlab-ctl status观察一段时间,确认稳定。

6.3 备份、恢复与升级前的准备动作

GitLab 自带的备份命令很好用:

gitlab-rake gitlab:backup:create

备份文件默认在/var/opt/gitlab/backups/。恢复的时候:

gitlab-ctl stop unicorn gitlab-ctl stop sidekiq gitlab-rake gitlab:backup:restore BACKUP=备份文件名 gitlab-ctl start

升级前一定要做两件事:一是完整备份,二是确认升级路径。GitLab 不能跨大版本升级,13.1.2 要升到 14.x,得先升到 13.x 的最后一个版本,再升 14.x 的第一个版本,一步步来。升级命令就是yum install指定新版本,然后reconfigure。

我在实际维护中最大的体会是:GitLab 的稳定性很大程度上取决于前期配置是否合理。装的时候多花半小时调参数,比后面出问题再救火划算得多。尤其是内存和磁盘这两块,小机器上一定要提前规划,别等 OOM 了才想起来加 swap。

另外分享一个小技巧:gitlab-ctl tail可以实时看所有组件的日志,排查问题时比一个个翻日志文件高效得多。配合gitlab-ctl status一起用,大部分问题都能快速定位。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进