
银河麒麟服务器操作系统V10-SP1部署gitlab服务年前接到一个任务在一台预装了银河麒麟服务器操作系统V10-SP1的机器上把GitLab私有代码仓库搭起来。机器配置不算高4核8G硬盘500G还要顺便跑一些别的服务。整体踩下来跟CentOS上装GitLab的流程大方向一致但麒麟系统的一些细节软件源、依赖、字体、服务管理方式确实有坑。这篇文章把从零到能正常用的完整过程记下来包含我踩过的坑和最终落地的配置给需要在国产化系统上部署GitLab的同学做个参考。先说结论GitLab在V10-SP1上是能稳定运行的关键是选对安装方式、合理分配内存、以及准备好排错手段。我这套环境跑的是gitlab-ce 16.x社区版开了LDAP对接公司账号体系未启用留接口日常十来个人使用完全没问题。下面按部署顺序一步步拆解。1. 部署前必须想清楚的几件事选型、硬件和版本策略1.1 为什么我选rpm安装而不是docker容器化网上大量教程会让你在麒麟系统上用docker跑gitlab毕竟docker镜像一条命令就能拉起来。但我个人强烈建议在国产化系统的生产环境里优先用rpm包安装理由有三个第一依赖关系更干净。GitLab本体依赖PostgreSQL、Redis、Nginx、Ruby等组件docker方式把这些都封装在镜像里表面上省事但一旦出问题排查链路非常绕容器日志、宿主机端口映射、卷挂载权限而且GitLab官方对docker里跑PostgreSQL的支持其实声明过不推荐用于生产。第二版本可管可控。rpm方式安装的是系统级服务systemd能直接管理升级时gitlab-ctl自带的升级流程走得很顺。docker方式升级时要换镜像、还要考虑数据卷兼容性之前我遇到过一次大版本升级后容器起不来折腾一晚上的经历至今难忘。第三银河麒麟和rpm生态天然契合。麒麟V10-SP1本身走的就是RHEL/CentOS那条生态路线用rpm装GitLab相当于系统层面的原生应用权限、启动、日志、开机自启都跟系统其他服务一致运维习惯不用切换。1.2 硬件配置底线和预期管理GitLab是吃内存大户官方文档明确写着4GB内存是起步线8GB才建议用于生产。我实测下来的体感是2核4G能装能跑但页面加载明显卡顿push代码时会有延迟跑gitlab-ci的时候内存会飙到90%以上可能会触发了OOM killer4核8G日常代码托管、几十人团队正常浏览和push完全流畅跑小规模CI也扛得住8核16G及以上可以放开手脚跑gitlab-ci多并发或者同时承载Jenkins等周边服务磁盘方面代码仓库本身不大但GitLab的仓库存储、数据库、日志、缓存加起来增长挺快建议给/var/opt/gitlab单独分区至少100G大团队按200G起步规划。1.3 GitLab版本怎么选别迷信最新版安装时GitLab已经出到了17.x但我选择了16.x版本。原因是GitLab大版本升级例如16升17有严格的路径限制——必须逐级升级不能跨版本跳变。如果直接装最新版后续官方升级策略一变升级路径会非常痛苦。而且社区版CE和商业版EE要从第一步就定清楚。个人或中小团队直接用CE就够CI/CD、代码审查、里程碑这些功能都有。EE的企业级功能如果以后有需求同一个版本内可以导入license不需要重新部署这个机制比较良心。提示下载rpm包前先确认CPU架构。银河麒麟V10-SP1在x86_64和ARM64如华为鲲鹏、飞腾上都有对应版本gitlab-ce的rpm包同样区分x86_64和aarch64选错架构安装虽然也能装上因为有些包兼容但运行效率不对而且后续升级容易出现依赖不匹配。2. 麒麟V10-SP1系统环境初始化依赖、源和基础服务2.1 先确认系统版本和基础环境部署前先把系统和环境信息摸清楚避免后续定位问题的时候手忙脚乱# 查看发行版信息 cat /etc/os-release # 查看内核架构 uname -a # 查看内存和磁盘 free -h df -h # 查看SELinux状态 getenforce麒麟V10-SP1的输出示例大概是NAMEKylin Linux Advanced ServerVERSIONV10-SP1这也是银河麒麟高级服务器操作系统的标识。注意架构和内存在后面配置时都要用到。2.2 配置好软件源安装基础依赖GitLab的rpm包安装时会自动拉取依赖这时候软件源就非常关键。如果你的服务器能在互联网上访问推荐直接用清华镜像源GitLab官方源在国内访问太慢容易超时# 配置GitLab CE的yum源清华镜像 vim /etc/yum.repos.d/gitlab-ce.repo [gitlab-ce] nameGitLab CE Repository baseurlhttps://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7 gpgcheck0 enabled1注意baseurl里的el7银河麒麟V10-SP1兼容CentOS 7生态用el7的源。如果是CentOS 8生态的版本则用el8。不确定自己系统对应哪个的可以先执行yum repolist看看现有源里有没有以el7或el8结尾的路径。然后安装基础依赖yum install -y curl policycoreutils openssh-server openssh-clients postfix mailx这里必须把postfix装上GitLab要用它来发邮件注册确认、找回密码、CI通知等。装完以后顺手把服务启起来systemctl enable sshd systemctl start sshd systemctl enable postfix systemctl start postfix2.3 防火墙和SELinux的处理策略默认情况下麒麟V10-SP1的firewalld是开的SELinux是Enforcing状态。这两个不处理好GitLab装完会给你整出各种“门关着”的问题。防火墙放行HTTP/HTTPS端口firewall-cmd --permanent --add-servicehttp firewall-cmd --permanent --add-servicehttps firewall-cmd --reloadSELinux这一块我建议保持Enforcing状态而不是直接关掉安全基线要求高的环境尤其要避免粗暴setenforce 0给GitLab相关的端口打上放行策略# 查看当前的SELinux布尔值 getsebool -a | grep http # 放行GitLab使用的81端口如果你把external_url端口改成81的话 semanage port -a -t http_port_t -p tcp 81但说实话SELinux的布尔值对GitLab这种全家桶式的web应用覆盖不全如果你不想在排错上花太多精力可以先把SELinux设为Permissive模式临时不阻断但记录日志跑通流程后再根据日志收紧策略setenforce 0 sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config重要提示我这里最后是保持Permissive的生产环境如果安全要求高请结合等保基线自行评估。如果你确实要Enforcing记得装完GitLab后重点观察/var/log/audit/audit.log里的avc日志。2.4 时间同步是很多人忽略的坑GitLab对服务器时间非常敏感时间偏差超过一定范围登录会直接报错SSL证书验证会失败git push也会出现奇怪的证书校验错误。麒麟系统默认一般不保证时间同步如果机器没有接NTP你可能在首次登录时就遇到“sign_in页面500”的问题。# 安装chrony麒麟默认可能已经装了 yum install -y chrony # 启动并设置开机自启 systemctl enable chronyd --now # 查看同步状态 chronyc sources -vchrony默认配置的server如果没有国内容器源访问慢的话可以修改/etc/chrony.conf换成能访问到的NTP服务器。这个细节直接影响GitLab的SSO和令牌机制建议在所有服务器上都配好。3. 安装gitlab-ce两种安装路径和依赖坑3.1 方式一纯离线本地安装服务器无法联网时用很多内网服务器是要求隔离的无法连yum源。这种场景下推荐在能联网的机器上先把rpm包下载好然后拷贝到目标机器安装。GitLab的rpm包比较大约700M左右加上依赖一次拷全。下载rpm包推荐到清华镜像站手动拉取# 在能联网的机器上 wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-16.11.0-ce.0.el7.x86_64.rpm然后把rpm包传到目标机器上用yum localinstall安装会自动解析本地的依赖yum localinstall -y gitlab-ce-16.11.0-ce.0.el7.x86_64.rpm如果目标机器完全没有配置任何软件源那就比较头疼需要把所有依赖rpm也一次性下载齐全。这时候可以准备一台和麒麟系统版本大概一致的CentOS 7联网机器用yumdownloader把这些依赖拉下来yumdownloader --resolve --destdir/opt/gitlab-deps policycoreutils-python openssh-server openssh-clients postfix mailx cronie然后把整个目录拷到目标机器rpm -Uvh *.rpm一条条装。依赖个数大约有二三十个比较繁琐但确实可行。我帮客户做过一次全离线环境部署就是这种方式确实是能跑通的。3.2 方式二配置yum源后直接安装推荐能联网的话配置好源之后安装非常省心# 安装gitlab-ce yum install -y gitlab-ce安装过程会创建git用户、gitlab相关目录把默认配置文件放到/etc/gitlab下。整个过程约5-10分钟取决于网络速度和机器性能通过yum安装时的输出末尾会有“gitlab is not configured”之类的提示信息这是正常的。但是这里有个很大的坑银河麒麟V10-SP1预装的某些依赖包版本可能会和GitLab要求的版本冲突。最常见的是policycoreutils-python旧版本里的semodule命令路径不一致安装GitLab时可能出现如下提示Could not execute the below in a non-root environment: /usr/sbin/semodule ...处理方案很简单把coreutils相关的包升级一下然后重新执行后续步骤即可yum install -y policycoreutils-python-utils policycoreutils3.3 安装完成后先看一眼基础目录结构GitLab装完会建立一套自有的目录结构理解这套结构对后续排错非常重要目录/文件作用/etc/gitlab/gitlab.rbGitLab的集中配置文件所有组件都在这里调/var/opt/gitlab各组件实际数据和运行文件git-data、postgresql、redis等/var/log/gitlab各组件日志排错第一站/opt/gitlab安装的代码和命令gitlab-ctl就在这里/var/opt/gitlab/backupsgitlab-backup生成的备份目录尤其要记住/var/log/gitlab这个位置一会儿排错全靠它。4. 核心配置external_url、内存优化和邮件发送4.1 external_url怎么设IP还是域名安装完成后第一件事就是编辑/etc/gitlab/gitlab.rb核心配置项是external_url。这个字段决定了GitLab生成链接的base地址直接影响clone地址、webhook回调、CI/CD变量等多处行为。如果你的环境还没有域名只想先通过IP访问那么直接写IP地址。注意端口问题默认external_url是http://gitlab.example.com如果不改的话重新配置后GitLab会尝试把80端口占住。如果80端口已经被其他服务比如你的业务系统用了需要让GitLab换端口external_url http://192.168.1.100:81这里有三个细节需要说清楚第一external_url一旦确定后续修改是一个高影响操作。因为修改后GitLab会更新项目仓库的remote地址、webhook回调URL、runner注册地址还会重写数据库里的相关配置执行gitlab-ctl reconfigure耗时也比较长。所以一开始就规划好这个地址别三天两头改。第二如果用域名域名解析要提前准备好。如果只是临时用IP访问后续再切换到域名你会发现历史项目的clone地址全部变成了旧IP团队成员要手动改remote非常烦。第三端口选择要避开常见被占用的端口。8080端口经常被Jenkins、Nacos、Spring Boot应用占用81或8081相对安全些。4.2 内存优化不让GitLab吃光你的全部家当默认配置下GitLab各组件都是按“这台机器专门跑GitLab”的标准分配的。在8G内存的机器上默认配置跑起来效果并不差但如果你还打算在这台机器上跑别的服务就要做内存限制。我最终在4核8G机器上用了这样一套收敛配置# 关闭prometheus监控这是内存大户如果不需要监控 prometheus_monitoring[enable] false # 限制独占进程的数量 puma[worker_processes] 2 puma[min_threads] 1 puma[max_threads] 4 # sidekiq并发保持默认即可 sidekiq[max_concurrency] 10 # PostgreSQL缓存调小 postgresql[shared_buffers] 256MB postgresql[max_connections] 100 # 开启系统级swapprometheus_monitoring关掉以后内存能省接近600M。puma从默认的worker数通常是CPU核数1或更多降到2个worker在4核CPU上对并发影响不大但对内存影响非常显著。实测关掉prometheus、puma调成2个worker后GitLab整体常驻内存从3.8G降到2.5G左右日常使用完全流畅。另外swap建议预留4G。有时候CI构建或大型仓库操作瞬间内存冲高swap能兜底避免OOM直接杀进程导致502。4.3 Nginx端口冲突和hosts解析GitLab使用自带的Nginx作为入口。如果external_url里指定了端口Nginx会自动监听对应端口但这里有个小坑可能你的服务器上已经装了其他Nginx或服务占用了同端口gitlab-ctl reconfigure的时候就会报“address already in use”。如果不想让GitLab自带Nginx对外监听而是用你公司已有的Nginx网关来转发可以这样处理# 关闭GitLab自带Nginx nginx[enable] false # 让GitLab只监听本机端口 gitlab_rails[internal_api_url] http://127.0.0.1:81然后在你自己的Nginx配置里加一条反向代理转发到GitLab的监听端口。生产环境里很多公司确实是用统一Nginx网关接管所有域名这样证书、WAF、限流配置放在统一网关更可控。不过这不是必须项如果不存在端口冲突直接用GitLab自带Nginx省事得多。4.4 SMTP邮件配置让GitLab能发出通知GitLab默认用自带的postfix发送邮件如果你的环境里postfix可以正常发信端口25对外可达默认不用改。但如果你的网络环境封了25端口现在的机房非常常见或者公司有统一的企业邮件网关建议直接配置SMTPgitlab_rails[smtp_enable] true gitlab_rails[smtp_address] smtp.example.com gitlab_rails[smtp_port] 465 gitlab_rails[smtp_user_name] gitlabexample.com gitlab_rails[smtp_password] your-password gitlab_rails[smtp_domain] example.com gitlab_rails[smtp_authentication] login gitlab_rails[smtp_tls] true gitlab_rails[gitlab_email_from] gitlabexample.com gitlab_rails[gitlab_email_reply_to] noreplyexample.com这个配置改完以后怎么验证邮件能发两件事一是执行gitlab-ctl reconfigure确认配置生效二是在后台任意触发一个需要发邮件的动作比如邀请用户、重置密码。如果邮件发不出去去/var/log/gitlab/gitlab-rails/production.log里看有没有smtp相关的报错这是最高效的排查方式。5. 首次启动reconfigure、初始root密码和账号体系5.1 reconfigure到底做了什么配置改完以后执行gitlab-ctl reconfigure很多第一次接触GitLab的人以为reconfigure只是重启服务其实它的全名是“重新配置触发chef收敛”会按gitlab.rb里的配置重新生成各组件的配置文件创建数据库、执行迁移、刷新服务。这个动作会持续3-8分钟不等取决于机器性能和改动幅度中途不要CtrlC打断否则可能导致配置半应用状态服务起不来。看到输出末尾出现“gitlab Reconfigured!”字样才算结束。reconfigure完成后再执行gitlab-ctl status确保所有组件的状态是绿色的run。生产环境建议再看一眼端口监听情况ss -tlnp | grep 815.2 root密码设置和初始登录首次访问GitLab的web页面http://你的服务器IP:端口时会要求设置root管理员密码要求至少8位。设置完以后用root账号登录这就是你的管理员账户。要注意如果在访问页面时发现不需要设置密码就能直接进说明初始密码被自动生成了路径位于/etc/gitlab/initial_root_password这个文件会在首次reconfigure后24小时自动删除。如果过了这个时间才来看就只有重新找回root密码或重置root密码了。重置方法gitlab-rails runner user User.find_by(username: root); user.password 新密码; user.password_confirmation 新密码; user.save!5.3 创建组、项目和用户建议一开始就把规范定好GitLab的权限模型比Gitea/Gogs复杂核心是“组(Group) - 项目(Project) - 成员(Member)”三层加上可见性等级私有、内部、公开和角色Guest、Reporter、Developer、Maintainer、Owner。我的建议是团队内部强制走“组”管理项目不要在根目录散建项目。比如后端组一个Group前端组一个Group每个项目挂在组下面成员权限在组级别统一给项目里再按需调整。这样成员流转时离职、转岗只要在组里增删即可不然每个项目都要改一次权限运维起来非常痛苦。具体操作路径页面上创建GroupGroups - New group填写组名和可见性在组内创建ProjectNew project归属选刚才的组邀请成员Manage - Members按角色给权限5.4 SSH key配置别让团队成员走http密码登录GitLab支持HTTP(S)和SSH两种clone方式。开发机上建议统一用SSH key既安全又省去每次push输密码的麻烦。配置流程不复杂但初次接触的人总有个误区以为要在GitLab服务器上生成key实际上是在开发者自己的电脑上生成公钥然后粘贴到GitLab的用户设置里。# 开发机本地生成密钥 ssh-keygen -t rsa -b 4096 -C 你的邮箱 -f ~/.ssh/id_rsa_gitlab # 查看公钥 cat ~/.ssh/id_rsa_gitlab.pub把公钥复制到GitLab右上角头像 - Preferences - SSH Keys粘贴保存即可。clone的时候用git clone git你的服务器IP:组名/项目名.git注意如果GitLab用的是非22端口SSH比如安装了默认sshd把22端口占用了需要在gitlab.rb里为GitLab SSH服务配置额外端口比如gitlab_rails[gitlab_shell_ssh_port] 2222然后clone地址就变成ssh://git服务器IP:2222/组名/项目名.git。很多踩坑的人在这里卡住因为默认sshd还占着22端口GitLab Shell的SSH需要另外开一个端口。6. 实测翻车记录502、中文乱码、时钟漂移和内存告罄6.1 502 Whoops先分清是入口问题还是后端问题几乎每个人第一次启动GitLab都会遇到502我也没例外。502是最常见的“入口正常但后端挂了”的错。排查时我遵循这样的顺序第一步看puma/web服务状态gitlab-ctl status如果有组件显示down比如puma或postgresql重点看对应日志gitlab-ctl tail puma gitlab-ctl tail postgresql第二步如果是postgresql没起来最常见的错误是共享内存不足或数据目录权限不对。日志里如果出现could not open shared memory file调整一下kernel的shared memory参数或者在postgresql配置里调小shared_buffers。第三步如果是puma反复重启查看日志有没有worker timeout或Memory allocation failed的提示。有的话说明puma的worker数配高了减少worker数或调大内存上限。6.2 ARM架构的坑aarch64上的内存分配异常身边有人用鲲鹏920ARM架构跑gitlab遇到的故障是gitlab-ctl reconfigure执行到postgresql初始化时会killed日志里没有明确报错。查来查去是ARM机器上特定版本内核某种内存碎片化导致PostgreSQL共享内存分配失败。当时的处理方案是postgresql[shared_buffers] 128MB postgresql[max_connections] 50 vim /etc/sysctl.conf # 增加 vm.max_map_count 262144 sysctl -p如果你用的也是ARM的麒麟版本建议在部署前就把这两个参数调低能省去很多麻烦。6.3 仓库页面中文乱码其实跟gitlab无关这个问题在微博和社区里出现频率极高——打开项目说明、commit信息中文全部变成方块或乱码。很多人以为是GitLab的问题折腾半天实际上是系统缺中文字体。检查方法fc-list | grep -i cjk\|wenquanyi\|noto大概率是空的。安装中文字体即可解决yum install -y wqy-microhei-fonts wqy-zenhei-fonts装完以后重启GitLab的nginx或者干脆重启整个gitlab-ctl restart中文就正常了。这类问题出现的原因是GitLab生成图片头像、图标、PDF导出等时依赖系统的字体渲染库系统里连一个中文字体都没有自然全变方块。6.4 磁盘写满GitLab的日志增长速度超乎预期跑了几个月后突然发现GitLab页面打不开git push报错“磁盘空间不足”。排查后发现是/var/log/gitlab下日志膨胀尤其是gitlab-rails/production.log和nginx/gitlab_access.log在团队活跃的时候一天能长到几个G。处理方案就是对日志做logrotate麒麟一般自带logrotate配置文件也生成了但默认周期可能偏长。调整gitlab的logrotatevim /etc/gitlab/gitlab.rb # 修改日志轮转 logging[logrotate_frequency] daily logging[logrotate_rotate] 14 logging[logrotate_compress] compress gitlab-ctl reconfigure另外建议在监控上加上磁盘使用率告警到80%就提前处理不要等写满了再救。这是没踩过的人不会理解的痛。6.5 gitlab-rake gitlab:check你的第一排错工具遇到各种奇怪问题可以先跑一把自检gitlab-rake gitlab:check这个命令会检查GitLab各组件状态、数据库、repo读写权限、时区等输出里会列出所有不正常的点。虽然有些检项偶尔会有误报比如SSH host key检查在某些环境下会标红但整体上能帮你快速定位80%的问题方向。比如你发现某个仓库clone权限异常而gitlab:check输出里很可能就直接显示“repo has invalid path”之类的信息省去大量盲查时间。7. 备份恢复与升级让服务活得更久7.1 备份策略数据丢了真的会砸饭碗GitLab的备份官方的工具是gitlab-backup。创建备份的命令# 创建备份 gitlab-backup create默认备份文件生成在/var/opt/gitlab/backups目录会包含整个数据库、所有仓库、附件、CI/CD相关数据。但是有一个很大的盲区备份不包含配置文件/etc/gitlab/gitlab.rb。恢复数据时如果配置文件丢了默认配置不匹配恢复出来的实例也起不来。所以这两个要分开备份# 手动备份配置目录建议加入cron cp -a /etc/gitlab /opt/gitlab-config-backup/我实际用的备份脚本每周日凌晨3点全量备份一份保留最近4份配置目录每天同步一次整体思路是备份数据 备份配置 异地归档三件事分开处理。7.2 恢复流程不完整还原会遇到的坑恢复的典型流程# 停止相关服务并恢复 gitlab-ctl stop puma gitlab-ctl stop sidekiq gitlab-backup restore BACKUP1643380800_2022_01_28_14.0.1恢复过程中会遇到交互式确认输入yes继续。注意恢复前要保证目标机器上的GitLab版本和备份时的版本一致否则数据库结构对不上恢复后可能报各种奇异错误。恢复完成后执行gitlab-ctl reconfigure gitlab-ctl restart gitlab-rake gitlab:check7.3 版本升级策略逐级走不要跳级GitLab的升级策略可以用两个字概括保守。升级路径规则如下小版本升级16.10 - 16.11可以直接升级大版本升级16.x - 17.0必须规划路径比如先升到16.11.x再升到17.0跨大版本15.x - 17.x必须先升到16.x的最后版本再升到17.x具体操作上# 查看当前版本 cat /opt/gitlab/version-manifest.txt # 停止相关服务 gitlab-ctl stop puma sidekiq # 升级先把版本锁定在目标版本 yum update gitlab-ce-17.0.0-ce.0.el7.x86_64 # 重新配置并启动 gitlab-ctl reconfigure gitlab-ctl start升级前务必备份一次完整数据 确认升级路径 阅读官方升级文档中对应版本的注意事项。不要贪心一次性跳好几个版本翻车概率极大。8. 长期运维的几条个人经验部署是一阵子的事运维是一辈子的事。GitLab跑起来之后有几个管理动作建议从一开始就养成习惯。第一管理员的账号不要日常使用。root账号只用来管理日常提交用普通账号否则一旦root的token泄漏或者passwd被改整个平台都危险。第二容器镜像库Registry功能如果不用就关掉。GitLab自带的Container Registry会占用大量磁盘和内存如果你的镜像都推到了专门的Harbor仓库不需要在GitLab里再开一份。关闭方式registry[enable] false第三Runner不要直接装在和GitLab同一台机器上。没有独立CI机器的情况下可以先装在一个但等团队规模上来后GitLab本身CI并发会一起把内存撑爆。规划时把CI执行机分开是更合理的方式。第四善用gitlab-rails runner做批量操作。比如批量调整项目可见性、批量添加用户到组一条runner命令就搞定比页面点几百次高效得多。最后说个不算秘密的经验部署完以后花半天时间把/var/log/gitlab下的日志目录结构和关键文件位置走一遍心里有个“哪里出问题去哪里看”的地图。GitLab内部组件多出了问题不是黑盒日志都摆在明面上只是很多人被“组件一大堆”吓到了不敢去看。这套部署流程我前后在麒麟V10-SP1上复现过好几次也帮朋友处理过ARM版的同类问题整体稳定性是够用的。把这台机器当作一台正经的代码托管服务器去配置和管理它会比你想象的更耐用。