GitLab 迁移到 server 命名空间 —— 方案与风险¶
交付物目录:
ns_migration/状态:待确认,尚未执行 关联工程:gitlab-deploy-v2/(chart 10.3.2 / GitLab 19.3.2)
1. 背景与现状¶
本次要求把含 "deploy" 的目录对应的命名空间统一为 server。Traefik(已完成)与 LDAP(仅文件)都属轻量变更;GitLab 是其中唯一带持久化数据的多命名空间应用,因此单独成文。
集群现状(实测):
| 命名空间 | 承载内容 | 数据卷 |
|---|---|---|
gitlab |
GitLab 主体(webservice / sidekiq / gitaly / registry / kas / toolbox / shell)+ Envoy Gateway(GitLab 19.x 走 Gateway API) | pv-gitaly-ssd(local PV,/mnt/ssd/k8s/gitaly) |
gitlab-pg |
CloudNativePG 的 Cluster gitlab-pg(1 实例,healthy) |
pv-postgres-ssd(local PV,/mnt/ssd/k8s/postgres) |
gitlab-redis |
Redis StatefulSet | pv-redis-ssd(local PV,/mnt/ssd/k8s/redis) |
gitlab-minio |
MinIO(对象存储:artifacts / LFS / uploads / packages / registry) | minio-data(nfs-csi 动态卷,50G,回收策略 Delete) |
- 三个 local PV 的回收策略均为 Retain,数据落在
k8s-node-01的/mnt/ssd/k8s/下 → 删 PVC 不会删数据。 - MinIO 的卷由
nfs-csi动态供给,回收策略是 Delete → 删 PVC 即删数据,这是本次最大的单点风险。 gitlab命名空间内有 20 个 Secret(gitlab-rails-secret、gitlab-gitaly-secret、gitlab-gitlab-initial-root-password、gitlab-object-storage、gitlab-pg-app、gitlab-redis等),承载数据库口令、组件密钥、root 初始口令,必须逐一搬迁且内容一致。
2. 目标¶
GitLab 全栈(含 PG / Redis / MinIO)运行在 server 命名空间,数据零丢失,登录与 CI 功能验证通过。
3. 为什么这是"重装级"变更¶
| 约束 | 后果 |
|---|---|
| Helm release 的命名空间安装即固定,无法迁移 | 必须 helm uninstall 后在新 ns 重装 |
local PV 的 claimRef 绑定在旧 ns 的 PVC 上 |
必须停机 → 释放 claimRef → 在新 ns 重绑,否则新 PVC 无法 Bound |
| MinIO 卷是 Delete 策略的动态卷 | 换 ns 等于换卷,数据必须显式复制,否则全部对象丢失 |
CNPG 的 Cluster CR 是命名空间级资源 |
重建后需以现有数据引导(复用 PV 或走 recovery),否则 PG 起不来 |
| GitLab chart 重装会重跑 migrations | Secret 必须完整迁移,任何密钥不一致都会导致启动失败或数据不可读 |
| GitLab 19.x 依赖 Gateway API + Envoy Gateway | envoy-gateway、Gateway、TCPRoute 等资源需一并迁移 |
4. 影响范围¶
- 停机:GitLab 全栈不可用,预计 1–3 小时(含镜像、migrations、验证);期间
gitlab.rainchen.com不可访问、CI 不可用、Git push 不可用、registry 不可用。 - 主机:
k8s-node-01(local PV 所在地,数据不动)、NFS 服务器192.168.31.249(MinIO 数据复制)。 - 集群:新增
serverns 内的 GitLab 全套对象;旧 4 个 ns 在验证通过后删除(删除前必须确认数据已迁移)。 - 不影响:Traefik(已迁至
server,与 GitLab 的 Gateway API 路径互不干扰)、监控栈(明确排除在本次范围外)。
5. 建议步骤(8 步)¶
下列为方案骨架,实际执行前会逐条核对并补充预期输出;涉及数据的步骤必须先备份。
# ① 全量备份(不可跳过)
helm get values gitlab -n gitlab -o yaml > ns_migration/backup/gitlab-values-before.yaml
kubectl -n gitlab get secret -o yaml > ns_migration/backup/gitlab-secrets-before.yaml
kubectl -n gitlab-pg get cluster gitlab-pg -o yaml > ns_migration/backup/cnpg-cluster-before.yaml
kubectl get pv,pvc -o yaml > ns_migration/backup/pv-pvc-before.yaml
# GitLab 侧逻辑备份(应用级):toolbox 里跑 gitlab-backup / pg_dump,产出落到 NFS 或宿主机
# ② 停止写入(先摘流量,再停组件)
# - 暂停 GitLab 写入口(scale webservice/sidekiq/registry/kas 到 0)
# - CNPG:停 Cluster 实例;Redis:scale 0
# - MinIO:scale 0
# ③ 备份 MinIO 数据(Delete 策略,必须先复制)
# 在 NFS 服务器上把旧卷目录整体复制一份(保留原目录不动,便于回滚)
# ④ 释放 local PV 的 claimRef
kubectl -n gitlab delete pvc repo-data-gitlab-gitaly-0
kubectl -n gitlab-pg delete pvc gitlab-pg-1
kubectl -n gitlab-redis delete pvc redis-data
# 逐个清空 claimRef,使 PV 回到 Available(数据仍在 /mnt/ssd/k8s/ 下)
kubectl patch pv pv-gitaly-ssd -p '{"spec":{"claimRef":null}}'
kubectl patch pv pv-postgres-ssd -p '{"spec":{"claimRef":null}}'
kubectl patch pv pv-redis-ssd -p '{"spec":{"claimRef":null}}'
# ⑤ 在 server 命名空间重建命名空间级资源
# - 20 个 Secret(从 ① 的备份还原,改名空间)
# - 三个 PVC(同名,spec.volumeName 指向对应 PV,storageClassName: local-ssd)
# - MinIO 的新 PVC 及其数据(从 ③ 的副本恢复)
# ⑥ 改 values 并重装
# values-gitlab.yaml 中 4 处跨命名空间引用须同步改为 server:
# gitlab-pg-rw.gitlab-pg.svc.cluster.local -> gitlab-pg-rw.server.svc.cluster.local
# redis.gitlab-redis.svc.cluster.local -> redis.server.svc.cluster.local
helm upgrade --install gitlab gitlab-deploy-v2/gitlab-10.3.2.tgz \
-n server -f gitlab-deploy-v2/values-gitlab.yaml \
--wait --timeout 30m
# ⑦ 验证(见第 6 节)
# ⑧ 清理旧命名空间(高危:确认数据已迁移且备份可用后再删)
kubectl delete namespace gitlab gitlab-pg gitlab-redis gitlab-minio
6. 验证¶
kubectl -n server get pods # gitlab-* 全部 Running 且 Ready
kubectl -n server get cluster gitlab-pg # Cluster in healthy state
kubectl -n server get job | grep migrations # migrations Job 成功
curl -s -o /dev/null -w '%{http_code}\n' http://<GitLab 入口>/users/sign_in # 200
# 业务验证:登录、浏览既有仓库、git clone、CI 跑一次、push/pull 一个镜像
7. 回滚¶
- 数据侧:PV 为 Retain,节点本地数据未被触碰;把
claimRef指回旧命名空间的 PVC 名即可复原。 - MinIO 侧:旧 NFS 卷目录保留未动,回滚时把旧 PVC 的 volumeHandle/目录还原即可。
- 应用侧:重新在旧命名空间
helm upgrade --install并挂回原 PVC。 - 触发条件:migrations 失败、PG 引导失败、MinIO 数据不一致、验证项任一不过 → 立即回滚。
8. 风险说明¶
| 风险 | 等级 | 缓解 |
|---|---|---|
| MinIO 对象数据丢失(Delete 策略) | 高 | 步骤 ③ 先复制数据;旧目录保留不删 |
| Gitaly 仓库数据受损 | 高 | local PV Retain + 停机操作;操作前确认 /mnt/ssd/k8s/gitaly 可读 |
| CNPG 重建后无法以现有数据引导 | 中 | 备份 Cluster CR;必要时改走 bootstrap.recovery 指向原备份 |
| 停机时间超预期(migrations 慢) | 中 | 安排在无 CI 任务的时间窗;预留 3 小时 |
| Secret 迁移不完整导致组件起不来 | 中 | 用 ① 的 Secret 全量备份 + diff 校验 |
| 回滚窗口内出现新提交无法回灌 | 低 | 停机期间禁止写入,无新数据产生 |
9. 我的判断(供你决策)¶
收益有限、风险显著。理由:
- GitLab 官方 chart 本身按多命名空间设计(PG / Redis / MinIO 独立),它们是同一套应用的不同组件,合并到
server不会带来运维简化,反而让server这个"业务命名空间"混入数据库与对象存储。 server目前的定位是业务与入口(Traefik、LDAP 都在此),把 GitLab 的 PG/MinIO 塞进来会让后续的资源配额、NetworkPolicy、备份策略更难做。- 真正需要"路由统一在同一命名空间"的诉求(IngressRoute 与后端同 ns 便于书写),GitLab 已经不走 Traefik(它用 Gateway API + Envoy Gateway),所以这个诉求对 GitLab 不成立。
因此建议二选一:
- 方案 A(推荐):GitLab 保持现状不动,本次只把
gitlab-deploy-v2/里的文档与 values 注释补一句说明("GitLab 因数据卷与 chart 架构原因保留独立命名空间"),集群零变更。 - 方案 B(按你原要求):执行上述 8 步完整迁移,需要你指定一个无 CI 任务的时间窗,我会先做全量备份再动手。
请告诉我选 A 还是 B。若选 B,我会在动手前把每一步的命令、预期输出、失败判据补全并逐条与你核对。
来源:
/home/rain/Documents/k8s_ins/ns_migration/GitLab迁移到server-方案与风险.md| 最后更新:2026-09-18 00:34(由build/sync.py同步,请勿在站点侧修改)