RUNBOOK — server 命名空间运行手册¶
面向对象:接手本集群日常运维与值班的人(假定你不熟悉这些服务,可能需要凌晨照着做) 命名空间:
server(2026-09-18 由traefik/gitlab/gitlab-pg/gitlab-redis/gitlab-minio统一而来) 本手册只写「命名空间级」的共性与速查;各服务的细节操作在各自的专用 RUNBOOK 中,本手册用链接指向 最近更新:2026-09-19
目录¶
1. 服务概览¶
server 是本集群的业务命名空间,承载入口代理、代码托管平台、目录服务与一个业务数据库。
| 组件 | 版本 | 形态 | 专用 RUNBOOK |
|---|---|---|---|
| Traefik(HTTP/HTTPS/TCP 入口代理) | v3.7.13 | Deployment ×1,固定 k8s-master-01 |
traefik_deploy/RUNBOOK.md |
| GitLab(含 webservice / sidekiq / gitaly / shell / kas / registry / toolbox) | v19.3.2 | 多 Deployment + StatefulSet | gitlab-deploy-v2/RUNBOOK.md |
| MinIO(GitLab 对象存储) | RELEASE.2025-04-22 | StatefulSet ×1,NFS 卷 | 见 GitLab RUNBOOK |
| PostgreSQL(CNPG 单实例) | 17.6 | Cluster gitlab-pg,local SSD |
见 GitLab RUNBOOK |
| Redis | 7.4 | StatefulSet ×1,local SSD | 见 GitLab RUNBOOK |
| OpenLDAP | 2.6.10 | StatefulSet ×1,NFS 卷 | ldap-deploy/RUNBOOK.md |
| phpLDAPadmin(LDAP 管理界面) | — | Deployment ×1 | 见 LDAP RUNBOOK |
| MariaDB | 12.3.3 | StatefulSet ×1,NFS 卷 | mariadb-deploy/(无独立 RUNBOOK) |
| Envoy Gateway(GitLab 的入口数据面) | v1.9.0 | Deployment + Gateway | 见 GitLab RUNBOOK |
依赖关系(自下而上):
Traefik ← 集群外客户端(80/443/389/636/3306)
└─ 路由到 → phpLDAPadmin / Traefik Dashboard / (monitoring 内的 grafana、prometheus)
└─ TCP 路由 → OpenLDAP(389/636)、MariaDB(3306)
Envoy Gateway ← gitlab.rainchen.top / registry / kas (GitLab 不经 Traefik)
└─ 转发到 → GitLab webservice / registry / kas
GitLab → PostgreSQL + Redis + MinIO(三者均在 server 内)
重要性等级:
- Traefik:核心。它宕机则所有 HTTP/HTTPS 与 TCP(LDAP/MariaDB)入口全部中断。
- GitLab:重要。宕机影响代码托管、CI、镜像仓库;不影响 LDAP 与数据库服务本身。
- OpenLDAP:重要。宕机影响依赖其认证的系统登录。
- MariaDB / phpLDAPadmin:一般。
2. 接入与凭据¶
| 业务域名 | 入口 | 后端(命名空间/服务) | 说明 |
|---|---|---|---|
gitlab.rainchen.top |
Envoy Gateway(不走 Traefik) | server/gitlab-webservice-default:8080 |
GitLab 主页 |
registry.rainchen.top |
Envoy Gateway | server/gitlab-registry:5000 |
容器镜像仓库 |
kas.rainchen.top |
Envoy Gateway | server/gitlab-kas:8154 |
GitLab Agent 服务 |
ldapadmin.rainchen.top |
Traefik (443) | server/phpldapadmin:80 |
LDAP 管理界面 |
traefik.rainchen.top |
Traefik (443) | Traefik Dashboard | 需 BasicAuth |
grafana.rainchen.top |
Traefik (443) | monitoring/grafana |
监控面板(跨命名空间) |
prometheus.rainchen.top |
Traefik (443) | monitoring/prometheus |
指标查询 |
192.168.31.10:389 / :636 |
Traefik (TCP) | server/openldap:389/636 |
LDAP 明文 / LDAPS |
192.168.31.10:3306 |
Traefik (TCP) | server/mariadb:3306 |
业务数据库 |
域名解析不在集群内维护(本机
/etc/hosts无相关条目),客户端需自行解析到192.168.31.10。
凭据只写位置,不写内容:
# Traefik Dashboard 口令(明文,权限 600)
cat traefik_deploy/secrets/dashboard-basic-auth.txt
# GitLab root 初始口令
kubectl -n server get secret gitlab-gitlab-initial-root-password -o jsonpath='{.data.password}' | base64 -d
# GitLab 依赖(PG/Redis/MinIO)口令
cat ns_migration/secrets/gitlab-credentials.env # 权限 600
# LDAP 管理员口令(见 LDAP RUNBOOK 第 2 章,存在集群 Secret 与工作目录两处)
# MariaDB 口令:kubectl -n server get secret | grep -i mariadb
3. 日常速查表¶
# 1) 一眼看全 `server` 的工作负载是否健康(最常用)
kubectl -n server get pods -o wide | grep -vE 'Completed' | awk '$3!="Running" {print}'
# 预期:无输出(全部 Running)。有输出即为异常 Pod,转到第 8 章对应场景
# 2) 入口是否可用(404 正常,表示 Traefik 在且无匹配路由)
curl -s -o /dev/null -w '%{http_code}\n' http://192.168.31.10/ # 预期 404
# 3) 各业务域名连通性(返回 200/302/401 均属"入口可达")
for h in gitlab.rainchen.top ldapadmin.rainchen.top traefik.rainchen.top; do
printf '%-26s ' "$h"
curl -sk -o /dev/null -w '%{http_code}\n' --resolve "$h:443:192.168.31.10" "https://$h/"
done
# 4) helm release 状态(应是 deployed)
helm list -n server
# 5) 存储是否都 Bound
kubectl -n server get pvc | grep -v Bound # 预期:无输出
# 6) 节点资源水位
kubectl top nodes
# 7) 最近 5 条事件(排查异常的第一现场)
kubectl -n server get events --sort-by=.lastTimestamp | tail -5
# 8) 取任意组件的日志(近 100 行)
kubectl -n server logs deploy/<组件名> --tail=100
4. 日常操作¶
# 查看某组件全部 Pod 与其所在节点
kubectl -n server get pods -o wide -l app.kubernetes.io/instance=<release> # 例:-l app=redis
# 重启单个组件(滚动重启,逐个替换 Pod)
kubectl -n server rollout restart deploy/<名称>
kubectl -n server rollout status deploy/<名称> --timeout=180s # 预期:successfully rolled out
# 【高危】重启 Traefik:单副本 + hostPort,重启期间所有入口中断数秒
# 执行前确认无重要业务在跑;详见 traefik_deploy/RUNBOOK.md
kubectl -n server rollout restart deploy/traefik
# 进入容器排障
kubectl -n server exec -it deploy/gitlab-toolbox -- bash # GitLab 运维工具箱
kubectl -n server exec -it sts/openldap -- sh # LDAP
# 临时把集群内服务暴露到本机(排查用;勿长期驻留)
kubectl -n server port-forward svc/gitlab-webservice-default 8080:8080
# 注意:不要 port-forward 到 envoy-gateway(那是控制面 18000/19001,连不上业务)
5. 配置管理¶
| 组件 | 配置载体 | 修改方式 | 生效方式 |
|---|---|---|---|
| Traefik | traefik_deploy/values.yaml |
改后 helm upgrade(见其 SOP 第 5 章) |
Pod 滚动重建 |
| GitLab | gitlab-deploy-v2/values-gitlab.yaml |
改后 helm upgrade |
对应组件滚动重建 |
| MinIO / PostgreSQL / Redis / MariaDB / OpenLDAP | 各自清单或 values(见各交付目录) | 重新 kubectl apply 或 helm upgrade |
视组件而定 |
| 路由(HTTP) | IngressRoute 自定义资源 |
kubectl apply 后热加载 |
无需重启 Traefik |
| 路由(TCP) | IngressRouteTCP 自定义资源 |
同上 | 同上 |
易错点:Traefik 的 entrypoint(端口)配置在 values 里,改端口需 helm upgrade 并会重建 Pod;而路由规则改的是 IngressRoute,与 helm 无关。两者不要混。
6. 备份与恢复¶
| 对象 | 备份方式 | 位置 |
|---|---|---|
| GitLab 应用数据 | chart 的备份机制(toolbox)+ 对象存储 gitlab-backups 桶 |
见 GitLab RUNBOOK |
| OpenLDAP 数据 | slapcat 导出 LDIF + 备份 CronJob |
见 LDAP RUNBOOK |
| MariaDB | 见 mariadb-deploy/ |
— |
| local PV 数据 | 节点本地目录(k8s-node-01:/mnt/ssd/k8s/{gitaly,postgres,redis}) |
由各组件自管 |
| 集群资源定义 | kubectl get all,pvc,secret -n server -o yaml > backup/server-resources-<日期>.yaml |
建议纳入 ns_migration/backup/ |
命名空间级快速快照(变更前必做):
kubectl -n server get all,pvc,ingressroute,ingressroutetcp,middleware -o yaml \
> ns_migration/backup/server-resources-$(date +%Y%m%d-%H%M%S).yaml
# 生成后请到 ns_migration/backup/README.md 登记:备份文件、原路径、产生时间、因何产生、何时可删
恢复原则:先恢复定义(YAML),再恢复数据。数据恢复必须在对应组件停写状态下进行。
7. 监控与告警¶
- 监控栈:
kube-prometheus-stack(在monitoring命名空间),Grafanagrafana.rainchen.top、Prometheusprometheus.rainchen.top。 - 现有采集范围:仅监控栈自身组件的 ServiceMonitor(alertmanager / apiserver / coredns / grafana / kube-state-metrics / kubelet / operator / prometheus)。
server命名空间的指标尚未接入:Traefik 已暴露metricsentrypoint(容器端口 9100),GitLab 有gitlab-gitlab-exporter:9168,但都没有对应的 ServiceMonitor —— 这是当前最大的可观测性缺口,建议后续补 ServiceMonitor(属变更,需走变更流程)。- 当前告警:依赖监控栈默认规则(集群级:节点不可用、Pod 重启、磁盘压力等),没有针对
server内业务服务的告警。 - 值班建议的替代手段(无告警时的兜底巡检):
# 每班一次:异常 Pod + 入口连通性
kubectl -n server get pods -o wide | grep -vE 'Completed' | awk '$3!="Running" {print "异常: " $0}'
for h in gitlab.rainchen.top traefik.rainchen.top ldapadmin.rainchen.top; do
printf '%-26s ' "$h"; curl -sk -o /dev/null -w '%{http_code}\n' --resolve "$h:443:192.168.31.10" "https://$h/"
done
8. 故障处置¶
场景 1:某个域名打不开(其他域名正常)¶
症状:单个域名无响应或返回 404/502,其余域名正常。
诊断
# 1) 是入口问题还是后端问题?先用 IP+Host 头直连 Traefik
curl -sk -o /dev/null -w '%{http_code}\n' -H 'Host: <域名>' https://192.168.31.10/ # 404=无路由; 502=后端不可达; 200/302=正常
# 2) 路由是否存在
kubectl get ingressroute,ingressroutetcp -A | grep <域名关键字> # 预期:能看到对应 IngressRoute
# 3) 后端 Pod 是否就绪
kubectl -n server get pods | grep <后端组件名> # 预期:1/1 或 2/2 Running
# 4) 后端 Service 是否有端点
kubectl -n server get endpoints <服务名> # 预期:有 IP:端口,而不是 <none>
处置:404 → 路由缺失,重新 kubectl apply 对应 IngressRoute(文件在各交付目录);502 → 后端未就绪,转场景 2;endpoints 为 <none> → 后端 Pod 未就绪或标签不匹配,检查 Pod 与 Service selector。
验证:重跑诊断第 1 步,预期返回 200/302;再用真实域名 curl 一次。
场景 2:Pod 一直 Pending¶
症状:kubectl -n server get pods 中某 Pod 长期 Pending。
诊断
kubectl -n server describe pod <pod> | grep -A5 Events # 关键看 Events
# 判读:
# "didn't match Pod's node affinity/selector" + local PV 相关 → 存储绑定在别的节点(场景 3)
# "Insufficient cpu/memory" → 资源不足,见第 10 章
# "didn't have free ports for the requested pod ports" → hostPort 冲突(Traefik 常见)
处置:资源不足 → 扩容节点或调整 requests;hostPort 冲突 → 同一节点上不允许两个 Pod 抢同一 hostPort,Traefik 只应有一个副本,若出现多副本请确认是否误改 replicas;亲和性/存储冲突 → 转场景 3。
验证:kubectl -n server get pod <pod> -o wide 预期 Running 且 NODE 与 PV 所在节点一致。
场景 3:PVC 绑定到了错误的 PV(或长期 Pending)¶
症状:PVC 卡 Pending;或 PVC 已 Bound 但 VOLUME 指向与用途不符的 PV(例如 PG 用上了 redis 卷)。
诊断
kubectl -n server get pvc -o custom-columns=NAME:.metadata.name,STATUS:.status.phase,VOLUME:.spec.volumeName # 核对绑定关系
kubectl get pv | grep -E 'Available|Released' # 看是否有闲置 PV
# 本集群的既定对应关系(2026-09-18 起):
# gitlab-pg-1 → pv-postgres-ssd ;redis-data → pv-redis-ssd ;repo-data-gitlab-gitaly-0 → pv-gitaly-ssd
处置:原因通常是「同容量 PV 被先到先得随机分配」。正确做法是用 claimRef 预绑定锁定关系:
# 1) 停用该 PVC 的负载(避免写入错卷)
kubectl -n server scale deploy/<负载> --replicas=0 # 或 delete cluster(CNPG)
# 2) 删除错绑的 PVC(PV 回收策略为 Retain,数据不会丢)
kubectl -n server delete pvc <pvc 名>
# 3) 清空 claimRef 使其回到 Available(必须去掉 uid,只留 4 个字段的预绑定是 Available)
kubectl patch pv <pv 名> -p '{"spec":{"claimRef":null}}'
kubectl patch pv <pv 名> --type=merge -p '{"spec":{"claimRef":{"apiVersion":"v1","kind":"PersistentVolumeClaim","namespace":"server","name":"<目标 pvc 名>"}}}'
# 4) 重建负载,让它自行创建 PVC(CNPG 必须自建,禁止预建 —— 否则卡 BootstrapPending)
验证:kubectl -n server get pvc 中目标 PVC 的 VOLUME 与预期 PV 一致。
场景 4:server 内服务访问 monitoring 或集群外服务失败¶
症状:跨命名空间调用报 connection refused / no such host / 超时。
诊断
# 1) DNS 是否可解析(用一次性 Pod)
kubectl -n server run dns-test --rm -i --restart=Never --image=busybox:1.36 --quiet -- \
nslookup kubernetes.default.svc.cluster.local # 预期能解析出 IP
# 2) 目标服务的 FQDN 格式:<svc>.<ns>.svc.cluster.local
kubectl get svc -n <目标 ns>
# 3) 目标端点是否就绪
kubectl -n <目标 ns> get endpoints <svc>
处置:DNS 失败 → 检查 CoreDNS(kubectl -n kube-system get pods -l k8s-app=kube-dns);端点为空 → 目标服务无就绪 Pod;跨命名空间引用被 Traefik 拒绝 → 该场景需在 Traefik values 中开启 allowCrossNamespace(属变更)。
验证:同一条 nslookup / curl 命令返回预期结果。
9. 安全与权限¶
- 命名空间内 Secret 清单(只列用途):Traefik(TLS 自签证书、Dashboard 口令)、GitLab(
gitlab-rails-secret等 20 个,含数据库/对象存储/组件密钥)、PG/Redis/MinIO 凭据、OpenLDAP(管理员口令、TLS)、MariaDB 口令。 - TLS:
- Traefik 使用内部 CA 自签证书(
traefik_deploy/certs/,有效期至 2036-09-13),为默认 TLSStore 证书。 - GitLab 经 Envoy Gateway 暴露,证书由 chart 自管(
gitlab-gitlab-tls类 Secret)。 - 轮换:替换 Secret 内容后
kubectl -n server rollout restart deploy/traefik(Traefik 会重载)。 - RBAC:本命名空间的工作负载多数使用各自 chart 创建的 ServiceAccount;集群级权限集中在
gitlab-*ClusterRole 与 Traefik 的 ClusterRole(只读 CRD 与 endpoints)。 - 访问控制:Traefik Dashboard 用 BasicAuth 中间件(
server/middleware/dashboard-auth);GitLab 自身有账号体系;phpLDAPadmin 走 LDAP 管理员认证。
10. 容量与性能¶
当前基线(2026-09-19 实测):
| 项 | 数值 |
|---|---|
server 命名空间 CPU requests 合计 |
3.73 核 |
server 命名空间内存 requests 合计 |
6.7 GiB |
server 命名空间存储(PVC 合计) |
117 GiB |
节点分配:k8s-master-01 |
4 核 / 7.4 GiB |
节点分配:k8s-node-01/02/03 |
各 8 核 / 15.3 GiB |
| 实际水位(全节点) | CPU 5–15%,内存 25–33% |
主要 Pod 落点:k8s-node-01 聚集了 Gitaly、PostgreSQL、MinIO、Redis 及多数 GitLab 组件(因 local PV 与存储亲和);k8s-node-03 有 Envoy 数据面、KAS、MariaDB、phpLDAPadmin。
扩容触发条件:
- 任一节点内存长期超过 70% → 优先排查 GitLab sidekiq / registry 的内存增长(
kubectl top pod -n server --sort-by=memory)。 k8s-node-01因聚集存储组件最先吃紧:若该节点 CPU/内存超 70%,应把无状态组件(sidekiq、registry 副本)通过节点亲和迁往node-02/03。- 存储:
pv-gitaly-ssd(20Gi)随仓库增长而增长,接近 80% 时需规划扩容(local PV 扩容需重建 PV 并迁移数据,属变更)。
已知瓶颈:k8s-node-01 单点承载全部 local PV 数据(Gitaly/PG/Redis),该节点故障会导致 GitLab 不可用且需人工介入恢复。
11. 附录¶
术语表¶
| 术语 | 含义 |
|---|---|
| entrypoint | Traefik 的监听端口定义(如 web=80、websecure=443、ldap=389) |
| IngressRoute / IngressRouteTCP | Traefik CRD 的 HTTP / TCP 路由资源(与 helm 无关,可热加载) |
| Gateway API | K8s 新一代入口标准(GitLab 用它 + Envoy Gateway,不经 Traefik) |
| local PV | 节点本地盘上的静态 PV(local-ssd),与节点强绑定 |
| claimRef 预绑定 | 在 PV 上预设目标 PVC 名(不写 uid),使绑定关系确定而非随机 |
相关文档¶
| 文档 | 位置 |
|---|---|
| 本次命名空间统一变更档案 | ns_migration/SOP.md |
| 本次变更中的两次阻塞故障 | ns_migration/INCIDENT-20260918-gitlab-ns-migration.md |
| Traefik 运行手册 / 部署 SOP | traefik_deploy/RUNBOOK.md、traefik_deploy/SOP.md |
| GitLab 运行手册 / 部署 SOP | gitlab-deploy-v2/RUNBOOK.md、gitlab-deploy-v2/SOP.md |
| LDAP 运行手册 / 部署 SOP | ldap-deploy/RUNBOOK.md、ldap-deploy/SOP.md |
| 数据非空场景的 GitLab 迁移方案 | ns_migration/GitLab迁移到server-方案与风险.md |
修订记录¶
| 日期 | 修改人 | 变更内容 |
|---|---|---|
| 2026-09-19 | 运维 | 首版:基于 2026-09-18 命名空间统一后的实际状态编写 |
来源:
/home/rain/Documents/k8s_ins/ns_migration/RUNBOOK.md| 最后更新:2026-09-19 16:50(由build/sync.py同步,请勿在站点侧修改)