如何解决多租户集群的安全隔离问题,是企业上云的关键问题。本文主要介绍了kubernetes多租户集群的基本概念和常见应用形式,以及企业内部共享集群的业务场景接下来,基于kubernetes原生和ACK集群现有的安全管理能力,提出相关解决方案可以快速实现多租户集群。什么是多租户集群?这里先介绍一下“租户”。租户的概念并不局限于集群用户。它可以包括由一组计算、网络、存储和其他资源组成的工作负载集合。在多租户集群中,需要为一个集群(未来可能是多集群)内的不同租户提供尽可能多的安全隔离,以最大程度避免恶意租户攻击其他租户。公平分配共享集群资源。在隔离的安全程度上,我们可以将其分为软隔离(SoftMulti-tenancy)和硬隔离(HardMulti-tenancy)。其中,软隔离更面向企业内部的多租户需求。在这种形式下,默认情况下没有恶意租户。隔离的目的是保护内部团队之间的业务,防止可能的安全攻击;而硬隔离则更有针对性。其中大部分是对外提供服务的服务商。由于这种业务形态下无法保证不同租户的业务用户的安全后台,我们默认租户之间、租户与k8s系统之间存在相互攻击的可能,所以这里也需要更严格的隔离作为安全保障。下一节将详细介绍多租户的不同应用场景。多租户应用场景下面介绍两种典型的企业多租户应用场景和不同的隔离需求:1)企业内部共享集群的多租户这种场景下,集群的所有用户都来自企业内部,这也是很多k8s集群客户的现状由于服务使用者身份的可控性,这种业务形式的安全风险相对可控。毕竟老板可以恶意直接裁掉员工:)根据企业内部人员结构的复杂程度,我们可以在一定程度上通过命名空间逻辑隔离不同部门或团队的资源,同时时间定义业务人员具有以下角色:集群管理员:具有集群管理能力(伸缩、添加节点等)负责租户管理员创建和分配命名空间负责各种策略(RAM/RBAC/networkpolicy/quota...)租户管理员至少拥有集群的RAM只读权限管理租户内相关人员的RBAC配置租户内用户之间的对应关系命名空间中权限范围内的k8s资源的使用基于建立基于用户角色的访问控制,我们还需要保证命名空间之间的网络隔离,只能在内部交叉访问不同命名空间之间可以允许白名单的范围。租户申请请求。另外,对于业务安全要求较高的应用场景,我们需要对应用容器的内核能力进行限制,可以配合seccomp/AppArmor/SELinux等策略工具来达到限制运行时能力的目的的容器。当然,现有的Kubernetes命名空间的单层逻辑隔离还不足以满足一些业务模型复杂的大型企业应用的隔离需求。我们可以关注VirtualCluster,它抽象出更高层次的租户资源模型,实现更精细的多重Rent管理,弥补原生命名空间能力的不足。2)SaaS&KaaS服务模型下的多租户在SaaS多租户场景下,kubernetes集群中的租户对应SaaS平台中的各个服务应用实例和SaaS控制平面本身。在这种场景下,平台的每个服务应用实例都可以划分到不同的命名空间中。服务的最终用户无法与Kubernetes控制平面组件进行交互。这些最终用户可以看到和使用的是SaaS控制台本身。他们通过上层自定义的SaaS控制平面使用服务或部署服务(如下图左图所示)。例如,一个博客平台被部署在一个多租户集群上运行。在这个场景中,租户是每个客户的博客实例和平台自己的控制平面。平台的控制平面和每个托管博客将在不同的命名空间中运行。客户会通过平台界面创建和删除博客,更新博客软件版本,但无法理解集群是如何工作的。KaaS多租户场景在云服务商中很常见。该场景下,业务平台的服务通过Kubernetes控制面直接暴露给不同租户下的用户。最终用户可以使用k8s原生API或基于CRD/控制器的服务提供者。界面。对于最基本的隔离需求,这里的不同租户还需要通过命名空间在逻辑上隔离访问,同时保证不同租户之间网络和资源配额的隔离。不同于企业内部的共享集群,这里的终端用户都是来自非信任域,其中难免有恶意租户在服务平台上执行恶意代码。因此,对于SaaS/KaaS服务模式下的多租户集群,我们需要更高标准的安全隔离,而kubernetes现有的原生能力不足以满足安全需求。因此,我们需要在容器运行时进行安全容器等内核级别的隔离,以加强该业务形态下租户的安全性。实现多租户架构在规划和实现多租户集群时,我们可以先利用Kubernetes自带的资源隔离层,包括集群本身、namespaces、nodes、pod、container都是不同层次的资源隔离模型。当不同租户的应用工作负载可以共享同一个资源模型时,它们之间就会存在安全风险。为此,我们在实现多租户时需要控制每个租户可以访问的资源域,在资源调度层面,保证处理敏感信息的容器运行在相对独立的资源节点上;从一个角度来看,当来自不同租户的负载共享同一个资源域时,可以通过运行时安全和资源调度控制策略来降低跨租户攻击的风险。虽然Kubernetes现有的安全和调度能力还不足以完全实现多租户隔离,但是在企业内部共享集群等应用场景中,租户之间的资源域隔离是通过命名空间来完成的,而RBAC、PodSecurityPolicy、NetworkPolicy等策略模型控制了租户对资源访问范围和能力的限制,结合现有的资源调度能力已经可以提供相当的安全隔离能力。对于SaaS、KaaS等服务平台形式,我们可以利用容器服务8月份推出的安全容器,实现容器内核级隔离,可以最大限度减少恶意租户通过规避手段进行跨租户攻击。本节重点介绍基于Kubernetes原生安全功能的多租户实践。访问控制AuthN&AuthZ&AdmissionACK集群授权分为两步:RAM授权和RBAC授权。RAM授权用于集群管理接口的访问控制,包括对集群的CRUD权限(如集群可见性、伸缩、添加Node等操作),RBAC授权用于集群内kubernetes资源模型的访问控制,可以实现命名空间内指定资源的粒度授权。ACK授权管理为租户内的用户提供不同级别的预设角色模板,支持绑定多个自定义集群角色,支持批量用户授权。关于ACK上集群相关访问控制授权的更多信息,请参考相关帮助文档。NetworkPolicyNetworkPolicy可以控制不同租户业务Pod之间的网络流量,也可以通过白名单实现跨租户业务访问限制。您可以在使用Terway网络插件的容器服务集群上配置NetworkPolicy。下面是一些策略配置示例。PodSecurityPolicyPSP是k8s原生的集群维度资源模型,可以在创建pod请求的准入阶段验证其行为是否满足对应PSP策略的要求,比如检查pod是否使用host(网络,文件系统,指定端口、PID命名空间)等,同时可以限制租户内用户开启特权容器,限制挂载磁盘类型,强制只读挂载等能力;不仅如此,PSP还可以根据绑定的policy为pod添加相应的SecurityContext,包括容器运行时的uid、gid以及添加或删除的内核能力等各种设置。关于如何启用PSP准入以及相关策略和权限绑定的使用,可以参考这里OPAOPA(OpenPolicyAgent)是一个强大的策略引擎,支持解耦的策略决策服务,社区已经比较成熟的一个集成解决方案与库伯内特斯。当现有的RBAC命名空间粒度隔离不能满足企业应用复杂的安全需求时,OPA可以在对象模型层面提供细粒度的访问策略控制。同时OPA支持七层NetworkPolicy策略定义和基于labels/annotation的跨命名空间访问控制,可以作为k8s原生NetworkPolicy的有效增强。ResourceSchedulingRelatedResourceQuotas&LimitRange在多租户场景下,不同团队或部门共享集群资源,必然会出现资源竞争。因此,我们需要限制每个租户的资源使用配额。其中,ResourceQuota用于限制租户对应的namespace中所有pod占用的资源请求总量和limit,LimitRange用于设置租户对应的namespace中部署的pod的默认资源请求和limit值租户。此外,我们还可以限制租户的存储资源配额和对象数量配额。有关资源配额的详细指导,请参阅PodPriority/Preemption。从1.14版本开始,pod的优先级和抢占从beta变成了稳定的特性,其中podpriority标识了pending状态下在调度队列中等待的pod的优先级;而当由于节点资源不足或其他原因导致高优先级的pod无法被调度时,调度器会尝试驱逐低优先级的pod,以保证高优先级的pod能够被调度部署。在多租户场景下,可以通过优先级和抢占设置来保证租户内重要业务应用的可用性;同时,podpriority可以和ResourceQuota结合使用,限制租户在指定优先级下的配额数量。专用节点注意:恶意租户可以规避节点污点和容忍机制强制执行的策略。以下说明仅适用于企业内具有受信任租户的集群,或租户无法直接访问Kubernetes控制平面的集群。通过在集群中的某些节点上添加污点,这些节点可以用来指定少数租户独占使用。例如在多租户场景下,可以将集群中的GPU节点以污点的形式预留给需要在业务应用中使用GPU的服务团队使用。集群管理员可以给节点添加污点,标签如effect:"NoSchedule",只有配置了相应容忍度设置的pod才能被调度到该节点上。当然,恶意租户也可以通过在自己的pod上添加相同的容忍配置来访问节点,因此仅使用节点污点和容忍机制并不能保证目标节点在不可信多租户集群上的独占性。请参阅此处了解如何使用节点污点机制来控制调度。REST敏感信息保护机密加密在多租户集群中,不同的租户共享同一组etcd存储。在终端用户可以访问Kubernetes控制平面的场景下,我们需要对数据进行保密,避免访问控制策略配置不当。敏感信息泄露。这个可以参考k8s原生的secret加密能力,参考这里。ACK还提供了基于阿里云KMS服务的机密加密开源解决方案,可以在这里找到。总结在实现多租户架构时,首先需要确定相应的应用场景,包括判断租户内用户和应用负载的可信度以及相应的安全隔离度。在此基础上,以下几点是安全隔离的基本要求:开启Kubernetes集群默认安全配置,开启RBAC认证,禁止匿名用户访问,开启密文加密,加强敏感信息保护。基于CISkubernetesbenchmarks进行相应的安全配置并开启NodeRestriction、AlwaysPullImages、PodSecurityPolicy等相关admissioncontroller通过PSP限制pod部署的特权模式,同时控制其运行时SecurityContext配置NetworkPolicyDocker运行时开启Seccomp/AppArmor/SELinux配置尽可能实现监控、日志等服务的多租户隔离。对于诸如SaaS,KaaS等服务模式下,或者我们无法保证租户中用户的可信度时,我们需要采用一些更强的隔离方式,例如:使用OPA等动态策略引擎进行细粒度的访问控制在网络或对象层面安全容器在容器运行时在内核层面实现安全隔离完整的监控,日志、存储等服务的多租户隔离解决方案
