3. Project与Namespace生命周期自动化
在 OpenShift 中,Project 是带注解与权限边界的 Namespace,二者在 API 层面共享同一资源对象。多团队共用集群时,手工创建 Namespace 会带来三类问题:命名不规范导致资源难以检索、配额与网络策略遗漏导致资源争抢或越权访问、团队下线后 Namespace 长期残留占用配额与 IP 地址。生命周期自动化的目标,就是把“创建—配置—隔离—回收”四个阶段固化为可版本化、可审计、可重复执行的声明式流程。
一、生命周期四阶段与自动化载体
一个 Namespace 从申请到回收,通常经历四个阶段,每个阶段适合的自动化载体不同:
- 创建:由模板或 GitOps 声明生成 Namespace 对象,附带标准标签(如
team、env、cost-center)与注解。 - 配置:同步创建 ResourceQuota、LimitRange、NetworkPolicy、RoleBinding 等配套对象。
- 隔离:通过网络策略与 RBAC 限制跨 Namespace 访问,必要时启用多租户网络隔离。
- 回收:团队下线时按顺序清理工作负载、释放配额、归档审计信息,最后删除 Namespace。
下图展示了这四个阶段与对应自动化载体的关系,以及每个阶段的关键产出对象:
二、模板化创建:从手工到声明式
最直接的自动化方式是用模板生成 Namespace 及其配套资源。OpenShift 提供 oc new-project 命令,但批量场景更适合用 YAML 模板配合 oc apply。以下是一个团队命名空间的模板示例,包含标准标签与配额:
apiVersion: v1
kind: Namespace
metadata:
name: team-alpha-dev
labels:
team: alpha
env: dev
cost-center: cc-1024
annotations:
owner: alpha-lead@example.com
created-by: gitops
---
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-alpha-quota
namespace: team-alpha-dev
spec:
hard:
requests.cpu: "8"
requests.memory: 16Gi
limits.cpu: "16"
limits.memory: 32Gi
pods: "40"
---
apiVersion: v1
kind: LimitRange
metadata:
name: team-alpha-limits
namespace: team-alpha-dev
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 200m
memory: 256Mi
type: Container
模板化的关键不在于 YAML 本身,而在于参数化。把 team、env、quota 抽成变量,用 envsubst 或 Helm 渲染,就能为不同团队生成一致结构的命名空间。例如用 Helm 的 values.yaml 定义每个团队的配额档位,模板中引用 {{ .Values.quota.cpu }},避免每个团队手写一份 YAML。
三、GitOps 方式:让集群状态跟随 Git
模板解决了“生成”问题,但没有解决“持续一致”。GitOps 的核心是把 Git 仓库作为期望状态的唯一来源,由 Argo CD 或 OpenShift GitOps 持续比对并同步。推荐目录结构如下:
clusters/
prod/
namespaces/
team-alpha/
namespace.yaml
quota.yaml
networkpolicy.yaml
rbac.yaml
team-beta/
...
kustomization.yaml
每个团队的目录是一个 Kustomize 单元,kustomization.yaml 列出该团队所有资源文件。Argo CD 的 Application 指向 clusters/prod/namespaces/team-alpha,开启 syncPolicy.automated.prune=true 与 selfHeal=true。这样当有人手动修改集群中的配额时,Argo CD 会自动回滚到 Git 中的值;当 Git 中删除某个资源文件时,集群中对应对象也会被清理。
四、隔离配置:网络与权限的双重边界
Namespace 本身只是逻辑分组,默认情况下所有 Pod 可以跨 Namespace 通信。真正的隔离需要 NetworkPolicy 与 RBAC 配合。以下策略实现“同团队可互通、跨团队默认拒绝”:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: team-alpha-dev
spec:
podSelector: {}
policyTypes:
- Ingress
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-same-team
namespace: team-alpha-dev
spec:
podSelector: {}
ingress:
- from:
- namespaceSelector:
matchLabels:
team: alpha
policyTypes:
- Ingress
第一条策略拒绝所有入站流量,第二条只允许带有 team: alpha 标签的 Namespace 访问。RBAC 方面,通过 RoleBinding 将团队用户绑定到 edit 或 admin 角色,但限制在自身 Namespace 内。注意不要给团队用户 cluster-admin,否则网络隔离形同虚设。
五、回收:顺序比速度更重要
Namespace 删除会级联清理其中所有资源,但直接删除可能造成两个问题:一是正在运行的工作负载被强制终止,可能丢失未持久化的数据;二是 PVC、LoadBalancer Service 等外部资源可能残留。推荐的回收顺序是:
- 将工作负载副本缩为 0,等待 Pod 优雅退出。
- 删除 Service、Route、PVC 等对外资源,确认云负载均衡器已释放。
- 删除 ResourceQuota、LimitRange、NetworkPolicy、RoleBinding。
- 最后删除 Namespace 对象。
在 GitOps 模式下,这个顺序通过分阶段 PR 实现:第一个 PR 缩容,第二个 PR 删除资源清单,第三个 PR 删除 Namespace 清单。每次 PR 合并后 Argo CD 同步,运维人员可在 Argo CD 界面观察同步状态与资源健康度。若 Namespace 卡在 Terminating 状态,通常是因为有 finalizer 未完成,可用 oc get namespace team-alpha-dev -o json 查看 spec.finalizers,定位是哪个控制器未释放。
六、标准化检查清单
为了让多团队环境保持一致,可以在 CI 流水线中加入校验步骤,对每个 Namespace 目录检查以下项:
| 检查项 | 要求 | 失败后果 |
|---|---|---|
| 命名规范 | 符合 team-<name>-<env> | 资源难以检索 |
| 标签完整性 | 包含 team、env、cost-center | 配额统计与计费缺失 |
| ResourceQuota | 必须存在且 CPU/内存上限合理 | 单团队耗尽集群资源 |
| LimitRange | 必须存在默认 request/limit | Pod 无限制运行 |
| NetworkPolicy | 至少一条 default-deny | 跨团队未授权访问 |
| RBAC | RoleBinding 限定在本 Namespace | 权限越界 |
这些检查可以用 conftest 或 kubeconform 在 PR 阶段执行,不通过则阻止合并。这样就把“标准化”从口头约定变成了流水线中的硬性门禁,配合 GitOps 的持续同步,最终实现多团队 Namespace 从创建到回收的全生命周期自动化治理。