标准企业级实践是实施 双层清理法(Dual-Layer Cleanup):先确保基础设施层(Kubernetes)资源释放,再通过 GitLab 控制台(Control Plane)优雅同步数据库状态。
基础设施层清理 (Kubernetes 侧)
在重置 GitLab 状态之前,必须确保 K8s 集群中没有残留的命名空间和僵尸 Pod。
1. 强制删除托管命名空间 GitLab-managed apps 默认部署在 gitlab-managed-apps 命名空间中。
kubectl delete namespace gitlab-managed-apps --wait=false
2. 解决可能出现的 Namespace 卡在 Terminating 的问题 如果命名空间由于 Finalizers 无法删除,可使用以下大厂常用的自动化脚本强制将其置空(无需手动编辑 JSON):
kubectl get namespace gitlab-managed-apps -o json | tr -d "\n" | sed "s/\"finalizers\": \[[^]]*\]/\"finalizers\": []/g" | kubectl replace --raw /api/v1/namespaces/gitlab-managed-apps/finalize -f -
第二步:控制台状态重置 (GitLab 数据库侧)
这是清理的核心。我们需要进入 GitLab 的 Rails 环境,将卡住的状态强行扭转。
1. 登录 GitLab 服务器并进入 Rails 控制台
sudo gitlab-rails console
(如果是 Docker 部署的 GitLab,请先执行 docker exec -it gitlab bash 再运行上方命令)
2. 查找对应的集群对象 在控制台中,通过集群名称或 ID 锁定你的 K8s 集群:
# 方案 A:通过集群名称查找
cluster = Clusters::Cluster.find_by(name: '你的集群名称')
# 方案 B:如果不记得名字,可以列出所有集群看 ID
Clusters::Cluster.all.map { |c| [c.id, c.name] }
# 锁定后直接读取:cluster = Clusters::Cluster.find(集群ID)
3. 查看并诊断卡住的组件状态 通过关联对象查看是哪个托管 App 卡住了,并查看其当前的状态名称:
# 查看各个组件的状态(未安装的会返回 nil)
cluster.application_helm&.status_name
cluster.application_runner&.status_name
cluster.application_ingress&.status_name
cluster.application_prometheus&.status_name
注:常见的卡住状态名通常为 :installing, :uninstalling 或 :updating。
4. 执行企业级安全重置(二选一)
选项 A:将状态重置为“可安装(Installable)”状态(推荐,适合想重新在 UI 触发安装的情况)
# 以 Runner 为例,如果是其他组件,换成 application_helm 或 application_ingress 等
app = cluster.application_runner
# 1 代表可安装状态 (installable);0 代表不可安装;3 代表已安装;4 代表有错误
app.update!(status: 1, status_reason: nil)
选项 B:彻底从数据库擦除该 App 的关联记录(最彻底,适合组件彻底不要了,或者彻底走 GitOps 管理的情况)
app = cluster.application_runner
app.destroy!
5. 退出控制台并验证 输入 exit 退出控制台。
exit
验证结果
重新刷新 GitLab 的集群管理 Web 页面(Operations > Kubernetes)。你会发现此前那个一直转圈圈、或者提示卸载中的应用图标已经恢复正常。
