2

一文了解字节跳动 KubeZoo 的核心理念——协议转换

 2 years ago
source link: https://juejin.cn/post/7132361348419158030
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

一文了解字节跳动 KubeZoo 的核心理念——协议转换

2022年08月16日 06:45 ·  阅读 331
一文了解字节跳动 KubeZoo 的核心理念——协议转换

本文是 KubeZoo 系列技术文章的第二篇,将重点介绍 KubeZoo 的核心理念和关键实现 —— 协议转换。

github.com/kubewharf/k…

从租户的视角来看,无论是 namespace scope 还是 cluster scope 的资源,用户都拥有完整和独立的视角,比如租户 A 拥有名字为 foo 的 namespace,租户 B 也可以拥有名字为 foo 的 namespace,而且这两个 namespace 只是名字相同,其资源和权限实际上是互相隔离的。

但是从 Kubernetes 的视角来看,其对 namespace 的资源要求在 namespace 内是命名唯一的,对于 cluster scope 的资源,其要求在全局上也是命名唯一的。

当所有的租户都共享同一个 Kubernetes 时,为了解决多个租户具备完整独立视角和 Kubernetes 要求在 namespace/scope cluster 不同层次命名的唯一性的矛盾,我们提出了协议转换的理念,以此解决命名唯一性的问题。

7a28eca5c17944f3be7559c806701be7~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

如上图所示,由于每个租户的名字/ID 是全局唯一的,因此如果在相关的资源名字上增加租户的标志,也就间接保证了在实际的 Kubernetes 控制面上保证了资源全局的唯一性;从租户的视角来看,如果我们对租户呈现其资源时,将相关的前缀剥离,即保证了租户的真实呈现视角和隔离性。

以 namespace 视角为例,比如租户 tenant2 有 default 和 prod 两个 namespace,其在上游的真实 namespace 则是加上了租户的前缀,故为 tenant2-default 和 tenant2-prod。

因此 KubeZoo 在租户和上游的 Kubernetes 集群充当了中间的转换适配层,接受租户的请求和上游 Kubernetes 的返回,并根据不同类型的资源进行不同的处理。

KubeZoo 基于“协议转换”核心理念实现控制面多租户功能,通过在资源的 name/namespace 等字段上增加租户的唯一标志,从而解决不同租户的同名资源在同一个上游物理的 K8s 冲突问题,该思想和 Linux 内存管理有如出一辙之处。

K8s 原生 API 大致可以被划分为如下 4 类:

  • Namespace scope:如 pod, pvc, statefulset, deployment etc;
  • Cluster scope:如 pv, namespace etc;
  • Custom:用户定义的资源;
  • Non-resource:如 openapi / healthz / livez / readyz 以及日志监控等 etc。

通过对上述 API 采取对应的协议转换方案,最终为绝大部分的 API 提供多租户能力。经分析检验, KubeZoo 的一致性测试通过率高达 86%。

Namespace Scope 资源

K8s 大概有 40 多种 namespace scope 的资源,比如 deployment / statefulset / pod / configmap 等。通过在每个资源的 namespace 字段关联租户信息,从而实现 namespace scope 资源的多租户能力。

134e8b070e8d4f8eb45086642a3ee600~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

对于租户不同类型的请求,KubeZoo 首先从请求的证书中解析租户信息,之后具体转换如下:

  • POST:在 request body 的 namespace 和 request url 的 namespace(如果有的话) 字段添加租户前缀,然后将请求转发至上游 K8s 完成资源创建;对于 response body,删除 namespace 中的租户前缀,最后把请求返回给租户。

  • GET

    • 查询/监听某个资源:在 request url 的 namespace 字段增加租户前缀,然后将请求转发至上游 K8s 完成资源查询;对于 response body,去除 namespace 中的租户前缀,最后把请求返回给租户。
    • 罗列/监听 ns 的资源:在 request url 的 namespace 字段增加租户前缀,调整 label selector 中涉及 namespace 相关的值,然后将请求转发至上游 K8s 完成资源查询;对于 response body,去除 namespace 中的租户前缀,最后把请求返回给租户。
    • 罗列/监听租户的资源:查询上游 K8S 所有此类资源,KubeZoo 根据 namespace 的租户前缀匹配本租户的所有此类资源;同时去除 namespace 中的租户前缀,最后把请求返回给租户。
  • PUT:在 request body 的 namespace 和 request url 的 namespace(如果有的话) 字段添加租户前缀,然后将请求转发至上游 K8s 完成资源更新;对于 response body,去除 namespace 中的租户前缀,最后将请求返回给租户。

  • DELETE

    • 删除某个资源:在 request url 的 namespace 字段增加租户前缀,然后将请求转发至上游 K8s 完成资源删除;对于 response body,去除 namespace 中的租户前缀,最后将请求返回给租户。
    • 删除某些资源:在 request url 的 namespace 字段增加租户前缀,调整 label selector 涉及 namespace 相关的值,然后罗列符合要求的资源,对于属于本租户的资源,逐个删除;对于 response body,去除 namespace 中的租户前缀,最后把请求返回给租户。

对于 POST / GET / PUT 操作的协议转换过程,所依赖的 ownerReference 资源名字也需要做相关处理,对于 Cluster Scope 的资源名字,其处理逻辑请见下节“Cluster Scope Resource”;对于 Custom Resouce 的资源名字,其处理逻辑等请见下文“Custom Resource”。

ownerReference 的命名转换是普遍适用的场景,不仅适用于本节 namespace scope resource,还包括 cluster scope resource 和 custom resource 等,后文不再累述。

Cluster Scope 资源

K8s 大概有 20 多种 cluster scope 的资源,比如 pv / namespace / storageclass 等等。通过在 name 关联租户信息,从而实现 cluster scope 资源的多租户能力。

0726d9b68a7f4fb4aadeb44b6c2ae759~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

对于租户不同类型的请求,KubeZoo 首先从请求的证书中解析租户信息,之后具体转换如下:

  • POST:在 request body 的 name 字段添加租户前缀,然后将请求转发至上游 K8s 完成资源创建;对于 response body,去除 name 中的租户前缀,最后把请求返回给租户。

  • GET

    • 查询/监听 某个资源:在 request url 的 name 字段增加租户前缀,然后将请求转发至上游 K8s 完成资源查询;对于 response body,去除 name 中的租户前缀,最后把请求返回给租户。
    • 罗列/监听 租户的资源:查询上游 K8s 所有此类资源,KubeZoo 根据 name 匹配的租户前缀匹配本租户的所有此类资源;同时去除 name 中的租户前缀,最后把请求返回给租户。
  • PUT:在 request body 的 name 和 request url 的 name(如果有的话)字段添加租户前缀,然后将请求转发至上游 K8s 完成资源更新;对于 response body,去除 name 中的租户前缀,最后将请求返回给租户。

  • DELETE

    • 删除某个资源:在 request url 的 name 字段增加租户前缀,然后将请求转发至上游 K8s 完成资源删除;对于 response body,去除 name 中的租户前缀,最后将请求返回给租户。
    • 删除某些资源:罗列符合要求的资源,对于属于本租户的资源,逐个删除;对于 response body,去除 name 中的租户前缀,最后把请求返回给租户。

对于 node 类型的资源,由于 KubeZoo 方案是倾向由弹性容器提供数据面多租户的能力,因此上游集群不会纳管实际的计算节点,故实现上采取屏蔽 node 类型的资源的做法。

Custom 资源

Custom Resource Definition(CRD)是一种特殊的 cluster scope 资源,由于其 name 由 group + plural 组成,我们选择在 group 前缀关联租户信息。除此处细节差异外,其它的逻辑则和上述 “cluster scope resource” 基本保持一致。详情如下图所示:

c4d95125a9354f56b669473709af086d~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

Custom Resource(CR)可以分为 namespace scope 和 cluster scope,我们以 namespace scope 的 CR 的请求为例,KubeZoo 从证书解析租户信息后,具体的转换逻辑如下:

  • POST:往 request url 的 group / namespace 和 request body 的 group / namespace 字段添加租户前缀,然后将请求转发至上游 K8s 完成资源创建;对于 response body,去除 group / namespace 中的租户前缀,最后将请求返回给租户。

  • GET

    • 查询/监听某个资源:向 request url 的 group / namespace 字段增加租户前缀,然后将请求转发至上游 K8s 完成资源查询;对于 response body,去除 group / namespace 中的租户前缀,最后把请求返回给租户;
    • 罗列/监听 ns 的资源:在 request url 的 group / namespace 字段增加租户前缀,调整 label selector 中和 namespace 相关的值,然后将请求转发至上游 K8s 完成资源查询;对于 response body,去除 namespace / group 中的租户前缀,最后把请求返回给租户;
    • 罗列/监听租户的资源:查询上游 K8s 所有此类 CR,KubeZoo 根据 group 匹配的租户前缀匹配本租户的所有此类资源;对于 response body,去除 namespace / group 中的租户前缀,最后把请求返回给租户。
  • PUT:往 request url 的 group / namespace 和 request body 的 group / namespace 字段添加租户前缀,然后将请求转发至上游 K8s 完成资源更新;对于 response body,去除 group / namespace 中的租户前缀 ,最后把请求返回给租户。

  • DELETE

    • 删除某个资源:向 request url 的 group / namespace 字段正确的注入租户信息,然后将请求转发至上游 K8s 完成资源删除;对于 response body,去除 group / namespace 中的租户前缀,最后将请求返回给租户;
    • 删除某些资源:在 request url 的 group / namespace 字段增加租户前缀,调整 label selector 涉及 namespace 相关的值,然后罗列符合要求的资源,对于属于本租户的资源,逐个删除;对于 response body,去除 group / namespace 中的租户前缀,最后把请求返回给租户。

对于 cluster scope 的 CR,结合上述逻辑易于推导,此处不再详述。

Cross Reference 资源

需要注意的是,同一租户的不同类型的资源 Spec 中的字段可能会存在资源引用的依赖情况,pvc 的 spec.volumeName 为对应的 pv,大体上可以将引用分为两类:

  • namespace 内引用:例如 pod 引用 pvc / configmap / serviceaccount 等,此类上下游资源为 namespace scope 资源,且同属一个 namespace,因此不需要做任何处理。
  • namespace 与 cluster 之间引用:pvc 引用 cluster scope pv,serviceaccount 引用 clusterrolebinding 等。对于此类的资源,需要准确理解其资源字段的含义,并在 KubeZoo 解析其 Body,完成资源名字的准确转换。

以 pvc 具体 case 为例,租户视角的 pvc:

0702c7ae0eb3412d8a54f8a53467862b~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

上游 K8s 视角的 pvc:

ff6890e6044149ffa6d89f2bccc67c19~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

常见涉及 namespace 和 cluster 之间交叉依赖的资源有如下 10 种:

clusterrole / clusterrolebinding / endpoint / endpointslice / pv / pvc / role / rolebinding / tokenreview / volumeattachment。

Non-resource 资源

除了上述核心资源以外,K8s 还有一部分 Non-resource API,主要包括监控、日志、Doc 等。

对于 readyz / healthz / livez / version 等类型近 60 个 GET 类型的 API,这些 API 主要用于表示 master / etcd / poststarthook 各类 controller 的健康状况、版本信息等。因此对于此类 API,KubeZoo 只需要将请求转发至下游 K8s 即可。

对于 /openapi/v2 API,KubeZoo 首先需要从上游 K8s 获取其支持的 openapi 资源,并从相关的资源过滤出租户的 CRD,然后合并原生 API 资源,最终返回给租户。

对于 /metrics API,这些 metrics 信息无法从租户粒度进行区分,且对于托管版本的 Serverless K8s 用户作用相对有限,因此暂不考虑支持详细的租户级别的 metrics。

对于 /logs API,由于其仅简单展示访问的审计信息,因此暂未支持详细的租户级别的 logs。从实现的角度可以在 KubeZoo 侧提供记录和审计能力,并将审计信息存储到 KubeZoo 的存储中。

本文详细介绍了 KubeZoo 的核心理念和详细设计,从而保证了资源隔离的视图和逻辑的准确性;由于不同类型的资源存在一些差异,因此针对 namespace scope、cluster scope、custom 和 non-resource 等类型的资源分别进行了处理,既提供了隔离能力,又保证了准确性。

关于“数据面隔离”详细设计,敬请期待系列文章。

最后,KubeZoo 已在 GitHub 开源,欢迎多多关注、体验。

github.com/kubewharf/k…

ad919909ad6a41d38a623dbf5932f7e9~tplv-k3u1fbpfcp-zoom-in-crop-mark:3024:0:0:0.awebp

扫描二维码,加入 KubeZoo 项目群聊


Recommend

  • 26

    创造自己的现金流。

  • 22
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    字节跳动在 Spark SQL 上的核心优化实践

    以下是 字节跳动数据仓库架构负责人郭俊 的分享主题沉淀,《字节跳动在Spark SQL上的核心优化实践》。 团队介绍 数据仓库架构团队负责数据仓库领域架构设计,支持字...

  • 8

    MBox 是字节跳动抖音基础技术、Client Infra-DevOps根据移动端研发出现的现状与问题,结合移动端研发工具相关实践经验,自研的一款面向移动端开发者的研发工具链产品。目前,MBox CLI (Command Line Tool) 已经开源,后续将增加更多平台支持,欢...

  • 14

    一直以来,字节跳动的同学们都在按“字节范”的工作风格,为实现“激发创造,丰富生活”的使命不断努力。 做为字节跳动的文化的核心,「字节范儿」是字节跳动人共享的工作风格和工作方法。 深入了解「字节范儿」,不仅可以让沟通...

  • 5

    一文了解字节跳动微服务中间件 CloudWeGo 2021 年 10 月 15 日

  • 7

    一文了解字节跳动的元宇宙布局 01区块链 原创 2021-12-10 02:00 热度 78973 分享 微信扫一扫:分享 ...

  • 5

    作者 | 开发套件团队基于字节跳动分布式治理的理念,数据平台数据治理团队自研了 SLA 保障平台,目前已在字节内部得到广泛使用,并支持了绝大部分数据团队的 SLA 治理需求,每天保障的 SLA 链路数量过千,解决了数据 SLA 难对齐、难保障、难管理的问题。

  • 6

    基于字节跳动分布式治理的理念,数据平台数据治理团队自研了 SLA 保障平台,目前已在字节内部得到广泛使用,并支持了绝大部分数据团队的 SLA 治理需求,每天保障的 SLA 链路数量过千,解决了数据 SLA 难对齐、难保障、难管理的问题。 一、背景介绍 S...

  • 4

    埋点数据作为推荐、搜索、产品优化的基石,其数据质量的重要性不言而喻,而要保障埋点数据的质量,埋点验证则首当其冲。工欲善其事必先利其器,要做好埋点验证会面临很多技术挑战:易用性、准确性、实时性、稳定性、扩展性,如何攻克这些挑战呢,其实还是技术,这也...

  • 7

    埋点数据作为推荐、搜索、产品优化的基石,其数据质量的重要性不言而喻,而要保障埋点数据的质量,埋点验证则首当其冲。工欲善其事必先利其器,要做好埋点验证会面临很多技术挑战:易用性、准确性、实时性、稳定性、扩展性,如何攻克这些挑战呢,其实还是技术,这也...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK