RUNBOOK — GitLab¶
服务:GitLab EE v19.3.2(Helm chart
gitlab-10.3.2,releasegitlab,命名空间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-ssd20Gi 上限)。
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-dataPVC 与 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同步,请勿在站点侧修改)