K8S - 命名空间实战 - 从资源隔离到多环境管理

引言

在传统的物理机或虚拟机环境中,不同业务应用共享资源,容易导致权限冲突、资源争用和管理混乱。Kubernetes 通过 命名空间(Namespace)实现资源逻辑隔离,将集群划分为多个虚拟子集群,从而解决以下问题:

• 资源组织:按业务、团队或环境分类管理

• 权限控制:限制用户/服务账号的操作范围

• 资源限制:分配 CPU/内存配额,防止资源抢占

• 环境隔离:支持开发、测试、生产环境独立部署

一、核心原理

1.1 命名空间的本质

命名空间是一种 逻辑隔离机制,使得集群中的资源独立管理,但仍共享底层物理资源。

• 资源独立:同名资源(如 Deployment、Service)可在不同命名空间共存。

• 默认网络互通:跨命名空间访问需指定完整域名。

1.2 命名空间分类

系统级命名空间示例:

类型 说明
系统级命令空间 由Kubernetes自动创建,存放核心组件
用户自定义命名空间 由用户创建,用于业务应用部署

• default:默认命名空间(未指定时资源部署至此)

• kube-system:存放集群核心组件(如 kube-proxy、CoreDNS)

• kube-public:可供所有用户读取(含未认证用户)

• kube-node-lease:管理节点心跳信息

注意:业务应用请勿部署到系统命名空间,避免影响集群稳定性!

二、实战:命名空间创建与应用部署

首先确保你已经完成如下环境准备。

2.1 环境搭建

1.安装必要工具

确保已安装并配置好以下环境:

• Kubernetes 集群(可使用 Minikube 或 Kind 进行本地测试)

• kubectl命令行工具

• Docker(用于构建镜像)

如果还没有环境,可使用如下命令安装。

java 复制代码
# 安装 Docker 并验证
brew install docker
docker --version          # 预期输出:Docker version 20.10.x
docker run hello-world    # 验证基础功能
# 安装 kubectl 并验证
brew install kubectl
kubectl version --client  # 预期输出:Client Version: v1.28.x
# 安装 kind 并验证
brew install kind
kind version              # 预期输出:kind v0.20.x

2.创建本地 Kubernetes 集群

java 复制代码
kind create cluster --name k8s-demo
kubectl cluster-info  # 确认集群正常运

到此k8s 集群环境已经准备完毕。

2.2 创建与删除命名空间

空间命名规范:符合 DNS-1123 标准,

• 仅包含小写字母、数字和 -

• 以字母开头和结尾

方法 1:命令行创建命名空间

通过 kubectl命令行工具直接创建命名空间,适合快速操作。

java 复制代码
# 创建命名空间
kubectl create namespace dev

# 删除命名空间(谨慎操作)
kubectl delete namespace dev
删除命名空间是 异步过程,状态从 Active → Terminating,其下所有资源将被清理。

在同一命名空间,不能重复创建相同的命名空间。示例

# 第一次创建(成功)
kubectl create namespace dev
# Output: namespace/dev created

# 第二次重复创建(失败)
kubectl create namespace dev
# Output: Error from server (AlreadyExists): namespaces "dev" already exists

方法 2:YAML文件创建命名空间

通过 YAML 文件创建命名空间,适合版本控制和自动化管理。

java 复制代码
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: testing
# 将 namespace空间设置应用到集群
kubectl apply -f namespace.yaml
# 第一次应用(成功)
kubectl apply -f namespace.yaml
# Output: namespace/dev created
# 第二次重复应用(无变化)
kubectl apply -f namespace.yaml
# Output: namespace/dev unchanged

特点

  • 幂等性:如果命名空间已存在,不会报错,而是维持现状。
  • 版本控制:YAML 文件可提交至 Git,便于团队协作和变更审计。
  • 扩展性:支持添加标签(labels)和注解(annotations),例如:
java 复制代码
apiVersion: v1
kind: Namespace
metadata:
  name: dev
  labels:
    env: development  # 资源环境标签
  annotations:
    owner: team-a     # 资源归属注解

也可通过命令为命名空间添加标签:

为命名空间添加标签

java 复制代码
kubectl label ns dev env=development
# 按标签过滤资源
kubectl get pods -n dev -l env=development

方式3:通过 Kubernetes API 编程创建

示例(Python + Kubernetes API)

java 复制代码
from kubernetes import client, config

# 加载 kubeconfig 配置
config.load_kube_config()

# 创建 API 客户端
v1 = client.CoreV1Api()

# 定义命名空间对象
namespace_name = "dev"
namespace = client.V1Namespace(metadata=client.V1ObjectMeta(name=namespace_name))

# 创建命名空间,异常处理
try:
    v1.create_namespace(body=namespace)
    print(f"Namespace '{namespace_name}' created successfully")
except client.exceptions.ApiException as e:
    if e.status == 409:
        print(f"Namespace '{namespace_name}' already exists.")
    else:
        print(f"Failed to create namespace '{namespace_name}': {e}")

适用场景

适用于 CI/CD,在部署流程中动态管理命名空间。

自动化集成,便于与 Python、Go、Java 编写的 Kubernetes 管理工具结合。

对比三种创建方式

2.3 在命名空间中部署应用

1.部署应用

方式 1:在 Manifest 文件中指定命名空间 (可使用 第4讲 2.3 中 示例 )

java 复制代码
# k8s/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: gitops-demo-app
  namespace: dev  # 指定命名空间

spec:
  replicas: 2

  selector:
    matchLabels:
      app: gitops-demo-app

  template:
    metadata:
      labels:
        app: gitops-demo-app

    spec:
      containers:
        - name: app
          image: your-dockerhub-username/gitops-demo-app:v1  # 替换为你的镜像
          ports:
            - containerPort: 5000
java 复制代码
# 检查命名空间是否存在,不存在则创建
kubectl get ns dev || kubectl create ns dev
把 deployment 应用到集群

kubectl apply -f deployment.yaml 

方式 2:命令行指定命名空间(推荐)

java 复制代码
kubectl apply -f deployment.yaml -n dev

2.查看命名空间资源

查看上面示例输出:

java 复制代码
#查看 dev 命名空间下的 deployment 
kubectl get deployment -n dev

NAME              READY   UP-TO-DATE   AVAILABLE   AGE
gitops-demo-app   2/2     2            2           17h

# 查看dev命名空间下的所有资源 (Pod/Service等)
kubectl get all -n dev

NAME                                  READY   STATUS    RESTARTS   AGE
pod/gitops-demo-app-5d7b98d8d-2j6qk   1/1     Running   0          17h
pod/gitops-demo-app-5d7b98d8d-8k9xv   1/1     Running   0          17h

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/gitops-demo-app   2/2     2            2           17h

NAME                                        DESIRED   CURRENT   READY   AGE
replicaset.apps/gitops-demo-app-5d7b98d8d   2         2         2       17h

注:UP-TO-DATE 表示已更新的 Pod 数。

三、实战:跨命名空间通信

3.1 基础知识

Kubernetes 默认允许跨命名空间访问,但需要使用 完整的 DNS 名称:

<服务名>.<命名空间>.svc.cluster.local

• 服务名:Service 资源的名称(如 backend-service)。

• 命名空间:Service 所在的命名空间(如 dev)。

• svc.cluster.local:集群默认的 DNS 后缀(可配置)。

在同一命名空间中访问服务时,使用服务名即可:

• 同一命名空间:backend-service:80

在跨命名空间访问时,必须使用完整的 DNS 名称:

• 跨命名空间:backend-service.dev.svc.cluster.local:80

3.2 实战示例 - 跨命名空间访问

步骤 1:在 dev 命名空间创建 Service

通过 kubectl expose命令暴露 Deployment 为 Service(ClusterIP 类型):

java 复制代码
kubectl expose deployment gitops-demo-app -n dev --port=80 --target-port=5000

参数说明:

• -n dev:指定命名空间为 dev。

• --port=80:Service 对外暴露的端口。

• --target-port=5000:容器内应用实际监听的端口(需与 Deployment 中定义的 containerPort一致)。

kubectl expose默认会直接创建 Service 并将其应用到集群中。等效的 Service YAML 配置(命令生成的 Service)为:

java 复制代码
apiVersion: v1
kind: Service
metadata:
  name: gitops-demo-app
  namespace: dev
spec:
  selector:
    app: gitops-demo-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
  type: ClusterIP

验证 Service

执行以下命令验证 Service 是否创建成功:

java 复制代码
kubectl get svc -n dev
预期输出:

NAME               TYPE        CLUSTER-IP      PORT(S)   AGE
gitops-demo-app    ClusterIP   10.96.123.456   80/TCP    5s

步骤 2:从 prod 命名空间发起跨命名空间访问

启动一个临时 Pod 测试跨命名空间访问:

java 复制代码
kubectl run curl-test -n prod \
  --image=curlimages/curl \
  --rm -it -- \
  curl http://gitops-demo-app.dev.svc.cluster.local

参数说明:

• -n prod:在 prod命名空间中运行 Pod。

• --rm -it:容器退出后自动删除此临时容器,并分配交互式终端。

• curl :测试访问目标 Service。

预期结果:

• 成功:返回 gitops-demo-app服务的响应内容(例如:GitOps Demo v1,具体内容可见 Deployment 文件)。

• 失败的可能原因:

1.目标 Service未正确暴露端口。

2.NetworkPolicy限制了跨命名空间访问。

四、实战:资源配额限制

创建命名空间时增加资源限制,可以通过创建一个 LimitRange对象来限制该命名空间中的资源。LimitRange是 Kubernetes 中用于定义资源限制的策略,可以限制容器的 CPU 和内存等资源。

将 LimitRange和 Namespace一起创建,确保命名空间创建后自动应用这些资源限制。

1.创建 namespace.yaml 和 limitrange.yaml

java 复制代码
# namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: testing

---

# limitrange.yaml

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limit
  namespace: testing
spec:
  limits:
  - max: 
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "200m"
      memory: "512Mi"
    default:
      cpu: "1"
      memory: "1Gi"
    defaultRequest:
      cpu: "500m"
      memory: "1Gi"
    type: Container

解析:

LimitRange资源限制了testing 命名空间中容器的资源使用:

1.max - 限制容器的 最大CPU 和内存使用量,防止某个容器占用过多资源。

• CPU 最大 2 核(2),即容器最多只能申请 2 核 CPU。

• 内存最大 4Gi(4Gi),即容器最多只能申请 4GB 内存。

2.min(最小值)- 规定容器的最小资源申请量,避免某些 Pod 资源太少而影响运行。

• 最小 CPU 为 200毫核(200m),内存为 512Mi。

3.default(默认值)-如果 Pod 没有明确指定资源限制,那么 Kubernetes 自动分配的资源值。

• 默认 CPU 为 1 核,内存为 1Gi。

4.defaultRequest(默认请求)- 如果 Pod 没有指定请求资源,Kubernetes 自动分配的最小起始值。

• 默认请求 CPU 为 500m,内存为 1Gi。

2.应用到集群中

java 复制代码
kubectl apply -f namespace.yaml
kubectl apply -f limitrange.yaml

两个 YAML 文件都在同一个目录下,也可以一次性应用:

java 复制代码
kubectl apply -f .

这样,testing命名空间会被创建,同时应用了资源限制策略。

五、使用场景与最佳实践

5.1 何时使用命名空间?

5.2 命名空间规划建议

小型团队:

• 按环境划分:dev、testing、prod

• 按业务划分:web、database

大型组织:

• 独立集群 + 命名空间:每个团队独立集群,内部再划分命名空间。

六、总结

6.1 核心重点

• 核心价值:命名空间通过逻辑隔离实现资源组织、权限控制和环境管理,是 Kubernetes 多租户能力的关键。

• 软隔离 vs 硬隔离:

• 软隔离:命名空间(同一集群内逻辑隔离)

• 硬隔离:独立集群(物理隔离)

最佳实践:

• 避免修改系统命名空间,业务应用请用自定义命名空间

• 使用 -n 参数指定部署环境,避免误操作

附:操作速查表

java 复制代码
# 查看所有命名空间
kubectl get ns
# 快速切换默认命名空间(避免频繁输入 -n)
kubectl config set-context --current --namespace=dev
# 设置命名空间资源配额(需提前定义 ResourceQuota)
kubectl apply -f quota.yaml -n dev
相关推荐
小马爱打代码8 分钟前
K8S - GitOps 入门实战 - 自动发布与秒级回滚
云原生·容器·kubernetes
jk英菲尼迪1 小时前
Windows系统安装Docker(Win10系统升级,然后安装)
运维·docker·容器
国际云,接待3 小时前
甲骨文云2025深度解析:AI驱动的云原生生态与全球化突围
运维·服务器·人工智能·云原生·性能优化·云计算·量子计算
野生绿箭侠4 小时前
Docker 部署 flink1.19.2
运维·docker·容器
qq7422349847 小时前
AI开发者的Docker实践:汉化(中文),更换镜像源,Dockerfile,部署Python项目
python·docker·容器
佳腾_7 小时前
【分布式系统中的“瑞士军刀”_ Zookeeper】二、Zookeeper 核心功能深度剖析与技术实现细节
分布式·zookeeper·云原生·集群管理·命名服务
欧先生^_^8 小时前
删除k8s某命名空间,一直卡住了怎么办?
云原生·容器·kubernetes
王中阳Go10 小时前
最新字节跳动运维云原生面经分享
运维·后端·云原生·面试·golang
阿湯哥11 小时前
外部访问 Kubernetes 集群中 MQ 服务的方案
云原生·容器·kubernetes