跳转至

RUNBOOK — GitLab

服务:GitLab EE v19.3.2(Helm chart gitlab-10.3.2,release gitlab,命名空间 server) 角色:代码托管 + CI/CD + 容器镜像仓库 + GitLab Agent 服务 部署档案见 SOP.md;命名空间总览见 ns_migration/RUNBOOK.md 最近更新:2026-09-19(2026-09-18 已由 4 个旧命名空间统一迁移到 server)

目录

1. 服务概览

GitLab 是一个多组件应用,由若干 Deployment / StatefulSet 组成,并依赖三个外部存储服务(PostgreSQL / Redis / MinIO)——它们都在同一命名空间 server 内。

组件 形态 副本 requests 作用
gitlab-webservice-default Deployment 1 500m / 2Gi Web 与 API(Puma)
gitlab-sidekiq-all-in-1-v2 Deployment 2 500m / 1536Mi 后台任务(CI、邮件、镜像清理)
gitlab-gitaly StatefulSet 1 — Git 仓库存储服务
gitlab-gitlab-shell Deployment 1 — / 6M SSH 协议入口(容器 22)
gitlab-registry Deployment 2 50m / 32Mi 容器镜像仓库
gitlab-kas Deployment 1 100m / 256Mi GitLab Agent(K8s 集群代理)
gitlab-toolbox Deployment 1 100m / 300Mi 运维工具箱(备份、恢复、rake)
gitlab-gitlab-exporter Deployment 1 75m / 100M 指标导出(9168)
envoy-gateway / envoy-server-gitlab-gw-* Deployment 1 / 1 100m / 512Mi 入口数据面(Gateway API,非 Traefik)

依赖组件(同在 server):

依赖 形态 存储 说明
PostgreSQL 17.6 CNPG Cluster/gitlab-pg pv-postgres-ssd 5Gi(local SSD) 用户/项目/CI 元数据
Redis 7.4 StatefulSet pv-redis-ssd 5Gi(local SSD) 缓存、会话、Sidekiq 队列
MinIO StatefulSet minio-data 50Gi(NFS) 对象存储:artifacts / LFS / uploads / packages / registry / backups(6 桶)

异常时的业务影响:Web 与 API 不可用、CI 无法执行、Git push/pull 失败、镜像拉取失败。不影响 LDAP、MariaDB、监控栈。

2. 接入与凭据

入口 地址 入口组件
GitLab 主页 / API https://gitlab.rainchen.top Envoy Gateway(Gateway gitlab-gw)
容器镜像仓库 https://registry.rainchen.top 同上
GitLab Agent(KAS) https://kas.rainchen.top 同上
SSH(git over ssh) kubectl -n server get svc envoy-server-gitlab-gw-80b44f81 的 22 端口 同上
集群内直连(排查用) http://gitlab-webservice-default.server.svc:8080 不走入口

公网暴露链路(隧道、TLS 终止)由 ingress_tunnel_deploy/ 主题承担,细节见该主题的 RUNBOOK;本手册只覆盖集群内这一段。

取用凭据(勿写入文档):

# root 初始口令
kubectl -n server get secret gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 -d; echo

# 依赖组件口令(PG / Redis / MinIO)
cat ns_migration/secrets/gitlab-credentials.env      # 权限 600

# 全部 GitLab 相关 Secret 名(只列名,不含内容)
kubectl -n server get secret | grep -E '^gitlab-' | awk '{print $1}'

3. 日常速查表

# 1) 全部组件是否健康(最常用)
kubectl -n server get deploy,sts | grep -E 'gitlab|envoy'
# 预期:gitlab-* 均 1/1 或 2/2;envoy-server-* 1/1

# 2) 非 Running 的 Pod(含原因线索)
kubectl -n server get pods | grep -E 'gitlab|envoy' | grep -vE 'Running|Completed'

# 3) 服务是否可用(集群内探活,不依赖域名解析)
kubectl -n server run gl-check --rm -i --restart=Never --image=curlimages/curl:latest --quiet -- \
  sh -c 'printf "sign_in "; curl -s -o /dev/null -w "%{http_code}\n" -H "Host: gitlab.rainchen.top" http://envoy-server-gitlab-gw-80b44f81/users/sign_in; printf "health  "; curl -s -H "Host: gitlab.rainchen.top" http://envoy-server-gitlab-gw-80b44f81/-/health'
# 预期:sign_in 返回 200;health 返回 GitLab OK

# 4) 依赖组件是否就绪(故障时先看这里)
kubectl -n server get cluster gitlab-pg            # 预期 Cluster in healthy state
kubectl -n server get pod redis-0 minio-0          # 预期 1/1 Running

# 5) 后台任务是否积压(Sidekiq)
kubectl -n server logs deploy/gitlab-sidekiq-all-in-1-v2 --tail=30 | grep -iE 'error|fail' || echo "无错误"

# 6) 最近一次数据库迁移是否成功
kubectl -n server get job | grep migrations        # 预期 Completed

# 7) 对象存储桶是否可写(备份依赖它)
kubectl -n server run mc-ls --rm -i --restart=Never --quiet \
  --image=quay.io/minio/mc:RELEASE.2025-04-16T18-13-26Z \
  --env=U="$(grep MINIO_USER ns_migration/secrets/gitlab-credentials.env | cut -d= -f2)" \
  --env=P="$(grep MINIO_PASS ns_migration/secrets/gitlab-credentials.env | cut -d= -f2)" \
  --command -- sh -c 'mc alias set m http://minio:9000 "$U" "$P" >/dev/null && mc ls m'
# 预期:列出 6 个桶

4. 日常操作

# 进入运维工具箱(备份、恢复、rake 任务都在这里做)
kubectl -n server exec -it deploy/gitlab-toolbox -- bash

# 查看 GitLab 版本与数据库迁移状态(在 toolbox 内)
gitlab-rake gitlab:check                      # 应用健康自检
gitlab-psql -c "select version();"            # 连库确认

# 重启单个组件(滚动,逐 Pod 替换)
kubectl -n server rollout restart deploy/gitlab-webservice-default
kubectl -n server rollout status  deploy/gitlab-webservice-default --timeout=300s

# 重启全部 GitLab 组件(【高危】服务中断数分钟;有 CI 任务时勿做)
kubectl -n server rollout restart deploy -l app.kubernetes.io/instance=gitlab

# 查看组件日志(webservice 最常见)
kubectl -n server logs deploy/gitlab-webservice-default --tail=100
kubectl -n server logs deploy/gitlab-sidekiq-all-in-1-v2 --tail=100

# 检查依赖连通的顺序:PG → Redis → MinIO → webservice
kubectl -n server get endpoints gitlab-pg-rw redis minio

5. 配置管理

唯一配置文件是 gitlab-deploy-v2/values-gitlab.yaml(约 130 行)。

想改什么 改哪里 生效方式
域名 global.hosts.domain / gitlab.hosts 等 helm upgrade
副本数 <组件>.replicas helm upgrade
数据库/Redis 地址 global.psql.host、global.redis.host helm upgrade(必须指向 server,见易错点)
对象存储 global.appConfig.object_store + Secret gitlab-object-storage 改 Secret 后重启相关组件
资源限制 <组件>.resources helm upgrade
关闭/开启某功能 对应子 chart 的 enabled helm upgrade
cd /home/rain/Documents/k8s_ins/gitlab-deploy-v2
# 1) 先本地渲染复核(不改集群):确认无监控类资源、地址正确
helm template gitlab ./gitlab -n server -f values-gitlab.yaml > /tmp/render.yaml
grep -cE '^kind: (Prometheus|Alertmanager|ServiceMonitor)' /tmp/render.yaml     # 预期 0
# 2) 应用
helm upgrade gitlab ./gitlab -n server -f values-gitlab.yaml --timeout 900s
# 3) 验证
kubectl -n server get pods | grep -vE 'Running|Completed'

易错点(本环境实测):

  • global.psql.host 与 global.redis.host 必须指向 server 命名空间(gitlab-pg-rw.server.svc.cluster.local、redis.server.svc.cluster.local)。若沿用旧的 gitlab-pg / gitlab-redis,所有 Pod 会卡在 Init 无法连库。
  • 凭据 Secret(gitlab-pg-app、gitlab-redis)必须在 release 所在命名空间(即 server),chart 不会去别的命名空间找。
  • gitlab.toolbox.backups.objectStorage.config.secret: gitlab-backup-s3cfg 必须存在且键为 config,缺失会导致 toolbox CrashLoop。
  • 改 values 后不要只重启 Pod —— 配置来自 chart 渲染的 ConfigMap/Secret,必须走 helm upgrade。

6. 备份与恢复

备份目标:MinIO 的 gitlab-backups 桶(端点 minio.server.svc.cluster.local:9000),凭据来自 Secret gitlab-backup-s3cfg。

手工备份(在 toolbox 内执行;命令名随版本不同,先确认):

kubectl -n server exec -it deploy/gitlab-toolbox -- bash
# 1) 确认工具(chart 10.x 通常提供 backup-utility)
ls -1 /usr/bin | grep -iE 'backup|rake'
# 2) 执行备份(-t 指定备份名,便于识别)
backup-utility --backup     # 或:gitlab-backup create
# 3) 确认对象已落桶(退出 toolbox 后在宿主执行)
kubectl -n server run mc-check --rm -i --restart=Never --quiet \
  --image=quay.io/minio/mc:RELEASE.2025-04-16T18-13-26Z \
  --env=U="$(grep MINIO_USER ns_migration/secrets/gitlab-credentials.env | cut -d= -f2)" \
  --env=P="$(grep MINIO_PASS ns_migration/secrets/gitlab-credentials.env | cut -d= -f2)" \
  --command -- sh -c 'mc alias set m http://minio:9000 "$U" "$P" >/dev/null && mc ls m/gitlab-backups | tail -5'

恢复(【高危】:会覆盖现有数据,务必先确认备份可用):

kubectl -n server exec -it deploy/gitlab-toolbox -- bash
backup-utility --restore -t <备份名>          # 交互确认后执行
# 恢复后按提示重启组件(通常需重启 webservice / sidekiq / gitaly)

恢复后验证:第 3 章速查表第 3 条返回 200 与 GitLab OK;登录后确认项目数量、最近一次 CI 记录存在。

变更前备份与台账:见 backup/README.md(本目录备份为配置与清单级;数据级备份走上面的 MinIO 桶)。

7. 监控与告警

  • 指标端点:gitlab-gitlab-exporter(Service 端口 9168)已运行,但未接入监控栈(monitoring 命名空间无对应 ServiceMonitor)—— 当前 Prometheus 里看不到 GitLab 指标,也没有 GitLab 专用告警。这是已知缺口。

建议接入(清单)

补 ServiceMonitor 与首批告警属于变更操作,建议内容如下(与 SOP 第 8 章、INCIDENT 行动项一致):

项 建议
指标采集 为 gitlab-gitlab-exporter:9168 建 ServiceMonitor
告警 1 webservice 5xx 比例超阈值
告警 2 GitLab 组件 Pod 不可用(副本数不满足)
告警 3 Gitaly 所在 PV(pv-gitaly-ssd 20Gi)使用率 > 80%
告警 4 PG 集群非 healthy(Cluster/gitlab-pg)
告警 5 Redis 内存接近 maxmemory(400MB)
- 日志:各组件的 stdout(kubectl -n server logs deploy/<组件>);GitLab 自身还有 /var/log/gitlab/(在容器内,随 Pod 生命周期)。
- 值班兜底巡检:
# 组件健康
kubectl -n server get deploy,sts | grep -E 'gitlab|envoy' | grep -vE '1/1|2/2'
# 服务可用性
kubectl -n server run gl-check --rm -i --restart=Never --image=curlimages/curl:latest --quiet -- \
  sh -c 'curl -s -H "Host: gitlab.rainchen.top" http://envoy-server-gitlab-gw-80b44f81/-/health'
# 依赖健康
kubectl -n server get cluster gitlab-pg; kubectl -n server get pod redis-0 minio-0
  • 重点盯:webservice 的 /‑/health、sidekiq 队列积压、Gitaly 所在节点磁盘(pv-gitaly-ssd 20Gi 上限)。

8. 故障处置

场景 1:GitLab 页面打不开(502 / 超时)

症状:gitlab.rainchen.top 返回 502 或超时;也可能表现为登录页转圈。

诊断

# 1) 入口数据面是否在
kubectl -n server get pod -l gateway.envoyproxy.io/owning-gateway-name=gitlab-gw      # 预期 1/1 Running
# 2) Gateway 是否被接受
kubectl -n server get gateway gitlab-gw                                               # 预期 PROGRAMMED=True
# 3) webservice 是否就绪
kubectl -n server get pods | grep webservice                                          # 预期 2/2(含 sidecar)
kubectl -n server logs deploy/gitlab-webservice-default --tail=50
# 4) 集群内直连后端(绕过入口)
kubectl -n server run ws-check --rm -i --restart=Never --image=curlimages/curl:latest --quiet -- \
  curl -s -o /dev/null -w '%{http_code}\n' http://gitlab-webservice-default:8080/-/health
# 预期 200;若此处通而域名不通,问题在入口侧

处置:后端不通 → 转场景 2;后端通但入口不通 → 看 Envoy 数据面 Pod 日志与 Gateway 状态,必要时 kubectl -n server rollout restart deploy/envoy-gateway 后重试。

验证:curl -sk --resolve gitlab.rainchen.top:443:<入口 IP> https://gitlab.rainchen.top/users/sign_in 返回 200。

场景 2:Pod 卡在 Init 或反复重启

症状:kubectl -n server get pods | grep gitlab 显示 Init:0/2、Init:CrashLoopBackOff。

诊断

kubectl -n server describe pod <pod> | grep -A6 Events
# 判读常见原因:
#   FailedMount secret "gitlab-pg-app"/"gitlab-redis" not found → 凭据 Secret 不在 server
#   initContainer "wait-for-deps" 超时                            → 依赖未就绪(PG/Redis/MinIO)
#   readiness/liveness 探针失败                                   → 组件自身启动慢或配置错误
# 1) 依赖就绪情况
kubectl -n server get cluster gitlab-pg; kubectl -n server get pod redis-0 minio-0
# 2) 依赖端点
kubectl -n server get endpoints gitlab-pg-rw redis minio

处置:Secret 缺失 → 在 server 重建(kubectl -n server create secret ... --dry-run=client -o yaml | kubectl apply -f -);依赖未就绪 → 先按场景 4 修依赖,再看 GitLab 组件;若组件自身起不来,看该组件日志定位。

验证:目标 Pod 变为 Running 且 READY 达到期望值。

场景 3:migrations Job 失败

症状:kubectl -n server get job | grep migrations 显示 Failed;Pod 的 Init 容器一直等 migrations。

诊断

kubectl -n server logs job/$(kubectl -n server get job -o name | grep migrations | head -1 | cut -d/ -f2) --tail=50
# 关键判读:
#   "out of shared memory" / max_locks_per_transaction → PG 参数问题
#   "PG::ConnectionBad"                                 → 连不上 PG
#   "relation already exists"                           → 上次失败残留,需人工确认

处置:PG 参数问题 → 确认 Cluster/gitlab-pg 的 spec.postgresql.parameters.max_locks_per_transaction: "256" 仍存在(该参数对 GitLab 是必需,改小会导致 migrations 反复失败);连不上 PG → 转场景 4。修好后删除失败 Job 并重跑 helm upgrade(chart 会重建 Job)。

验证:新 Job 状态 Completed,随后 webservice Pod 能进入 Ready。

场景 4:依赖组件故障(PG / Redis / MinIO)

症状:GitLab 大面积 Pod 卡 Init 或 CrashLoop;gitlab-webservice 报连库失败。

诊断

kubectl -n server get cluster gitlab-pg                    # 预期 healthy;否则看 conditions
kubectl -n server get pods gitlab-pg-1 redis-0 minio-0
kubectl -n server describe cluster gitlab-pg | tail -20    # 事件
kubectl -n server get pvc                                  # 预期全部 Bound

处置:

  • PG 未 Ready → 看 gitlab-pg-1 日志;若 PVC 丢失或绑定异常,按 ns_migration/RUNBOOK.md 场景 3 处理绑定。(注意:CNPG 的 PVC 必须由 operator 自建,不可预先手工创建,否则会卡 BootstrapPending。)
  • Redis 未就绪 → kubectl -n server describe pod redis-0;Redis 数据可丢(缓存性质),必要时 kubectl -n server delete pod redis-0 触发重建。
  • MinIO 未就绪 → 影响 artifacts/LFS/registry 读写;检查 minio-data PVC 与 NFS 后端可达性。

验证:kubectl -n server get cluster gitlab-pg 为 healthy;kubectl -n server get pod redis-0 minio-0 均 1/1;再跑第 3 章速查表第 3 条确认 GitLab 恢复。

场景 5:gitlab-toolbox CrashLoopBackOff

症状:toolbox 反复重启,kubectl -n server logs deploy/gitlab-toolbox 显示找不到 /etc/gitlab/.s3cfg 或类似。

诊断

kubectl -n server logs deploy/gitlab-toolbox --tail=30
kubectl -n server get secret gitlab-backup-s3cfg                     # 预期存在且含 data.config

处置:Secret 缺失或键名不对 → 重建(键必须是 config,内容为 s3cfg 格式,端点指向 minio.server.svc.cluster.local:9000);重建后 kubectl -n server rollout restart deploy/gitlab-toolbox。

验证:toolbox Pod 1/1 Running 且可进入 bash。

9. 安全与权限

  • 账号:root 为超级管理员,初始口令存在 server/secret/gitlab-gitlab-initial-root-password;首次登录后应修改并妥善保存。
  • Secret 清单(用途分类,值不列出):
  • 数据库/缓存/对象存储:gitlab-pg-app、gitlab-redis、gitlab-object-storage、registry-storage、gitlab-backup-s3cfg
  • 组件密钥:gitlab-rails-secret、gitlab-gitaly-secret、gitlab-gitlab-shell-secret、gitlab-gitlab-shell-host-keys、gitlab-kas-private-api、gitlab-kas-websocket-token、gitlab-registry-httpsecret、gitlab-registry-notification
  • TLS:GitLab 域名证书由 chart 自管(Gateway/Envoy 侧)。替换后需重启 Envoy 数据面。
  • Registry 认证:由 GitLab 自身令牌体系负责,不是独立账号。
  • 访问控制:GitLab 页面走 HTTPS;集群内 Service 为 ClusterIP,不对集群外暴露。

10. 容量与性能

项 当前值
资源 requests 合计(GitLab 组件) 约 1.4 核 / 7.3 GiB(webservice 2Gi + sidekiq 1.5Gi×2 + 其余)
主要存储 Gitaly pv-gitaly-ssd 20Gi(local SSD)、MinIO 50Gi(NFS)、PG 5Gi、Redis 5Gi
组件落点 Gitaly / PG / MinIO / Redis 集中在 k8s-node-01(因 local PV 绑定);registry、kas 部分在 k8s-node-03

扩容触发条件:镜像拉取变慢或 registry 排队 → 增 gitlab-registry.replicas;CI 积压 → 增 gitlab-sidekiq.replicas;pv-gitaly-ssd 使用率 > 80% → 需规划 Gitaly 存储扩容(local PV 扩容需重建 PV 并迁移数据,属变更)。

已知瓶颈:本地盘 PV 全部集中在 k8s-node-01,该节点故障会同时影响 GitLab、PostgreSQL、Redis,且无自动切换。

11. 附录

术语表

术语 含义
toolbox GitLab 官方运维工具箱容器(备份/恢复/rake)
CNPG CloudNativePG,本环境用于运行 PostgreSQL
Gateway API / Envoy Gateway GitLab 的入口方案(不经 Traefik)
migrations chart 的数据库迁移 Job,首次安装或升级时运行

相关文档

文档 位置
部署变更档案(八章,含排障与回滚) gitlab-deploy-v2/SOP.md
命名空间总览与跨服务排障 ns_migration/RUNBOOK.md
命名空间统一变更档案 ns_migration/SOP.md
数据非空场景的迁移方案 ns_migration/GitLab迁移到server-方案与风险.md
变更前备份台账 gitlab-deploy-v2/backup/README.md
部署期排障台账(4 个阻塞问题 + 1 起凭据失误) gitlab-deploy-v2/INCIDENT-20260917-01-gitlab-部署与迁移期排障.md
公网暴露链路(隧道与 TLS 终止) ingress_tunnel_deploy/RUNBOOK.md

修订记录

日期 修改人 变更内容
2026-09-19 运维 首版:GitLab 19.3.2 运行于 server 命名空间(四命名空间已合并)

来源:/home/rain/Documents/k8s_ins/gitlab-deploy-v2/RUNBOOK.md | 最后更新:2026-09-19 16:53(由 build/sync.py 同步,请勿在站点侧修改)