2. GitLab平台架构与治理对象盘点

要对GitLab做运营治理,第一步不是打开后台改配置,而是先把“平台里到底有哪些东西、它们怎么连、谁管谁”画清楚。GitLab不是单一应用,而是一套由多个组件、多种存储、多层权限叠加而成的平台。治理对象识别不清,后续的配额、审计、成本分摊、权限收敛都会落空。本节从整体架构、组件构成、数据模型、权限模型四个角度切入,最终落到“关键治理对象与边界”的盘点方法上。

一、整体架构:从请求入口到数据落盘

GitLab的典型自建部署(Omnibus或Helm Chart)在逻辑上可分为四层:接入层、应用层、数据层、支撑层。接入层由外部负载均衡与Nginx(或GitLab Workhorse前置)承担TLS终止、路由分发;应用层是核心,包含Puma承载的Rails应用(Web/API)、Sidekiq异步任务、Gitaly(Git仓库访问服务)、GitLab Shell(SSH Git操作)、Container Registry、Runner等;数据层包括PostgreSQL(元数据)、Redis(缓存与队列)、对象存储(附件、制品、LFS、备份);支撑层则是Prometheus监控、日志、备份与升级通道。

理解这张架构图的意义在于:治理动作往往发生在“层与层的接缝处”。例如限流发生在接入层,配额与权限校验发生在应用层,仓库容量治理落在Gitaly与对象存储,审计日志则横跨应用层与数据层。下面这张图把组件、数据流与治理关注点放在同一张视图里,便于后续逐项盘点。

GitLab 平台架构与治理对象视图 接入层 外部 LB / TLS 限流 · 证书 Nginx / Workhorse 路由 · 上传缓冲 SSH 入口 GitLab Shell 治理关注:访问策略、限流阈值 IP 白名单 · 速率限制 应用层 Puma (Rails) Web / API / 权限校验 Sidekiq 异步任务 · 队列 Gitaly Git 仓库读写 Registry / Runner / Pages 制品 · 流水线 · 静态站点 治理关注:命名空间配额、项目可见性、Runner 标签与并发、流水线策略 成员角色 · 保护分支 · 审批规则 · 制品保留期 数据层 PostgreSQL 用户 · 项目 · 权限元数据 Redis 缓存 · 会话 · 队列 对象存储 附件 · LFS · 制品 · 备份 治理关注:容量 备份 · 保留 · 归档 支撑层 Prometheus / 日志 备份 / 升级通道 治理关注:审计日志留存、SLO 指标、变更窗口 治理边界:接入层管“进得来”,应用层管“用得对”,数据层管“存得住”,支撑层管“看得见”

二、组件构成与治理归属

把架构落到可盘点对象,需要一份组件清单。下表按“组件—职责—治理归属”三列整理,便于在运营中明确谁负责什么。示例中的归属角色为常见分工假设,实际组织可按自身团队结构替换。

组件核心职责治理归属(示例)
Nginx / WorkhorseTLS、路由、上传缓冲、限流平台接入组
Puma (Rails)Web/API、权限校验、业务逻辑平台应用组
Sidekiq异步任务、邮件、导入导出平台应用组
GitalyGit 仓库读写、仓库存储代码存储组
GitLab ShellSSH Git 操作、密钥校验平台接入组
Container Registry镜像存储与拉取制品治理组
Runner流水线执行、并发调度CI/CD 治理组
PostgreSQL元数据、权限、审计记录数据库组
Redis缓存、会话、队列数据库组
对象存储附件、LFS、制品、备份存储治理组

三、数据模型:治理对象从哪里来

GitLab的数据模型以命名空间(Namespace)为骨架。顶层是群组(Group),群组可嵌套子群组,群组之下是项目(Project)。项目是绝大多数治理动作的最小单元:仓库、议题、合并请求、流水线、制品、成员都挂在项目上。用户(User)通过成员关系(Membership)与群组或项目关联,成员关系携带角色(Role)。此外还有实例级对象:用户、应用(OAuth/SCIM)、Runner、License、系统钩子等。

理解这个层级的意义在于:配额、可见性、权限继承都沿“实例→群组→子群组→项目”这条链传递。例如在群组层设置“禁止创建公开项目”,其下所有子群组和项目都会继承该限制,除非在更下层被显式覆盖。治理盘点时,必须记录每个对象的“归属路径”,否则无法判断一条策略到底作用在哪些项目上。

四、权限模型:五级角色与可见性叠加

GitLab的权限由“角色 + 可见性 + 保护规则”三者叠加决定。角色从低到高为:Guest、Reporter、Developer、Maintainer、Owner。角色决定“能做什么”,可见性(Private/Internal/Public)决定“谁能看到”,保护分支/保护标签、合并请求审批规则、推送规则则决定“在具体操作上是否被拦截”。

一个常见误区是只看角色不看可见性。例如某项目为Internal,则任何登录用户都能看到该项目,即使其角色只是Guest。治理时若要求“项目仅限本部门可见”,就必须同时检查可见性设置与成员列表,而不是只调整角色。另一个误区是忽略继承:子群组会继承父群组的成员与权限,若父群组给某用户Maintainer,则该用户在其下所有项目中都拥有Maintainer,除非在项目层被显式覆盖。

盘点权限时建议按“实例级→群组级→项目级”三层分别导出成员清单,再与角色矩阵比对,避免只查项目层而漏掉群组继承带来的越权。

五、关键治理对象与边界盘点

综合以上四层,可以把治理对象归为五类,并明确各自的边界:

  • 身份与访问对象:用户、群组、项目、成员关系、角色、Token、SSH Key、SCIM/OAuth应用。边界是“谁能进、以什么身份进”。
  • 代码与仓库对象:仓库、分支、标签、保护规则、LFS、子模块。边界是“代码怎么存、怎么改、怎么保护”。
  • 流水线与制品对象:Runner、流水线、作业、制品、镜像、缓存。边界是“构建怎么跑、产物怎么留、资源怎么耗”。
  • 数据与存储对象:PostgreSQL、Redis、对象存储、备份、归档。边界是“数据存哪、留多久、怎么恢复”。
  • 审计与合规对象:审计事件、登录日志、系统钩子、License、合规框架。边界是“发生了什么、能否追溯、是否合规”。

盘点的落地做法是:先按上述五类列出对象清单,再为每个对象标注“归属路径、当前配置、责任人、治理动作”。例如“项目A的保护分支”属于代码与仓库对象,归属路径为“群组X/子群组Y/项目A”,当前配置为“main分支仅Maintainer可推送”,责任人为代码存储组,治理动作为“季度复核保护规则是否与分支策略一致”。

边界不清是治理失效的首要原因。典型表现是:限流策略只配在Nginx却未在应用层做配额,导致绕过入口的API调用不受控;或只治理项目层权限却忽略群组继承,导致成员实际权限高于预期。盘点时必须同时覆盖“配置位置”和“生效范围”两个维度。

完成本节盘点后,你应当能够回答三个问题:平台由哪些组件构成、每个组件的治理归属是谁;数据模型如何决定治理对象的层级与继承;权限模型如何叠加决定实际访问结果。这三问是后续配额管理、审计、成本分摊与权限收敛的共同基础。