3. Namespace深度解析:隔离的艺术

说实话,刚接触Kubernetes那会儿,我对Namespace的理解特别肤浅。就觉得它是个“文件夹”,把资源分门别类放好。直到有一次,我在生产环境里把测试服务的Pod误删了——嗯,就是因为没做Namespace隔离。从那以后,我才真正重视起这个看似简单的概念。

3.1 Namespace到底是什么?

Namespace,说白了就是K8s里的虚拟集群。一个物理集群可以拆成多个虚拟集群,每个虚拟集群之间资源是隔离的。你想想看,这就像一栋大楼里的不同房间——房间之间互不干扰,但都在同一栋楼里。

我个人习惯把Namespace比作“租户”。每个租户有自己的Pod、Service、ConfigMap,但看不到别的租户的东西。这在多团队协作的场景下特别有用。

核心要点:Namespace提供的是资源对象的逻辑隔离,不是网络隔离或安全隔离。如果你需要网络层面的隔离,那得用NetworkPolicy。

3.2 查看Namespace

查看Namespace很简单,就一条命令:

# 查看所有Namespace
kubectl get namespaces

# 或者简写
kubectl get ns

输出大概长这样:

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

看到这四个默认的Namespace了吗?default是你没指定Namespace时默认使用的;kube-system跑的是系统组件;kube-public是公开的;kube-node-lease跟节点心跳有关。我刚开始学的时候,老是把Pod丢到default里,后来发现这样特别乱。

3.3 创建Namespace

创建Namespace有两种方式。先看命令行的:

kubectl create namespace my-namespace

或者用YAML文件:

apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace

然后执行:

kubectl apply -f namespace.yaml

我个人更推荐用YAML方式。为什么?因为可以版本化管理。我曾经在一个项目里,所有Namespace都是手敲命令创建的,结果后来想回溯谁在什么时候创建了什么,完全查不到。用YAML文件配合Git,这些问题就迎刃而解了。

3.4 删除Namespace

删除Namespace要特别小心:

kubectl delete namespace my-namespace
⚠️ 警告:删除Namespace会级联删除里面所有的资源!Pod、Service、ConfigMap、Secret……全都没了。我曾经在生产环境里手滑删错了一个Namespace,还好有备份,不然就凉了。

所以我的建议是:

  • 删除前先确认里面有什么资源:kubectl get all -n my-namespace
  • 考虑先用kubectl delete加上--grace-period=0强制删除?不,别这么干。先正常删,等5分钟,不行再考虑强制。
  • 实在不行了,可以编辑Namespace的finalizers:kubectl edit namespace my-namespace,把finalizers清空。

3.5 资源配额(ResourceQuota)

有了Namespace,资源怎么分配?这就是ResourceQuota出场的时候了。

ResourceQuota说白了就是给Namespace“画个圈”。比如,你给某个团队分配了10个CPU、20G内存,他们最多只能用这么多,用完了就得等。

来看个例子:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
  namespace: my-namespace
spec:
  hard:
    requests.cpu: "4"
    requests.memory: "8Gi"
    limits.cpu: "8"
    limits.memory: "16Gi"
    pods: "10"
    services: "5"
    persistentvolumeclaims: "3"

这里我设置了:

  • 最多请求4个CPU、8G内存
  • 最多限制8个CPU、16G内存
  • 最多10个Pod、5个Service、3个PVC

我记得有一次,一个团队疯狂创建Pod,把集群资源全吃光了。后来加了ResourceQuota,他们想创建也创建不了,报错信息也很明确:exceeded quota。嗯,这就是规矩。

💡 小技巧:ResourceQuota的requestslimits要区分清楚。requests是“保证能拿到的”,limits是“最多能用到的”。我一般建议requests设小一点,limits设大一点,这样资源利用率更高。

3.6 限制范围(LimitRange)

ResourceQuota管的是Namespace的总量,那单个Pod或容器的资源限制谁来管?LimitRange。

LimitRange的作用是给Pod或容器设置默认的资源请求和限制。比如,你希望每个容器默认请求0.1个CPU、256M内存,限制0.5个CPU、512M内存,就可以用LimitRange。

看个例子:

apiVersion: v1
kind: LimitRange
metadata:
  name: my-limits
  namespace: my-namespace
spec:
  limits:
  - max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "0.1"
      memory: "128Mi"
    default:
      cpu: "0.5"
      memory: "512Mi"
    defaultRequest:
      cpu: "0.2"
      memory: "256Mi"
    type: Container

这里我设置了:

  • 每个容器最多2个CPU、4G内存
  • 每个容器最少0.1个CPU、128M内存
  • 默认限制0.5个CPU、512M内存
  • 默认请求0.2个CPU、256M内存

你想想看,如果没有LimitRange,开发人员可能随手写个resources: {},结果Pod跑起来后资源不受控。有了LimitRange,就算YAML里没写资源限制,系统也会自动加上默认值。

关键区别:
  • ResourceQuota:管的是Namespace的总量上限
  • LimitRange:管的是单个Pod/容器的资源范围
两者配合使用,才能实现精细化的资源管理。

3.7 知识体系图

下面这张图展示了Namespace、ResourceQuota、LimitRange之间的关系:

Namespace资源管理体系 Kubernetes 集群 Namespace: team-a ResourceQuota CPU: 8核 | 内存: 16Gi | Pod: 20 LimitRange 默认: 0.5核/512Mi | 最大: 2核/4Gi Pod Pod Pod Namespace: team-b ResourceQuota CPU: 4核 | 内存: 8Gi | Pod: 10 LimitRange 默认: 0.3核/256Mi | 最大: 1核/2Gi Pod Pod 隔离 每个Namespace拥有独立的ResourceQuota和LimitRange,资源互不干扰

3.8 实战建议

最后,分享几个我在项目中积累的经验:

  1. 命名规范要统一:我习惯用项目名-环境的格式,比如vllm-prodvllm-staging。别用拼音,也别用乱七八糟的缩写。
  2. ResourceQuota和LimitRange要一起配:光配ResourceQuota,单个Pod可能把配额全占了;光配LimitRange,总量可能失控。两者配合才是王道。
  3. 定期检查资源使用情况:用kubectl describe resourcequota -n my-namespace可以查看当前使用量。我一般每周看一次,发现某个Namespace快满了就提前扩容。
  4. 别滥用Namespace:不是所有东西都要分Namespace。我见过有人每个微服务一个Namespace,结果管理成本比收益还高。一般来说,按团队或环境分就够了。
💡 避坑指南:我曾经在创建Namespace时忘了加metadata.labels,后来想用Label Selector筛选Namespace,发现根本筛不了。所以,创建Namespace时就加上标签,比如env: prodteam: ai,方便后续管理。

好了,Namespace这块的内容就这些。记住一句话:Namespace是K8s资源隔离的基石,ResourceQuota和LimitRange是资源管控的左膀右臂。用好它们,你的集群管理会轻松很多。


公众号:蓝海资料掘金营,微信deep3321