在单个 Kubernetes 集群上安全托管大量用户一直是一个棘手问题,其中最大的麻烦就是 不同的组织以不同的方式使用 Kubernetes,很难找到一种租户模式可以适配所有组织。相 反,Kubernetes 只提供了创建不同租户模式的基础构件,例如 RBAC 和NetworkPolicies,这些基础构件实现得越好,安全构建多租户集群就越容易。
1
多租户命名空间
其中最重要的基础构件是命名空间(namespace),它构成了几乎所有 Kubernetes 控制平 面安全性和共享策略的基础。例如,RBAC,NetworkPolicies 和 ResourceQuotas 默认情 况下都使用租户命名空间,并且像 Secrets,ServiceAccounts 和 Ingress 之类的对象可在 任何一个命名空间内自由使用,但与其他命名空间完全隔离。
命名空间具有两个关键属性,使其成为执行策略的理想选择。
首先,命名空间可以用来代表所有权。大多数 Kubernetes 对象必须位于命名空间中,因此, 如果使用名称空间表示所有权,那么命名空间中的所有对象都隶属于同一个所有者。
其次,命名空间的创建和使用需要授权。只有特权高的管理员才能创建命名空间,其他用户 需要具有使用这些命名空间的明确权限(即创建,查看或修改对象。)这样,在没有特权的 用户可以创建“常规”对象(例如 Pod 和服务)之前,可以使用适当的策略防止非特权用 户创建某些资源对象。
2
命名空间的限制
但是,实际上,名称空间不够灵活,无法满足一些常见的用例。例如,假设一个团队拥有多 个具有不同机密和配额的微服务。理想情况下,他们应该将这些服务放在不同的命名空间中, 以将它们彼此隔离,但这带来了两个问题。
首先,这些命名空间没有相同的所有权概念,即使它们都属于同一团队。这意味着,如果团 队控制多个命名空间,不仅 Kubernetes 不会拥有其共同所有者的任何记录,而且针对命名 空间范围内的策略也无法跨多个命名空间生效。
其次,团队通常能够最好地自主运作,但是由于命名空间的创建需要具有很高的特权,因此 开发团队的任何成员都不太可能被允许创建命名空间。这意味着,每当团队需要新的命名空 间时,他们都必须向集群管理员提出要求。尽管这对于小型组织来说可能是可以接受的,但 是随着组织的发展,它会产生不必要的麻烦。
这种层级命名空间的所有权可以在命名空间的基础上实现额外的两种功能:
这为我们的开发团队解决了两个问题。集群管理员可以为团队创建一个“根”命名空间以 及所有必要的策略,然后将创建子命名空间的权限委派给该团队的成员。然后,这些团队 成员可以创建供自己使用的子命名空间,而不会违反集群管理员策略。
3
层级命名空间控制器
层级命名空间由 Kubernetes 的层级命名空间控制器(Hierarchical Namespace Controller,HNC)。HNC 包含两个组件:
让我们来看看 HNC 的作用。想象一下我没有命名空间创建特权,但是我可以查看命名空 间 team-a 并在其中创建子命名空间。使用 kubectl 插件执行以下命令:
$ kubectl hns create svc1-team-a -n team-a
这将创建一个名为 svc1-team-a 的子命名空间。请注意,由于子命名空间只是常规的Kubernetes 命名空间,因此所有子命名空间名称仍必须是唯一的。
我可以通过请求树视图来查看这些名称空间的结构:
$ kubectl hns tree team-a
# Output:
team-a
└── svc1-team-a
而且,如果父名称空间中有任何策略,这些策略现在也将出现在子策略中。例如,假设team-a 有一个称为 sres 的 RBAC RoleBinding。此角色绑定还将出现在子命名空间中:
$ kubectl describe rolebinding sres -n svc1-team-a
# Output:
Name: sres
Labels: hnc.x-k8s.io/inheritedFrom=team-a # inserted by HNC
Annotations: <none>
Role:
Kind: ClusterRole
Name: admin
Subjects: ...
最后,HNC 将标签添加到这些命名空间,其中包含有关层次结构的有用信息,您可以使用 这些信息来应用其他策略。例如,您可以创建以下 NetworkPolicy:
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: allow-team-a
namespace: team-a
spec:
ingress:
- from:
- namespaceSelector:
matchExpressions:
- key: 'team-a.tree.hnc.x-k8s.io/depth' # Label created by HNC
operator: Exists
该策略将被传播到 team-a 的所有后代,还将允许所有这些命名空间之间的入口流量。“tree”标签只能由 HNC 应用,并保证可以反映最新的层次结构。
关于 HNC 的更多信息请参考用户指南。
4
下一步计划
如果您认为分层命名空间适用于贵组织,则可以在 GitHub 上使用 HNC v0.5.1。我们很 想知道您的想法,正在使用它来解决哪些问题,最希望看到哪些功能。与所有早 期软件一样,应该在生产环境中使用 HNC 时要谨慎,但是获得的反馈越多,我们越早就 能使用 HNC 1.0。
我们还向其他贡献者开放,无论是修复或报告错误,还是帮助原型化新功能,例如异常,改 进监控,分层资源配额或细粒度的配置。
原文链接:
https://kubernetes.io/blog/2020/08/14/introducing-hierarchical-namespaces/