Kubernetes 基础概念:名字空间

Kubernetes 可以在一个物理集群上运行多个虚拟集群,这种虚拟集群被称作名字空间(namespace)。

名字空间提供了在多用户间隔离集群资源的方式(通过资源配额)。

同一个名字空间中的资源名称必须唯一,而不同名字空间之间则没有这个要求。名字空间是不能嵌套的,每一个 Kubernetes 的资源都只能在一个名字空间内,但并非所有资源都会在名字空间内,比如 namespace 本身,以及底层资源如 nodes、persistentVolumes 等。

要查看资源是否在名字空间内,可以用 kubectl api-resources 命令的 --namespaced=[true|false] 选项来筛选:

# 在名字空间内
kubectl api-resources --namespaced=true

# 不在名字空间内
kubectl api-resources --namespaced=false

名字空间与 DNS

当你创建一个服务(Service)时,它会创建一个对应的 DNS 记录。记录的格式是 <service-name>.<namespace-name>.svc.cluster.local。如果一个容器访问 <service-name>,那么它会解析到容器所在的名字空间内对应的服务。这对于跨多个名字空间使用相同配置的情况来说很有用。如果要跨名字空间访问,那么必须访问完整的域名(FQDN)。

使用 kubectl 操作名字空间

查看名字空间

  1. 列出集群使用的名字空间:
kubectl get namespaces
NAME          STATUS    AGE
default       Active    11d
kube-system   Active    11d
kube-public   Active    11d
  1. 查看一个名字空间的概要信息:
kubectl get namespaces <name>
  1. 或者想要看到一个名字空间的详细信息:
kubectl describe namespaces <name>
Name:           default
Labels:         <none>
Annotations:    <none>
Status:         Active

No resource quota.

Resource Limits
 Type       Resource    Min Max Default
 ----               --------    --- --- ---
 Container          cpu         -   -   100m

详细信息除了展示名称、标签、状态以外,还会展示资源配额(resource quota)和资源限制范围(resource limits)。

资源配额会跟踪一个名字空间内所有资源的使用情况的总和,允许集群运维人员定义一个名字空间可以消费的 Hard 资源使用限制。

资源限制范围定义了名字空间内的一个实体可以消费的资源范围(最小/最大值)。

名字空间有两种状态:

  • Active - 正在使用
  • Terminating - 名字空间正在被删除,不能为其他对象所用

关于这两种状态的详细解释可以参照设计文档

创建名字空间

首先需要确定名字空间的名称,比如 my-namespace。然后可以有两种方式创建名字空间:

  1. 创建一个 YAML 文件 my-namespace.yaml,内容为:
apiVersion: v1
kind: Namespace
metadata:
  name: my-namespace

然后运行:

kubectl create -f ./my-namespace.yaml
  1. 或者可以用以下命令直接创建名字空间:
kubectl create namespace my-namespace

需要注意的是名字空间的名称必须符合 DNS 的名称规范。

这里还有一个可选的字段 finalizers,可以监测名字空间的删除,然后清除资源。如果你配置了一个不存在的 finalizer,那么在创建名字空间之后,如果用户尝试删除,名字空间会卡在 Terminating 状态。

关于 finalizers 的更多信息请查看设计文档

删除名字空间

删除名字空间只需要运行以下命令:

kubectl delete namespaces my-namespace

警告:这会删除该名字空间下的所有资源。

删除是异步的,所以在一段时间内你会看到名字空间处于 Terminating 状态。

设置命令所在的名字空间

设置当前命令所在的名字空间

使用 --namespace 参数可以设置当前命令所在的名字空间:

kubectl run nginx --image=nginx --namespace=my-namespace
kubectl get pods --namespace=my-namespace

设置默认名字空间

你可以将当前上下文(context)的默认名字空间保存到 kubectl 的配置中:

kubectl config set-context --current --namespace=my-namespace
# 验证
kubectl config view | grep namespace:

这样,下次执行命令时,无需添加 --namespace 参数就已经在设置的名字空间内了。