专栏首页01ZOO多租户Kubernetes
原创

多租户Kubernetes

假设

  1. 租户间互不信任,对方是恶意的,会造成攻击或资源抢占
  2. 内部用户和外部用户一样有威胁 (即使是内部用户也更偏好 hard multi-tenancy model)

与运营多个单租户集群相比,运营多租户集群有几个优点:

  • 减少管理开销
  • 减少资源碎片
  • 新租户无需等待集群创建

关于什么是租户,以及为什么要多租户,可以参考这篇,和这篇

解决办法

Kubernetes Multitenancy WG Deep Dive KubeCon EU 2019 (last updated 5/22/2019) 描述了4种解决方案,并做了对比:

image
image

这篇文章将介绍其中的 B 和C 方案

使用 namespace 隔离

一种常见的设计方案时使用 namespace隔离, 让 namespace 成为多租户隔离的边界。

这种设计里面的推荐做法是:

  • Host OS 必须是安全的,应该是 reduced operating system, minimal distribution,比如 CoreOS Container Linux/Container Optimized OS/Intel Clear Linux
  • Container Runtime: 隔离性强,比如 Katacontainers
  • Network: 支持 network policy,在 namespace 之间做网络隔离
  • DNS: 每个租户都有自己的 dns 应用
  • Authorization: RBAC 解决
  • Master/System Node 上不调度
  • Encryption of etcd at rest
  • Node authorizer and admission plugin
  • Restrict access to host/node resources via PodSecurityPolicy:需要拒绝以下使用场景
    • hostPath for volumes
    • nodePort via hostPorts
    • hostIPC
    • hostPID
    • hostNetwork
    • privileged
    • allowedHostPaths -> none
  • 资源使用都需要设置 Limit/Request,即使用 Quota, 和 LimitRange
  • 环境变量问题:kubernetes 未fixkubernetes/community/pull/176, kubernetes/community/pull/1249
  • 考虑 监控日志的多租户

为了支持这种方案,社区设计了一套 CRD

这种通过 Namespace 隔离的存在问题,

namespace 是 kubernetes 的概念,并非所有资源在 kubernetes 都能通过 namespace 隔离,比如:

  • 不同的用户会共享 kube-proxy (尽管 network policy 能够给网络访问增加一些边界), api-server, etcd, scheduler, controller ...
  • 不同到用户可能会共享 node, 而对于不同到 cri 实现, 隔离能力不同。例如 PodSecurityPolicy 和 NetworkPolicy,以及更高级别隔离性的 cri 实现(比如katacontainers)正在发展以增强这种隔离能力。但是即使 cri 有等价于 vm 的隔离能力,当用户需要使用 node 的一些资源时,这种隔离性时常被打破。

虚拟 kubernetes

这张图来自 https://blog.jessfraz.com/post/hard-multi-tenancy-in-kubernetes/

image

如果我们使用嵌套都 kubernetes apiserver(以及其他控制组件),那么我们要关心都事情就变得简单了:kubernetes 相关的核心组建,以及资源视图已经做了隔离,那么我们需要做的事情就是:让不同的虚拟kubernetes 共享同一个 ring 0 kubernetes 资源池. 如果我们能做到 虚拟kubernetes 绑定到其中几个 kubelet 就可以做到按照上图所示的按节点的隔离。

然后这种做法似乎和新建多个 kubernetes 集群并无大的区别。记得吗,当我们考虑在同一个kubernetes 上追求多租户,我们首先考虑的在保证安全的前提下,是否能提高资源利用率。我们可能追求的如下图所示方案:

image

这种方案的带来的问题是 node 视图被混淆了。当然我们有几种做法,比如在 虚拟kubernetes api 层做一些修改,以过滤掉不适合 用户空间的信息,或者使用 一套有趣的方案 virtural node, 其中一种开源等实现为:virtual-kubelet, virtual-node 成为 node 的上一层封装,对于 虚拟kubernetes来讲,所有的节点可以都是 virtual-node,而 virtual-node 再通过其他方式,比如调用 ring0 kubernetes API, 完成 pod的创建,以及同步 pod 的状态信息。

image
image

在这篇提案中描述了类似设计.

更为具体等工作流程为

  • 某租户创建 pod => 虚拟kubernetes
  • sync manager( 或virtual-node ) 将 虚拟kubernetes 中的 pod 拷贝到 super master,即上文提的 ring0 kubernetes
  • Unified scheduler 进行调度
  • kubelet 创建 pod
  • sync manager ( 或virtual-node )创建出node和同步 pod 状态

这种方案的好处是:

  • kubernetes 层无需修改
  • 灵活方便,能解决多种问题比如:名字冲突,一个租户多个 namespace 等 (在就等方案中只能用 Hierarchical Namespace来解决)
  • 隔离更强: api等组件独立

这种方案需要解决的问题:

  • Kubelet and CNI-plugin:需要 tenant-aware,支持隔离
  • Kube-proxy/Kube-dns: 需要 tenant-aware to make cluster-IP type of tenant services work
  • Tools:比如 监控日志等组件需要 tenant-aware

甚至:

  • super master 不一定是一个,可以是多个,这样 tenent master 和 super master 变成一个多对多的关系,这样就降低了 super master 无法无限扩展的问题
  • virtual node 同步,创建 pod 状态,不一定需要是通过 super master 创建,可以映射到其他资源,比如 virtual-kubelet 支持的 AWS Fargate, Azure Container Instance 等等

当然 上述的两种场景在解决 网络,监控等问题时会变得更为复杂的问题。

参考

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 扩展 Kubernetes 之 FlexVolume And CSI

    kubernetes 的 volume 解决的 存储 state 的问题。State 有很多种存储方式,kubernetes 只关注其中的一部分

    王磊-AI基础
  • k8s on eks

    虚拟 kubernetes 是一种多租户 kubernetes 的运行方式,有兴趣的可以阅读这篇文章

    王磊-AI基础
  • scheduler-设计与实现

    调度器的核心目标是: 将 workload bind 到 resource【workload --bind--> resource】,结合各类信息,将这一目标做...

    王磊-AI基础
  • Spring Boot集成Mybatis-Plus多租户架构实战

    目前公司产品就是对外企业服务,入职后了解到SaaS模式和私有部署,当我第一次听到SaaS时,我不是很理解。经过查阅资料,以及在后续研发功能时,不断的加深了对多租...

    小东啊
  • 如何在Python中使用Linux epoll

    原文链接:http://scotdoyle.com/python-epoll-howto.html

    ccf19881030
  • RabbitMQ 详解 五种队列-SpiritMark_liu

      消费者1和消费者2获取到的消息内容是不同的,也就是说同一个消息只能被一个消费者获取。

    用户6918224
  • [PHP] PHP请求Socket接口测试

    使用php读取socket接口的数据,通过php传递请求方法和请求参数,得到返回结果

    陶士涵
  • RabbitMQ详解(三)------RabbitMQ的五种队列

      上一篇博客我们介绍了RabbitMQ消息通信中的一些基本概念,这篇博客我们介绍 RabbitMQ 的五种工作模式,这也是实际使用RabbitMQ需要重点关注...

    IT可乐
  • socket套接字是什么

    socket 的原意是“插座”,在计算机通信领域,socket 被翻译为“套接字”,它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定,一...

    chenchenchen
  • node模块加载层级优化

    模块加载痛点 大家也或多或少的了解node模块的加载机制,最为粗浅的表述就是依次从当前目录向上级查询node_modules目录,若发现依赖则加载。但是随着应用...

    欲休

扫码关注云+社区

领取腾讯云代金券