使用命名空间共享集群

此页面展示如何查看、使用和删除命名空间。此页面也展示如何使用 Kubernetes 命名空间来划分集群。

在你开始之前

查看命名空间

使用以下命令列出集群中的当前命名空间

kubectl get namespaces
NAME              STATUS   AGE
default           Active   11d
kube-node-lease   Active   11d
kube-public       Active   11d
kube-system       Active   11d

Kubernetes 启动时包含四个初始命名空间

  • default 没有指定其他命名空间的对象的默认命名空间
  • kube-node-lease 这个命名空间持有与每个节点相关的Lease(租约)对象。节点租约允许 kubelet 发送心跳,以便控制面能够检测到节点故障。
  • kube-public 这个命名空间是自动创建的,所有用户(包括未认证的用户)都可以读取它。这个命名空间主要保留用于集群使用,以防某些资源需要在整个集群范围内公开可见和可读。此命名空间的“公共”特性只是一种约定,并非强制要求。
  • kube-system 用于 Kubernetes 系统创建的对象的命名空间

你也可以使用以下命令获取特定命名空间的概要

kubectl get namespaces <name>

或者你可以使用以下命令获取详细信息

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

请注意,这些详细信息显示了资源配额(如果存在)和资源限制范围。

资源配额跟踪命名空间中资源的总体使用情况,并允许集群管理员定义命名空间可消耗的硬性资源使用限制。

限制范围定义了单个实体在命名空间中可以消耗的资源量的最小/最大约束。

参阅 Admission control: Limit Range

命名空间可能处于以下两个阶段之一

  • Active 命名空间正在使用中
  • Terminating 命名空间正在被删除,不能用于创建新对象

更多详细信息,请参阅 API 参考中的Namespace

创建新的命名空间

创建一个名为 my-namespace.yaml 的新 YAML 文件,其内容如下

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

然后运行

kubectl create -f ./my-namespace.yaml

或者,你可以使用以下命令创建命名空间

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

你的命名空间的名称必须是合法的 DNS 标签

有一个可选字段 finalizers,它允许可观察对象在命名空间被删除时清除资源。请记住,如果指定一个不存在的 finalizer,命名空间将被创建,但如果用户尝试删除它,它将卡在 Terminating 状态。

有关 finalizers 的更多信息可以在命名空间设计文档中找到。

删除命名空间

使用以下命令删除命名空间

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

此删除操作是异步的,因此在一段时间内,你将看到命名空间处于 Terminating 状态。

使用 Kubernetes 命名空间划分集群

默认情况下,Kubernetes 集群在配置时会实例化一个默认命名空间,用于存放集群使用的默认 Pod、Service 和 Deployment。

假设你有一个全新的集群,你可以通过执行以下操作来查看可用的命名空间

kubectl get namespaces
NAME      STATUS    AGE
default   Active    13m

创建新的命名空间

在本练习中,我们将创建两个额外的 Kubernetes 命名空间来存放我们的内容。

在一个组织使用共享 Kubernetes 集群进行开发和生产用例的场景中

  • 开发团队希望在集群中维护一个空间,以便他们能够查看用于构建和运行其应用的 Pod、Service 和 Deployment 列表。在这个空间中,Kubernetes 资源会经常创建和删除,并且对谁可以或不可以修改资源的限制会比较宽松,以支持敏捷开发。

  • 运维团队希望在集群中维护一个空间,以便他们能够对谁可以或不可以操作运行生产站点的 Pod、Service 和 Deployment 集合强制执行严格的程序。

该组织可以遵循的一种模式是将 Kubernetes 集群划分为两个命名空间:development(开发)和 production(生产)。让我们创建两个新的命名空间来存放我们的工作。

使用 kubectl 创建 development 命名空间

kubectl create -f https://k8s.io/examples/admin/namespace-dev.json

然后使用 kubectl 创建 production 命名空间

kubectl create -f https://k8s.io/examples/admin/namespace-prod.json

为了确保一切正常,列出我们集群中的所有命名空间。

kubectl get namespaces --show-labels
NAME          STATUS    AGE       LABELS
default       Active    32m       <none>
development   Active    29s       name=development
production    Active    23s       name=production

在每个命名空间中创建 Pod

Kubernetes 命名空间为集群中的 Pod、Service 和 Deployment 提供作用域。与一个命名空间交互的用户看不到其他命名空间中的内容。为了演示这一点,让我们在 development 命名空间中启动一个简单的 Deployment 和 Pod。

kubectl create deployment snowflake \
  --image=registry.k8s.io/serve_hostname \
  -n=development --replicas=2

我们创建了一个副本数量为 2 的 Deployment,它运行名为 snowflake 的 Pod,其中包含一个提供主机名的基本容器。

kubectl get deployment -n=development
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
snowflake    2/2     2            2           2m
kubectl get pods -l app=snowflake -n=development
NAME                         READY     STATUS    RESTARTS   AGE
snowflake-3968820950-9dgr8   1/1       Running   0          2m
snowflake-3968820950-vgc4n   1/1       Running   0          2m

这很好,开发人员可以做他们想做的事情,并且不必担心会影响 production 命名空间中的内容。

让我们切换到 production 命名空间,看看一个命名空间中的资源是如何对另一个命名空间隐藏的。production 命名空间应该是空的,以下命令应该不会返回任何内容。

kubectl get deployment -n=production
kubectl get pods -n=production

生产环境喜欢运行 cattle(牛,指代可替换的、非唯一的实例),所以让我们创建一些 cattle Pod。

kubectl create deployment cattle --image=registry.k8s.io/serve_hostname -n=production
kubectl scale deployment cattle --replicas=5 -n=production

kubectl get deployment -n=production
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
cattle       5/5     5            5           10s
kubectl get pods -l app=cattle -n=production
NAME                      READY     STATUS    RESTARTS   AGE
cattle-2263376956-41xy6   1/1       Running   0          34s
cattle-2263376956-kw466   1/1       Running   0          34s
cattle-2263376956-n4v97   1/1       Running   0          34s
cattle-2263376956-p5p3i   1/1       Running   0          34s
cattle-2263376956-sxpth   1/1       Running   0          34s

至此,应该很清楚,用户在一个命名空间中创建的资源对其他命名空间是隐藏的。

随着 Kubernetes 中策略支持的发展,我们将扩展这个场景,展示如何为每个命名空间提供不同的授权规则。

理解使用命名空间的动机

单个集群应该能够满足多个用户或用户组(在本文档中,以下称为用户社区)的需求。

Kubernetes 命名空间有助于不同的项目、团队或客户共享一个 Kubernetes 集群。

它通过提供以下功能来实现这一点

  1. 名称的作用域。
  2. 将授权和策略附加到集群子区域的机制。

使用多个命名空间是可选的。

每个用户社区都希望能够独立于其他社区工作。每个用户社区都有自己的

  1. 资源 (Pod、Service、Replication Controller 等)
  2. 策略 (谁可以在其社区中执行或不能执行操作)
  3. 约束 (该社区被允许使用多少配额等)

集群管理员可以为每个独特的用户社区创建一个命名空间。

命名空间为以下内容提供一个独特的作用域

  1. 命名资源 (避免基本的命名冲突)
  2. 向受信用户的委托管理权限
  3. 限制社区资源消耗的能力

用例包括

  1. 作为集群管理员,我希望在一个集群上支持多个用户社区。
  2. 作为集群管理员,我希望将集群部分的管理权限委托给这些社区中受信的用户。
  3. 作为集群管理员,我希望限制每个社区可以消耗的资源量,以限制对使用该集群的其他社区的影响。
  4. 作为集群用户,我希望与我所属用户社区相关的资源进行交互,并与其他用户社区在集群上的活动相互隔离。

理解命名空间和 DNS

当你创建一个Service时,它会创建一个相应的DNS 条目。此条目的形式为 <service-name>.<namespace-name>.svc.cluster.local,这意味着如果容器使用 <service-name>,它将解析到命名空间本地的 Service。这对于在多个命名空间(如开发、预发和生产)中使用相同的配置非常有用。如果你想跨命名空间访问,你需要使用完全限定域名(FQDN)。

下一步

上次修改时间:太平洋标准时间 2023 年 8 月 1 日下午 5:31:添加 kube-node-lease 命名空间 (973280594f)