引言
在传统的物理机或虚拟机环境中,不同业务应用共享资源,容易导致权限冲突、资源争用和管理混乱。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