Kubernetes通过名称空间(namespace)在同一个物理集群上支持多个虚拟集群.
名称空间的用途是,为不同团队的用户(或项目)提供虚拟的集群空间,也可以用来区分开发环境/测试环境、准上线环境/生产环境。
名称空间为名称提供了作用域。名称空间内部的同类型对象不能重名,但是跨名称空间可以有同名同类型对象。名称空间不可以嵌套,任何一个Kubernetes对象只能在一个名称空间中。
名称空间可以用来在不同的团队(用户)之间划分集群的资源.
当对象之间的差异不大时,无需使用名称空间来区分,例如,同一个软件的不同版本,只需要使用 labels 来区分即可。

查看名称空间

kubectl get namespaces

默认会输出三个初始化名称空间:

  • default 默认名称空间,如果 Kubernetes 对象中不定义 metadata.namespace 字段,该对象将放在此名称空间下
  • kube-system Kubernetes系统创建的对象放在此名称空间下
  • kube-public 此名称空间自动在安装集群是自动创建,并且所有用户都是可以读取的(即使是那些未登录的用户)。主要是为集群预留的,例如,某些情况下,某些Kubernetes对象应该被所有集群用户看到。

kubectl describe namespaces <名称空间的名字> #查看更详细的名称空间信息

输出结果

Resource quota 汇总了名称空间中使用的资源总量,并指定了集群管理员定义该名称空间最多可以使用的资源量
Limit range 定义了名称空间中某种具体的资源类型的最大、最小值
名称空间可能有两种状态(phase):
Active 名称空间正在使用中
Termining 名称空间正在被删除,不能再向其中创建新的对象

在执行请求时设定namespace

kubectl run nginx --image=nginx --namespace=<名称空间的名字>
kubectl get pods --namespace=
<名称空间的名字>

设置名称空间偏好

可以通过 set-context 命令改变当前 kubectl 上下文 的名称空间,后续所有命令都默认在此名称空间下执行。

kubectl config set-context --current --namespace=<名称空间的名字>

验证

kubectl config view --minify | grep namespace:

名称空间与DNS

当您创建一个 Service 时,Kubernetes 为其创建一个对应的 DNS 条目。该 DNS 记录的格式为 <service-name>.<namespace-name>.svc.cluster.local,也就是说,如果在容器中只使用 <service-name>,其DNS将解析到同名称空间下的 Service。这个特点在多环境的情况下非常有用,例如将开发环境、测试环境、生产环境部署在不同的名称空间下,应用程序只需要使用 <service-name> 即可进行服务发现,无需为不同的环境修改配置。如果您想跨名称空间访问服务,则必须使用完整的域名。

并非所有对象都在名称空间里

大部分的 Kubernetes 对象(例如,Pod、Service、Deployment、StatefulSet等)都必须在名称空间里。但是某些更低层级的对象,是不在任何名称空间中的,例如 nodes、persistentVolumes、storageClass 等
执行一下命令可查看哪些 Kubernetes 对象在名称空间里,哪些不在:

kubectl api-resources --namespaced=true #在名称空间里

kubectl api-resources --namespaced=false #不在名称空间里

创建名称空间

通过 yaml 文件

vim namespace.yaml 

apiVersion: v1
kind: Namespace
metadata:
name: <名称空间的名字>

kubectl create -f ./my-namespace.yaml

直接使用命令

kubectl create namespace <名称空间的名字>

删除名称空间

kubectl delete namespaces <名称空间的名字>

使用名称空间切分集群

需求:
假设企业使用同一个集群作为开发环境和生产环境(注意:通常开发环境和生产环境是物理隔绝的):
开发团队期望有一个集群中的空间,以便他们可以查看查看和使用他们创建的 Pod、Service、Deployment等。在此空间中,Kubernetes对象被创建又被删除,为了适应敏捷开发的过程,团队中的许多人都可以在此空间内做他们想做的事情。
运维团队也期望有一个集群中的空间,在这里,将有严格的流程控制谁可以操作 Pod、Service、Deployment等对象,因为这些对象都直接服务于生产环境。

创建名称空间

vim dev.yaml

apiVersion: v1
kind: Namespace
metadata:
name: development
labels:
name: development

vim prod.yaml

apiVersion: v1
kind: Namespace
metadata:
name: production
labels:
name: production

kubectl apply -f dev.yaml
kubectl apply -f prod.yaml

配置kubectl上下文

kubectl config view

取值cluster和user

kubectl config set-context dev --namespace=development --cluster=kubernetes --user=kubernetes-admin
kubectl config set-context prod --namespace=production --cluster=kubernetes --user=kubernetes-admin

切换dev名称空间

kubectl config use-context dev

创建nginx

kubectl create deployment nginx --image nginx

查看deployment

kubectl get deployment

切换prod名称空间

kubectl config use-context prod

至此,我们可以了解到,用户在一个名称空间创建的内容对于另外一个名称空间来说是不可见的。

为什么需要名称空间

一个Kubernetes集群应该可以满足多组用户的不同需要。Kubernetes名称空间可以使不同的项目、团队或客户共享同一个 Kubernetes 集群。实现的方式是,提供:

  • 名称 的作用域
  • 为不同的名称空间定义不同的授权方式和资源分配策略 Resource Quota 和 resource limit range

每一个用户组都期望独立于其他用户组进行工作。通过名称空间,每个用户组拥有自己的:

  • Kubernetes 对象(Pod、Service、Deployment等)
  • 授权(谁可以在该名称空间中执行操作)
  • 资源分配(该用户组或名称空间可以使用集群中的多少计算资源)

可能的使用情况有:

  • 集群管理员通过一个Kubernetes集群支持多个用户组
  • 集群管理员将集群中某个名称空间的权限分配给用户组中的受信任的成员
  • 集群管理员可以限定某一个用户组可以消耗的资源数量,以避免其他用户组受到影响
  • 集群用户可以使用自己的Kubernetes对象,而不会与集群中的其他用户组相互干扰