Kubernetes(k8s)手册 Kubernetes 名字空间

2024-02-25 开发教程 Kubernetes(k8s)手册 匿名 1

名字空间

在 Kubernetes 中,“名字空间(Namespace)”提供一种机制,将同一集群中的资源划分为相互隔离的组。 同一名字空间内的资源名称要唯一,但跨名字空间时没有这个要求。 名字空间作用域仅针对带有名字空间的对象,例如 Deployment、Service 等, 这种作用域对集群访问的对象不适用,例如 StorageClass、Node、PersistentVolume 等。

何时使用多个名字空间

名字空间适用于存在很多跨多个团队或项目的用户的场景。对于只有几到几十个用户的集群,根本不需要创建或考虑名字空间。当需要名称空间提供的功能时,请开始使用它们。

名字空间为名称提供了一个范围。资源的名称需要在名字空间内是唯一的,但不能跨名字空间。 名字空间不能相互嵌套,每个 Kubernetes 资源只能在一个名字空间中。

名字空间是在多个用户之间划分集群资源的一种方法(通过资源配额)。

不必使用多个名字空间来分隔仅仅轻微不同的资源,例如同一软件的不同版本: 应该使用标签 来区分同一名字空间中的不同资源。

使用名字空间

创建名字空间

避免使用前缀 ​kube-​ 创建名字空间,因为它是为 Kubernetes 系统名字空间保留的。

新建一个名为 my-namespace.yaml 的 YAML 文件,并写入下列内容:

apiVersion: v1
kind: Namespace
metadata:
name: <insert-namespace-name-here>

然后运行:

kubectl create -f ./my-namespace.yaml

2、或者,你可以使用下面的命令创建名字空间:

kubectl create namespace <insert-namespace-name-here>

请注意,名字空间的名称必须是一个合法的 DNS 标签。

可选字段 finalizers 允许观察者们在名字空间被删除时清除资源。记住如果指定了一个不存在的终结器,名字空间仍会被创建,但如果用户试图删除它,它将陷入 Terminating 状态。

更多有关 finalizers 的信息请查阅 设计文档 中名字空间部分。

删除名字空间

删除名字空间使用命令:

kubectl delete namespaces <insert-some-namespace-name>

Warning: 这会删除名字空间下的 所有内容 !

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

查看名字空间

你可以使用以下命令列出集群中现存的名字空间:

kubectl get namespace

Kubernetes 会创建四个初始名字空间:

  • default ​没有指明使用其它名字空间的对象所使用的默认名字空间
  • kube-system​ Kubernetes 系统创建对象所使用的名字空间
  • kube-public​ 这个名字空间是自动创建的,所有用户(包括未经过身份验证的用户)都可以读取它。 这个名字空间主要用于集群使用,以防某些资源在整个集群中应该是可见和可读的。 这个名字空间的公共方面只是一种约定,而不是要求。
  • kube-node-lease​ 此名字空间用于与各个节点相关的 租约(Lease)对象。 节点租期允许 kubelet 发送心跳,由此控制面能够检测到节点故障。

为请求设置名字空间

要为当前请求设置名字空间,请使用 ​--namespace​ 参数。

例如:

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

设置名字空间偏好

你可以永久保存名字空间,以用于对应上下文中所有后续 kubectl 命令。

kubectl config set-context --current --namespace=<名字空间名称>
# 验证之
kubectl config view | grep namespace:

名字空间和 DNS

当你创建一个服务 时, Kubernetes 会创建一个相应的 DNS 条目。

该条目的形式是 ​<服务名称>.<名字空间名称>.svc.cluster.local​,这意味着如果容器只使用 ​<服务名称>​,它将被解析到本地名字空间的服务。这对于跨多个名字空间(如开发、分级和生产) 使用相同的配置非常有用。如果你希望跨名字空间访问,则需要使用完全限定域名(FQDN)。

因此,所有的名字空间名称都必须是合法的 RFC 1123 DNS 标签。

Warning:
通过创建与公共顶级域名同名的名字空间,这些名字空间中的服务可以拥有与公共 DNS 记录重叠的、较短的 DNS 名称。 所有名字空间中的负载在执行 DNS 查找时,如果查找的名称没有 尾部句点, 就会被重定向到这些服务上,因此呈现出比公共 DNS 更高的优先序。
为了缓解这类问题,需要将创建名字空间的权限授予可信的用户。 如果需要,你可以额外部署第三方的安全控制机制,例如以 准入 Webhook 的形式,阻止用户创建与公共 TLD同名的名字空间。

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

大多数 kubernetes 资源(例如 Pod、Service、副本控制器等)都位于某些名字空间中。 但是名字空间资源本身并不在名字空间中。而且底层资源,例如 节点 和持久化卷不属于任何名字空间。

查看哪些 Kubernetes 资源在名字空间中,哪些不在名字空间中:

# 位于名字空间中的资源
kubectl api-resources --namespaced=true
# 不在名字空间中的资源
kubectl api-resources --namespaced=false

自动打标签

FEATURE STATE: Kubernetes 1.21 [beta]

Kubernetes 控制面会为所有名字空间设置一个不可变更的 标签 ​kubernetes.io/metadata.name​,只要 ​NamespaceDefaultLabelName​ 这一 特性门控 被启用。标签的值是名字空间的名称。