本文发表已超过一年。较早的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已失效。
Kubernetes Namespaces:用例和洞察
“谁在一垒,什么在二垒,我不知道在三垒”
谁在一垒? 作者:Abbott and Costello
引言
Kubernetes 是一个包含多个概念的系统。其中许多概念在 RESTful API 中表现为“对象”(通常称为“资源”或“Kind”)。其中一个概念是 Namespace。在 Kubernetes 中,Namespace 是一种将单个 Kubernetes 集群划分为多个虚拟集群的方式。在本文中,我们将重点介绍我们的客户如何使用 Namespace 的示例。
但首先,一个比喻:Namespace 就像人类的姓氏。姓氏,例如 Wong,代表一个家庭单元。在 Wong 家族内部,其成员之一,例如 Sam Wong,很容易被家人简称为“Sam”。在家族外部,为了避免“哪个 Sam?”的问题,Sam 通常会被称为“Sam Wong”,甚至可能是“来自旧金山的 Sam Wong”。
Namespace 是一种逻辑分区能力,允许多个用户、用户团队或具有多个应用的单个用户使用同一个 Kubernetes 集群,而无需担心不必要的交互。每个用户、用户团队或应用都可以存在于其 Namespace 中,与其他集群用户隔离,就像它是集群的唯一用户一样运行。(此外,资源配额(Resource Quotas) 提供了将 Kubernetes 集群的部分资源分配给 Namespace 的能力。)
对于 Kubernetes 的大多数非简单用法,使用 Namespace 都将带来益处。在本文中,我们将介绍我们在 Google Cloud Platform 上看到 Kubernetes 用户使用 Namespace 的最常见方式,但我们的列表并非详尽无遗,我们也乐于向你学习其他示例。
涵盖的用例
- 企业中关于 Namespace 的角色和职责
- 划分环境:开发 vs 测试 vs 生产
- 非多租户场景下的客户分区
- 何时不使用 Namespace
用例 #1:企业中的角色和职责
典型的企业包含多个业务/技术实体,它们相互独立运作,并由企业自身管理着某种形式的总体控制层。在这种环境中运行 Kubernetes 集群时,当定义了与 Kubernetes 相关的角色和职责后,可以更有效地进行管理。
下面是一些推荐的角色及其职责,可以使在大型组织中管理 Kubernetes 集群更加容易。
- 设计师/架构师角色:此角色将定义总体 Namespace 策略,考虑产品/位置/团队/成本中心等因素,并确定如何最好地将这些映射到 Kubernetes Namespace。投资于此角色可以防止 Namespace 泛滥和“雪花” Namespace。
- 管理员角色:此角色拥有所有 Kubernetes 集群的管理员权限。管理员可以创建/删除集群并添加/删除节点来扩展集群。此角色负责修补、保护和维护集群。此外,还要在组织中不同实体之间实施配额。Kubernetes 管理员负责实施设计师/架构师定义的 Namespace 策略。
这两个角色以及实际使用集群的开发者,还将从企业安全和网络团队获得支持和反馈,解决诸如安全隔离需求以及 Namespace 如何适应此模型的问题,或者在网络子网和负载均衡器设置方面获得帮助。
反模式
- 没有集中控制的孤立 Kubernetes 使用“孤岛”:如果一开始不投入精力建立围绕 Kubernetes 管理的集中控制结构,就有可能最终形成“蘑菇农场”拓扑,即组织内集群没有明确的大小/形状/结构。结果是难以管理、风险更高,并且由于资源利用不足而导致成本上升。
- 旧式 IT 控制扼杀使用和创新:一种普遍趋势是试图将现有的本地控制/流程移植到新的动态框架上。这会加重这些框架的敏捷性,并抵消快速动态部署的好处。
- 万能集群:延迟创建 Namespace 管理结构/机制的努力可能会导致一个庞大的万能集群,很难将其剥离成更小的使用组。
用例 #2:使用 Namespace 划分开发环境
软件开发团队习惯上将其开发管道划分为独立的单元。这些单元有各种形式和标签,但通常会形成独立的开发环境、测试|QA 环境、可能的预生产环境和最终的生产环境。由此产生的布局非常适合 Kubernetes Namespace。管道中的每个环境或阶段都成为一个唯一的 Namespace。
上述方法效果很好,因为每个 namespace 都可以模板化并镜像到开发周期的下一个后续环境,例如 dev->qa->prod。每个 namespace 逻辑上独立的特性允许开发团队在隔离的“开发”namespace 中工作。DevOps(在 Google 最接近的角色称为站点可靠性工程师(Site Reliability Engineering),简称“SRE”) 将负责通过管道迁移代码,并确保将适当的团队分配给每个环境。最终,DevOps 全权负责最终的生产环境,在那里解决方案被交付给最终用户。
将 Namespace 应用于开发周期的一个主要好处是,可以保持软件组件(例如微服务/端点)的命名,而不会在不同环境之间发生冲突。这是由于 Kubernetes Namespace 的隔离性,例如,dev 中的 serviceX 在所有其他 Namespace 中都会被如此引用;但是,如果需要,可以在 mycluster.com 的 development Namespace 中使用其完全限定名 serviceX.development.mycluster.com 来唯一引用它。
反模式
- 滥用 Namespace 的好处,导致开发管道中出现不必要的环境。因此,如果你不做预生产部署,就不要创建一个“staging” Namespace。
- Namespace 过度拥挤,例如将所有开发项目放在一个巨大的“development”Namespace 中。由于 Namespace 的作用是分区,因此也请用它们来按项目分区。由于 Namespace 是扁平的,你可能需要类似 projectA-dev, projectA-prod 这样的 Namespace 作为 projectA 的 Namespace。
用例 #3:客户分区
例如,如果你是一家咨询公司,希望为你的每个客户管理独立的应用,那么 Namespace 提供的分区功能非常适合。你可以为每个客户、客户项目或客户业务单元创建一个独立的 Namespace,以保持它们的独立性,同时无需担心在不同项目之间重复使用相同的资源名称。
这里需要考虑一个重要事项:Kubernetes 目前不提供跨 Namespace 强制执行访问控制的机制,因此我们建议你不要将使用这种方法开发的应用对外暴露。
反模式
- 多租户应用不需要 Kubernetes Namespace 的额外复杂性,因为应用本身已经强制执行了这种分区。
- 客户与 Namespace 的映射不一致。例如,你在一家全球性公司赢得了业务,你最初可能考虑为整个企业设置一个 Namespace,却没有考虑到该客户可能更喜欢进一步分区,例如 BigCorp 会计部和 BigCorp 工程部。在这种情况下,客户的每个部门都可能需要一个 Namespace。
何时不使用 Namespace
在某些情况下,Kubernetes Namespaces 将无法提供你所需的隔离。这可能是由于地理位置、计费或安全因素。尽管 Namespace 提供了逻辑分区的好处,但目前没有能力强制执行分区。Kubernetes 集群中的任何用户或资源都可以访问集群中的任何其他资源,无论其 Namespace 如何。因此,如果你需要保护或隔离资源,最终的 Namespace 是一个独立的 Kubernetes 集群,你可以在其上应用常规的安全|ACL 控制。
另一个你可能考虑不使用 Namespace 的情况是当你希望反映地理上分布式的部署时。如果你希望部署靠近美国、欧盟和亚洲的客户,建议在每个区域本地部署一个 Kubernetes 集群。
当需要精细计费,例如按成本中心或按客户进行费用分摊时,建议将计费工作留给你的基础设施提供商。例如,在 Google Cloud Platform (GCP) 中,你可以使用单独的 GCP 项目(Project)或计费账户(Billing Account),并将 Kubernetes 集群部署到特定客户的项目中。
在需要客户之间完全不透明(出于保密或合规性原因)的情况下,为每个客户/工作负载分配一个 Kubernetes 集群将提供所需的隔离级别。同样,你应该将资源分区的工作委托给你的提供商。
目前正在开展工作以提供 (a) Kubernetes Namespace 上的 ACL,从而能够强制执行安全性;(b) 提供 Kubernetes 集群联邦(Cluster Federation)。这两种机制都将解决这些反模式中需要独立 Kubernetes 集群的原因。
Kubernetes Namespace 的一个容易理解的反模式是版本控制。你不应该使用 Namespace 作为区分 Kubernetes 资源版本的方式。对版本控制的支持存在于容器和容器注册表以及 Kubernetes Deployment 资源中。多个版本应该通过利用 Kubernetes 容器模型共存,该模型还提供了通过 Deployment 在版本之间进行自动迁移。此外,以版本为范围的 Namespace 将导致集群内 Namespace 大量激增,从而使其难以管理。
忠告
你可能希望这样做,但不能创建 Namespace 层次结构。Namespace 不能嵌套。例如,你不能创建 my-team.my-org 作为 Namespace,但或许可以创建 team-org。
Namespace 易于创建和使用,但也容易不经意地将代码部署到错误的 Namespace 中。良好的 DevOps 实践建议在可能的情况下文档化和自动化流程,这将有所帮助。避免使用错误 Namespace 的另一种方法是设置 kubectl context。
如前所述,Kubernetes 目前不提供跨 Namespace 强制执行安全性的机制。你应该仅在可信域(例如内部使用)内使用 Namespace,当你需要能够保证 Kubernetes 集群的用户或其资源无法访问任何其他 Namespace 的资源时,则不应使用 Namespace。这种增强的安全功能正在 Kubernetes 身份验证和授权特别兴趣小组(Special Interest Group for Authentication and Authorization)中讨论,欢迎在 SIG-Auth 参与。
- 下载 Kubernetes
- 在 GitHub 上参与 Kubernetes 项目
- 在 Stack Overflow 上提问(或回答问题)
- 在 Slack 上与社区联系
- 在 Twitter 上关注我们 @Kubernetesio 获取最新动态