K8S 之 Namespace

摘要

命名空间(Namespace) 介绍

  • 在 Kubernetes 中,命名空间提供了一种在单个集群中隔离资源组的机制。资源名称在命名空间内需要唯一,但不需要跨命名空间唯一。

  • 基于命名空间的作用域仅适用于命名空间对象 (例如,Deployments、Services 等),而不适用于集群范围的对象(例如 StorageClass、Nodes、PersistentVolumes 等)。

  • Namespace 是在多个用户之间划分集群资源的一种方法,适用于跨多个团队或项目的场景,Namespace 不能相互嵌套,每个 Kubernetes 资源只能在一个 Namespace 中。

  • 避免使用前缀 kube- 创建 Namespace,因为它是为 Kubernetes 系统 Namespace 保留的。

  • Kubernetes 启动时会创建四个初始 Namespace:

名称空间名称 说明
default 默认命名空间,供用户开始使用新集群时直接部署资源,无需额外创建命名空间。
kube-node-lease 存放与各个 Node 关联的 Lease(租约)对象,用于 Kubelet 发送心跳,帮助控制平面检测节点健康状态。
kube-public 所有客户端(包括匿名用户)都可以读取,主要用于集群范围内需要公开访问的资源。公共属性是一种使用约定。
kube-system Kubernetes 系统组件(如 kube-dns、kube-proxy 等)运行所在的命名空间。由系统自动管理。

查看集群中的命名空间

1
2
3
# namespace 可以简写为 ns
kubectl get namespace
kubectl get ns

创建命名空间

  • 命令行方式

1
kubectl create namespace <namespace-name>
  • yaml 方式

1
2
3
4
apiVersion: v1  # API 版本,可以通过 kubectl api-resources | grep Namespace 获取
kind: Namespace # 资源类型
metadata: # 元数据
name: <namespace-name> # 命名空间名称
1
kubectl apply -f <namespace.yaml>
  • 通过命令行直接生成yaml文件

1
2
# --dry-run=client: 本地模拟运行命令,不会真的执行,-o yaml: 输出yaml格式
kubectl create namespace <namespace-name> --dry-run=client -o yaml > <namespace.yaml>

删除命名空间

  • 命令行方式

1
kubectl delete namespace <namespace-name>
  • yaml 方式

1
kubectl delete -f <namespace.yaml>

设置名字空间偏好

1
2
# 默认为 default,即我们在执行 'kubbectl get pod' 时,默认会查看 default 这个名字空间下的所有 Pod
kubectl config set-context --current --namespace=<namespace-name>

查看资源时指定命名空间

1
2
3
4
5
6
kubectl get pod -n <namespace-name>
kubectl get service -n <namespace-name>

# 查看所有命名空间下的资源,-A, --all-namespaces
kubectl get pod -A
kubectl get service -A

并非所有对象都在名字空间中

1
2
3
4
5
# 位于名字空间中的资源
kubectl api-resources --namespaced=true

# 不在名字空间中的资源
kubectl api-resources --namespaced=false
  • kubectl api-resources 这个命令很有用,我们可以通过该命令获取所有资源的 简写,也可以获取资源的 apiVersion

1
2
3
4
5
6
kubectl api-resources
NAME: 资源名称
SHORTNAMES: 简写
APIVERSION: apiVersion
NAMESPACED: 是否在名字空间中
KIND: 资源类型

Kubernetes 中关于 命名空间(namespace)与 DNS 的机制

  • Kubernetes 服务有自动的 DNS 名称,它和命名空间有关。默认是能在本命名空间内直接访问;跨命名空间访问需要写完整域名(FQDN)。

  • 命名空间名字不能重复,且命名空间名字不能乱起,尤其不要用公共互联网域名名词(如 com、org、net、cn 等)。

举个例子说明服务 DNS 是怎么工作的

  • 场景:你在两个命名空间中部署了两个 nginx 服务

1
2
3
4
5
6
7
8
9
# 命名空间 dev 中创建服务 nginx
kubectl create ns dev
kubectl create deployment nginx --image=nginx --replicas=2 -n dev
kubectl expose deployment nginx --port=80 --type=NodePort -n dev

# 命名空间 prod 中也创建服务 nginx
kubectl create ns prod
kubectl create deployment nginx --image=nginx --replicas=2 -n prod
kubectl expose deployment nginx --port=80 --type=NodePort -n prod
  • 1️⃣ 如果你在 dev 命名空间的 Pod 里访问如下请求,它实际解析的 DNS 是 nginx.dev.svc.cluster.local,也就是 <服务名>.<命名空间>.svc.cluster.local

1
curl http://nginx
  • 2️⃣ 如果你想从 dev 命名空间访问 prod 命名空间的 nginx 服务,你必须这样访问

1
curl http://nginx.prod.svc.cluster.local