Skip to content

Instantly share code, notes, and snippets.

@caohe
Last active November 2, 2022 06:54
Show Gist options
  • Save caohe/b50d28f83efbdd17aa94d8070811b83b to your computer and use it in GitHub Desktop.
Save caohe/b50d28f83efbdd17aa94d8070811b83b to your computer and use it in GitHub Desktop.
TiDB Hackathon 2022 RFC
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

RFC: 轻量、安全的 TiDB Cloud 多租户方案

团队名称:摸鱼

成员:曹贺

代码仓库:https://github.com/orgs/tidb-hackathon-2022/repositories

项目介绍

基于 K8s 控制面网关 KubeZoo, Virtual Kubelet 和弹性容器服务 AWS Fargate,构建一个轻量、完整的多租户 K8s 底座,从而对 TiDB Cloud 当前的多租户与集群管理机制进行优化和下沉。

该方案可以带来下列收益:

  • 降低运维管理成本
  • 提升资源利用率
  • 提升租户 K8s 集群创建速度
  • 保证对不同租户的 TiDB 负载之间的强隔离,包括安全上和性能上的隔离

背景&动机

TiDB Cloud 当前的多租户模型为 Cluster as a Service, 通过不同的集群来隔离租户。在公有云的海量小集群场景下,存在下列潜在的问题:

  • 运维管理成本高
    • TiDB Cloud 虽然已经由自建集群的方式,改为使用公有云托管的 K8s 服务。但是当集群数量非常多时,多集群的管理仍是一个较复杂的问题。 比如,每个租户有自己的 K8s 控制面,分别属于不同的 VPC, 要将 TiDB Cloud 的管控组件与其打通网络,费用和管理成本都较高。
  • 资源利用率低
    • 每个租户的 K8s 集群是独立、割裂的资源池,资源的弹性较差,且无法通过不同租户的 TiDB 负载混部来提升资源利用率。
    • 每个租户的 K8s 集群控制面组件都占据了一定的资源,如高可用的 kube-apiserver, kube-scheduler, kube-controller-manager, etcd 等
  • 集群创建速度慢
    • 每当有新的租户时,都需要创建一个 K8s 集群,通常在公有云上一个 K8s 集群的创建需要几到十几分钟。

因此,我们考虑优化 TiDB Cloud 的多租户方案,通过将租户间的隔离能力由当前的集群管理层,下沉到 K8s 层,使多个租户可以共享一个 K8s 集群

从而在降低运维管理成本、提升资源利用率、提升集群创建速度的同时,保证对不同租户的 TiDB 负载之间的强隔离。`

项目设计

整体设计

architecture.svg

  • 基于 KubeZoo 实现控制面的多租户,租户或 TiDB Operator 访问 K8s 集群均需通过 KubeZoo
  • 通过 Virtual Kubelet 将租户的负载 (TiDB Operator, TiDB, TiKV 等) 以 Fargate Pod 的方式运行
  • 基于 Fargate 服务实现租户间数据面的隔离
    • 为不同租户的 Pod 分配不同的 VPC
    • 将不同租户的云盘创建在对应租户的 AWS 账号下,并挂载到对应租户的 TiKV/TiFlash 容器内

详细设计

控制面多租户

kubezoo.png

K8s 控制面的多租户基于 KubeZoo 项目实现。KubeZoo 是字节跳动开源的轻量级多租户网关,具有以下特性:

  • 基于 ”协议转换“ 的理念,通过在资源的 Name 或 Namespace 等字段上增加租户的唯一标志,使得每个租户拥有独立且完整的 K8s 集群视图。
  • 通过 kube-apiserver 网关的方式扩展功能,对 K8s 无侵入
  • 多个租户共享 K8s 集群和控制面,具有轻量化的特点。
  • 通过网关限流,实现租户对 kube-apiserver 请求的公平性,并支持租户 Quota 的能力。

当创建一个 TiDB Cloud 的新租户时,只需要创建一个 KubeZoo 的 Tenant 对象,实现秒级拉起一个租户 K8s 集群。

apiVersion: tenant.kubezoo.io/v1alpha1
kind: Tenant
metadata:
  name: "111111"
spec:
  id: 111111

在租户的虚拟 K8s 集群中,可以为其单独部署一套 TiDB Operator, 不同租户的 Operator 相互隔离:租户间 CRD 隔离、资源对象隔离、Watch 事件推送隔离。

数据面多租户

为了实现数据面的租户间隔离,我们使用 Virtual Kubelet + 公有云弹性容器服务 (如 AWS Fargate, 阿里云 ECI, 火山引擎 VCI) 的方式运行 TiDB/TiKV/TiFlash 等工作负载,并与 KubeZoo 的租户机制打通。

image 以 AWS 为例,通过 Virtual Kubelet 可以在 EKS 集群中注册一个虚拟节点,向下对接 Fargate 服务的 API, 实现原生 kubelet 的各项能力。

在具体实现上,我们修改 Virtual Kubelet, 使其在创建 Pod 时,从 Pod 所在 Namespace 的前缀判定其属于哪个租户,并将 Fargate Pod 创建到该租户的 AWS 账号下。

从而实现在一个 EKS 集群中,将不同租户的 TiDB/TiKV/TiFlash Pod 创建到租户各自的 AWS 账号下

计算隔离

公有云的弹性容器服务通常使用安全容器 (如 Kata, Firecracker, gVisor 等),实现容器间内核的隔离。

kata.png

以 Kata 为例,相比 runc 容器共享宿主机内核,Kata 容器基于轻量化的虚拟机技术,使得每个容器拥有自己的内核,避免容器进程发生逃逸或者夺取整个宿主机的控制权。

因此,我们通过 Virtual Kubelet 对接公有云上的弹性容器服务,来运行 TiDB/TiKV/TiFlash 等 Pod, 天然支持了租户负载之间在计算上的隔离。

网络多租户

弹性容器服务 (如 Fargate/ECI/VCI) 的 Pod 间通信使用 VPC 网络,而非容器网络。

因此我们可以修改 Virtual Kubelet, 使其在创建 Pod 时,从 Pod 所在 Namespace 的前缀判定其属于哪个租户,将 Fargate Pod 创建到该租户的 VPC 下。

从而实现为不同租户的 TiDB/TiKV/TiFlash/PD 等 Pod 分配不同的 VPC,实现租户内的网络连通,租户间的网络隔离。

存储多租户

在存储多租户的实现上,我们将扩展 EBS CSI:

  • 借助公有云的 AssumeRole 跨服务/账号授权机制,使其支持多账号;
  • 并与 KubeZoo 的租户机制打通。

从而实现在一个 EKS 集群中,将不同租户的块存储 PV:

  • 分别创建至不同租户的 AWS 账号下;
  • 并挂载到对应租户的 TiKV/TiFlash Pod 中。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment