返回首页

2.5 Namespace 与资源隔离:多环境与多团队基础

Kubernetes 是一个共享集群平台。只要集群里不止一个应用、不止一个团队,甚至只是同时存在开发、测试、生产三套环境,你很快就会遇到“资源怎么分组、名字怎么隔离、权限怎么划边界”的问题。Namespace 就是解决这类问题的基础设施。::cite[421]

Namespace 不是“更高级的目录”,也不是“更强的安全沙箱”,它首先是一个集群内资源分组与作用域隔离机制。在单个集群里,它让不同团队、不同环境、不同项目可以更清晰地组织资源,并为后续的资源配额和权限控制提供边界。::cite[421]::cite[521]::cite[166]

2.5.1 Namespace 的作用与适用场景

官方文档对 Namespace 的定义非常明确:它为单个集群中的一组资源提供隔离机制。很多对象的名字只需要在同一个 Namespace 内唯一,而不需要在整个集群范围唯一。::cite[421]

例如:

  • 你可以在 dev 命名空间里有一个 web Deployment。
  • 同时也可以在 prod 命名空间里再有一个同名 web Deployment。

这在多环境管理中非常实用。

Namespace 主要解决什么问题?

1)资源分组

把同一类资源放在一起,例如:

  • dev
  • test
  • staging
  • prod
  • team-a
  • team-b

2)名称隔离

同一个资源名可以在不同 Namespace 中重复使用。

3)访问边界

RBAC 中的 Role / RoleBinding 很多都是以 Namespace 为作用域的,可以做到“某个团队只能管理自己命名空间里的资源”。::cite[166]

4)资源配额边界

ResourceQuota 和 LimitRange 通常也是按 Namespace 生效,用来防止某个团队抢占过多集群资源。::cite[521]

什么时候适合使用多个 Namespace?

官方建议:当集群开始被多个用户、团队或项目共享时,就应该考虑 Namespace。::cite[421]

常见场景包括:

  • 多团队共享一个集群
  • 同一业务的多环境隔离
  • 平台团队统一托管多个项目
  • 需要按团队或环境做权限控制和资源配额

什么时候没必要过度拆 Namespace?

如果只是“同一个应用的几个版本”或者“轻微配置差异”,官方建议优先用 labels 来区分,而不是动不动就新建 Namespace。::cite[421]

2.5.2 默认命名空间与自定义命名空间

一个新集群里,Kubernetes 默认就会带几个初始 Namespace。::cite[421]

Namespace 作用
default 默认工作空间,未指定时资源通常落在这里
kube-system Kubernetes 系统组件所在命名空间
kube-public 约定上可被所有客户端读取的公共命名空间
kube-node-lease 保存节点 Lease,用于节点心跳与故障检测

default 能不能一直用?

技术上当然可以,但官方对生产集群给出的建议是:尽量不要长期把业务都放在 default 命名空间里。更好的做法是,根据团队或环境明确创建自己的 Namespace。::cite[421]

这样做的好处有三个:

  • 资源归属更清晰
  • 权限边界更清晰
  • 排查与运维动作更不容易误操作到别的业务

查看当前命名空间列表

kubectl get namespace

示例输出:

NAME              STATUS   AGE
default           Active   1d
kube-node-lease   Active   1d
kube-public       Active   1d
kube-system       Active   1d

2.5.3 创建和使用自定义命名空间

最基础的 Namespace YAML

apiVersion: v1
kind: Namespace
metadata:
  name: team-a-dev

创建方式:

kubectl apply -f namespace-team-a-dev.yaml

指定资源属于哪个 Namespace

你可以在 YAML 里显式写 metadata.namespace

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: team-a-dev
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

也可以在命令行里临时指定:

kubectl get pods -n team-a-dev

设置当前上下文默认 Namespace

如果你经常操作某个命名空间,可以直接把当前 kubectl 上下文切过去:

kubectl config set-context --current --namespace=team-a-dev

验证:

kubectl config view --minify | grep namespace:

这样之后大部分命令就不用每次都写 -n 了。::cite[421]

2.5.4 通过命名空间组织环境、团队与应用

Namespace 最常见的组织方式,大致有三类。

方式 1:按环境拆分

例如:

  • dev
  • test
  • staging
  • prod

优点:

  • 环境边界清晰
  • 不同环境可以有不同配额和权限
  • 与 CI/CD 流水线对应关系明确

适合:

  • 中小团队
  • 单业务多环境管理

方式 2:按团队拆分

例如:

  • team-a
  • team-b
  • platform
  • data

优点:

  • 团队自治边界清晰
  • 配合 RBAC 很方便
  • 适合平台型共享集群

适合:

  • 多团队共用一个集群
  • 平台团队统一运维基础设施

方式 3:团队 + 环境组合

这是很多生产环境最常见的方式,例如:

  • team-a-dev
  • team-a-prod
  • team-b-dev
  • team-b-prod

优点:

  • 同时表达“归谁”和“处于什么环境”
  • 审计、授权、配额都更直观

一个完整示例:两个环境命名空间

apiVersion: v1
kind: Namespace
metadata:
  name: development
---
apiVersion: v1
kind: Namespace
metadata:
  name: production

应用资源分别放到对应环境:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: development
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: production
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.27
          ports:
            - containerPort: 80

这时,两个 Namespace 里都可以有一个名为 web 的 Deployment,互不冲突。::cite[421]

2.5.5 Namespace 与 DNS 的关系

Namespace 不只是“组织方式”,它还会影响 Service 的 DNS 解析行为。官方说明,Service 的 DNS 名称通常形如:

<service-name>.<namespace>.svc.cluster.local

例如:

api.production.svc.cluster.local

如果客户端 Pod 与目标 Service 在同一 Namespace 中,通常只写 Service 名即可;跨命名空间访问时,则建议明确写出 <service>.<namespace> 或完整 FQDN。::cite[421]

这也是为什么,同一个配置模板可以在多个环境复用:

  • 开发环境中,api 解析到 api.development.svc.cluster.local
  • 生产环境中,api 解析到 api.production.svc.cluster.local

Namespace 在这里天然承担了环境隔离作用。::cite[421]

2.5.6 Namespace 与资源配额的关系

Namespace 自身不直接限制资源使用,但它是 ResourceQuota 生效的边界。官方文档明确指出,ResourceQuota 用来限制某个命名空间内总体资源消耗,防止共享集群里某个团队吃掉过多 CPU、内存、存储或对象数量。::cite[521]

一个简单的 ResourceQuota 示例

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a-dev
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 8Gi
    pods: "20"
    services: "10"
    configmaps: "20"
    secrets: "20"

这表示:

  • team-a-dev 命名空间最多能申请 20 个 Pod
  • CPU / 内存请求与限制都有总量约束
  • Service、ConfigMap、Secret 的数量也可被限制::cite[521]

实操步骤

  1. 创建 Namespace。
kubectl create namespace team-a-dev
  1. 应用配额。
kubectl apply -f quota.yaml
  1. 查看配额使用情况。
kubectl describe quota -n team-a-dev

配额的现实意义

这在共享集群里特别重要,因为它能避免:

  • 某团队误创建大量 Pod
  • 某应用无限制请求资源
  • API 对象数量失控

2.5.7 Namespace 与权限控制的关系

Namespace 还是 RBAC 非常重要的作用域边界。RBAC 通过 RoleRoleBinding 等对象,把“谁能对哪些资源做什么操作”表达出来。::cite[166]

一个最小角色授权示例

下面例子表示:用户组 team-a-developers 可以在 team-a-dev 命名空间里查看和管理常见工作负载,但不能越权到其它命名空间。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: team-a-developer-role
  namespace: team-a-dev
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: team-a-developer-binding
  namespace: team-a-dev
subjects:
  - kind: Group
    name: team-a-developers
    apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: team-a-developer-role
  apiGroup: rbac.authorization.k8s.io

这个模型的价值在于:

  • 同一个集群可以安全地给多个团队共用
  • 权限做到按命名空间收口
  • 运维与审计范围更明确::cite[166]

2.5.8 一个推荐的多团队命名空间模板

下面给出一套比较实用的 Namespace 落地模板:

apiVersion: v1
kind: Namespace
metadata:
  name: team-a-dev
  labels:
    team: team-a
    env: dev
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-dev-quota
  namespace: team-a-dev
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 4Gi
    limits.cpu: "4"
    limits.memory: 8Gi
    pods: "20"
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: team-a-dev-role
  namespace: team-a-dev
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps", "secrets"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]

这套模板体现了 Namespace 的三个核心价值:

  • 有清晰的环境与归属标签
  • 有资源上限
  • 有权限边界

2.5.9 常见注意事项

1)不要把所有业务都堆在 default

尤其是生产环境,强烈建议按团队或环境创建自定义命名空间。::cite[421]

2)不要把 Namespace 当成强安全边界的全部

Namespace 是重要边界,但不是唯一边界。真正的隔离能力仍然依赖:

  • RBAC
  • ResourceQuota / LimitRange
  • NetworkPolicy
  • Pod Security 等策略

3)不要滥建 Namespace

Namespace 太多也会带来管理复杂度。只是一些轻微版本差异时,优先考虑 labels。::cite[421]

4)避免使用 kube- 前缀命名业务 Namespace

官方明确提示,这个前缀保留给系统命名空间。::cite[421]

5)关注跨命名空间访问

跨 Namespace 的 Service 访问要注意 DNS 名称写法,特别是同名服务在不同 Namespace 下共存时,更要写清楚调用目标。::cite[421]

2.5.10 本章小结

这一章的核心结论可以归纳为五句话:

  1. Namespace 是单集群内资源分组与作用域隔离的基础。
  2. 它最适合用来组织多团队、多项目、多环境。
  3. default 只适合起步,不适合长期承载全部生产业务。
  4. ResourceQuota 与 RBAC 通常都以 Namespace 为边界发挥作用。
  5. Namespace 不是全部隔离能力,但它是后续治理的起点。

当你的集群开始走向共享化、平台化时,Namespace 往往是第一层必须做好的治理基础。把这层打稳,后面的配额、权限、网络策略、审计与成本管理,才会真正有抓手。


📝 版权声明:本文为原创技术博客,转载请注明出处。

如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!

上一篇

8.4 性能调优与生产最佳实践

下一篇

4.1 Kubernetes 网络模型