Kubernetes 多租安全那些事儿
技术
作者:王泽锋
译者:
2018-04-08 03:10

随着 Kubernetes 被广泛地应用,其安全与多租能力受到越来越多的关注和讨论。经过社区几个大版本的发展,Kubernetes 已经在一定程度上具备了构建多租户的能力。本次分享将介绍 Kubernetes 中使用多租户的常见形态,相关安全能力的发展现状及未来展望。

安全,实际上是一个非常大的话题。而 Kubernetes 的多租,从项目诞生到现在其实已经经过了很长时间和非常多的讨论。去年年底在北美的 KubeCon 成立了多租的 WorkingGroup,近期有了一些阶段性的成果,今天就在这里给大家做一个介绍。 

多租安全的基本要素

“多租”这个概念本身应该属于常识,其实多租在 Kubernetes 里的含义其实也差不多。

基础安全基础安全如何理解?通常来说,首先肯定要阻止匿名访问,简单说就是在系统里面区别 Root 权限和普通用户权限。同样在 Kubernetes 里面,其实首先要保证大部分用户不会做或者说没法做破坏性的事情,这是最基础的。比如说整体的 API 限流,不会因为个别用户的流量请求过大,导致你的整个 Kubernetes 挂掉,这个是非常不可接受的事情。

可见性的隔离这个其实也非常好理解,通常意义上我们理解最直观的就是读权限控制,或者说是知识受限。就是说一个用户应该只能看到属于他自己的信息,也就是他能知道的事情,看不到其他人的应用跟数据。当然更不应该看到一些集群内,包括底层的一些信息,这个就是避免数据泄露。

避免干扰避免干扰其实一方面是写的控制,那么比如你在创建应用的时候,不能创建到别人那里去或者说你创建的应用不会影响其他人。比如不能创建到别人的命名空间下去,就是做你能做的事情。
另外(一方面)是用你能用的。其实和维护其他平台时是一样的,往往要提前做容量规划,给不同的租户分配一定的容量。而每个租户的行为,应该是只在给他分配的这个范围内去使用资源。不因为个别用户,不管是被人当成了肉机,或者其他形式的恶意攻击,或是流量压力过大、内存泄露,侵占额外的资源,造成别人的业务挂掉。

Kubernetes 多租常见形态

接下来先看下 Kubernetes 中多租的一种常见的形态。

形态 1:小公司内部共享平台

首先是最简单的,Kubernetes 最容易达到的一种形态,也就是小公司内部使用 Kubernetes 实现一个资源共享的平台。它的特点在于租户定义比较简单,实际上 Kubernetes 中的 Namespace 已经基本能够达到这样的要求。

而对于小公司内部,他的使用者特点是在集群中呈现的角色划分比较少,颗粒度粗放,往往一个人可能分配到许多的权限。大部分场景来说,只需要设置管理员角色,给他分配完全的权限,剩下的人全部使用开发者权限,就足够了。这种场景下,因为用户都是来自企业内部,知根知底,行为是非常可控的。而对于数据敏感度来说,因为组织结构的扁平化,往往只需要一种比较单一的敏感度。要么是比较敏感的数据,统一加密处理;要么是不敏感的数据,直接明文处理。
对于在集群里面跑的应用,因为大部分是来自于企业内部自主开发,经过一系列的审查调试,其实业务部署的多样性比较低,应用行为也相对可靠。这种情况下(Kubernetes 多租)最主要完成的就是一个简单的资源共享,有基本的多租控制,而相对来说租户之间的隔离要求就非常低。

形态 2: 大公司内部共享平台

第二种形态就是大公司内部资源共享的平台。据我了解,其实在国内很多公司也基本上都处在这个阶段。
它的特点在于组织结构比较复杂,大公司往往有多级的部门和团队设置,那么租户定义的颗粒度也就不一样。比如某个部门可能希望在下面的几个团队之间共享一部分资源。而在另一个团队中,它的每个组之间资源都是隔离的。在这种情况下,租户的定义存在嵌套关系,但是 Kubernetes 的原生 API 中根本就没有租户的概念。所以当我们用 Namespace 去套用的时候,由于 Namespace 只是一个单层的结构,就会遇到各种问题。
在这个场景中,因为人员来自于不同的部门或者构成的多样性,它对这种细分的权限控制,或者说租户资源的限额要求得会比较多。但是它的应用都是来自于企业内部,所以它跑的业务在行为上是比较可控的。主要是在部署和避免租户间的干扰方面,需要做大量的工作。

形态 3:公有云 SaaS 平台

第三种场景可能是国外更多一点,就是基于 Kubernetes 做二次开发。它的特点往往是不直接暴露 Kubernetes API。这就带来了一个实现上的便利性。虽然 Kubernetes 本身没有多租的模型,但你可以在 Kubernetes 之上封装自己的 API。对于 Kubernetes 来说,其实这一层完全不用感知租户的概念,你只要在自己的服务层调用 Kubernetes 时,有一个或者有几个简单的核心角色,进行一些统一的操作就行了。

但是在这种场景下,集群中运行的应用来自于最终用户。比如 CI/CD 平台,或者培训场景下会用到的 OJ 平台,Go Playground (play.golang.org) 等。平台最终会运行各种各样的代码,甚至可能是一些恶意代码。这种情况,就需要不同应用的运行环境之间有非常好的隔离。

形态 4:公有云 PaaS/CaaS/KaaS 平台

第四种形态实际上现在出现得相对较少,当然也有不少企业在尝试中,特别是公有云的提供商。包括我们自己也是最近上了一个基于 Kubernetes 做的一个 Serverless container 服务。这种场景下,平台的特点是架构设计会比较扁平化。

由于 Kubernetes 本身的生态非常活跃,我们希望最终的服务可以直接暴露原生的 Kubernetes API,或者说是只在 Kubernetes API 的基础上做一些扩展,因此这个扁平化的架构需要 Kubernetes 感知租户的概念。

而对于应用来说,因为是在公有云上提供多租的 PaaS、KaaS 服务,应用时来自于最终用户,同样也可能包含恶意代码。另外就是公有云上不可避免会有人来做一些安全性的挑战,尝试攻击,再或者是应用代码问题出现大量的内存泄露或者吃带宽等等。那在这种情况下,在公有云上提供一个多租的平台,对数据面的隔离能力要求是非常高的。
多租场景的隔离性要求我们再把刚才 4 个典型的场景放在一起做一个对比,这里我分了两个维度:

  • 控制面的隔离性,主要是隔离不同租户间能够访问哪些 API,或者说看到租户都在干些什么;
  • 数据面的隔离性,比如说你的业务在实际运行起来之后,不能去占用别人的计算资源、存储资源等。

我们可以看到,小公司的内部平台其实隔离性要求是非常低的,而大型企业同样因为它的业务是可控的,所以主要偏向于控制面的隔离性。SaaS 刚好相反,因为它有自己的业务层封装和租户定义,所以它主要是在数据面,隔离性的要求最高。当然终极形态就是我们公有云的 PaaS 服务,它在控制面,还有数据面的隔离性要求都是最高的。

如何构建 K8S 多租集群

刚才说了场景,接下来讲讲构建一个 Kubernetes 的多租户集群时,最主要的几个问题:

租户定义及 API 访问控制

首先是租户的定义,你到底需要一个什么颗粒度的租户。我们最常见的,或者说业界现在讨论最多、分享最多的还是用 Namespace 来隔。因为 Kubernetes 大部分的 API 都是有 Namespace 这一层隔离的实现。还有 API 访问这一块一般都是基于 RBAC。

节点隔离和 Runtime 安全

其次就是节点,节点隔离和 Runtime 的安全,这个本质是计算资源的隔离。

网络隔离

再接下来是网络,因为 Kubernetes 原生是一个扁平的、全通的网络,所以在多租场景下网络怎么隔就是一个很大的问题。

而储存为什么没有单独拿出来呢?因为储存相对特殊一点,目前更多的问题都可以归类到租户定义里面。

租户定义及 API 访问控制

租户的定义,这是社区当前讨论中,包括业界已有的一些典型的方案中最主要的一个设计的问题。

你是否真的需要一个租户的 API?常见的做法就是套用 Namespace,比如在 OpenShift 中,每个用户都有一个不同的 project,这个 project 其实就映射为 Namespace,所以实际上可以完全不要 project 这个对象。

另外就是可以自定义这个 Tenant API,那像典型的多租方案比如 Stackube 就有自己 Tenant API ,但它实际上依然是一个 Tenant 对应一个 Namespace。那么在复杂场景下想要做租户嵌套,也就是一个租户包含多个 Namespace,目前看开源的方案还没有,但是也有厂商正在做。

隔离的颗粒度隔离的颗粒度其实跟 Namespace 是相适应的,Namespace 是 Kubernetes 中实现租户安全的一个基础边界。因为我们知道 Kubernetes API 其实可以粗略地分成两类,我们称之为不同的 scope。一类是 Root scope,比如 Node、PV,他们在全局是同一个命名空间。比如一个 PV 你命名了 PV-a,那另外一个人就不能再创建 PV-a,因为没有一层隔离,名字已被占用。另外一类就是有 Namespace 的。另外就是 RBAC,基于角色的访问控制(全拼 Role based access control),这是 2017 年已经 GA 的一个特性,非常重要。不管是自定义一个 Tenant API 还是直接套用 Namespace,只要是多租,RBAC 是一定要开的。再有就是 ResourceQuota 和 LimitRange。ResourceQuota 是用来限制每个 Namespace 能够使用多少 CPU、memory,或者磁盘空间的。如果在前期的租户定义这一问题上你选择了自定义 Tenant API,甚至要做租户嵌套,这个时候就要另外在租户层去实现 ResourceQuota 和 LimitRange,包括 RBAC 的处理,以及下面要提到的 Root scope API 的处理。

Root scope API 的处理

在直接套用 Namespace 的场景下,最简单粗暴的做法就是对普通用户直接屏蔽 Root scope API,全部保留给管理员来操作。比如 PV,其实它对应在 Namespace 下我们知道是有 PVC 的,而且实际上大部分的应用开发者,因为他们是定义 Pod,所以只需要面对 PVC 就行,PV 其实完全可以不感知。再比如 Node,我们知道在虚拟机时代,比如说你在用 OpenStack,其实是没有太多人去关心这个虚拟机跑在哪个物理节点上的。

所以在容器时代或是说在 Kubernetes 中,你也不需要关心 Pod 跑在哪个 Node 上,你只要关心的是你的 Pod 能跑,Pod 分配到多少的资源,这个就够了。所以最简单、最直观的做法就是 Root scope API 对普通用户全部屏蔽。当然,如果要用自定义的 API 实现嵌套的 Namespace,这种情况实际是你需要把 Root scope API 一定程度上开放给用户。

我们在私有云的场景就有遇到这种客户,他们的机器是提前做预算,分配给不同部门的,然后由部门再把机器接到平台里来。但是接入之后,还保留对机器完整的控制权,因为预算是从部门走的,所以机器只能为特定部门所用。这种情况就要把 Node 权限开放给用户,但是 Node 没有 Namespace,又要做隔离,这个时候我们只能做分组。分组的方案功能强大,但是在实施上这种方案很容易失控。

在 RBAC 里面,用社区现有能力,你可以直接枚举每一个值,来设定哪个角色可以访问到哪些资源。比如 Node,要给一个用户开放 Node 权限,但是我可以指定他只能访问某几个 Node,就是值的枚举。这种方案如果你去实现,集群中节点非常多,并且还要通过不同的角色去映射不同的 Node 分组,其实是非常容易失控的。

RBAC 权限到底要怎么划分

最后还是再三地强调 RBAC 要配好,权限到底要怎么划分。RBAC 其实还分两类,一类是 ClusterRole,定义的是能够访问哪些 Root scope API,另外一类是 Namespace 级别的 Role。

Namespace 下的资源,大家知道,必须要先有 Namespace 才能创建。而 Namespace 创建之后,没创建 RBAC 之前,用户是没有访问权限的。还有接下来会讲到的租户网络问题。如何在创建 Namespace 之后,及时创建 RBAC 和 Network,然后再告知用户这个 Namespace 可以用了,权限和网络都已经配好了。这个在实施过程中是一个非常值得大家思考的问题。这也是为什么在一些方案中会选择再定义一个 Tenant API,即便它是跟 Namespace 一一映射的。因为它可以在 Tenant 上面标记状态,通过 Tenant Controller 去初始化它后面对应的 Namespace,RBAC 和它的网络,完成后再标记为可用。

节点隔离和 Runtime 安全

控制面 VS 数据面Self-hosting(Kubernetes 的控制面组件,APIserver、etcd、controllermanager、scheduler 都是容器化的,并且它们所运行的这套 Kubernetes 就是它自己管的,或者说 APIserver 所在的这个节点,它的 kubelet 就归这个 APIserver 管)这种情况下就会有些干扰问题。Kubernetes 其实在默认配置下,对所有的 Node 一视同仁,它并不关心某个节点上面是运行着平台组件的 Pod,还是普通用户的 Pod。

如果一些大 IO 的比如 DB,被调度到了 APIserver 所在的节点,DB 的 IO 高的时候可能就会直接影响到 etcd 的读写,然后这个集群就不可用了。我们之前在做这个全容器化方案的过程中也遇到过这样的问题。

当然现在如果你使用的是社区默认的方案(Kubeadm),部署完之后会自动给 master 打上 Taint。Taint 就是节点上的一种特殊标记,可以用来排斥所有的 Pod, 只有拥有特定 toleration 的 Pod 才能被调度上来。比如给节点打一个 Taint,reserved-for-control-plan,那么这些节点就会留出来,然后再给 APIserver 等组件打上相应的 toleration,这样就只有这些组件的 Pod 能够被调度上去。这样的好处是可以保证控制面的组件能够得到足够的资源,不会被其他用户的 Pod 影响。像上一个例子里讲到 Kubernetes 没有对 Pod 的 IO 限制,我们可以通过区分节点的方案来做足够的资源预留。把 Pod 分散在不同的节点上,至少让节点的 IO 是够 Pod 用的。

租户节点隔离

另外就是租户的节点要不要隔离的问题。租户的节点隔离其实第一个就是用来划分不同的资源池(different plans),因为平台的计算资源可能有多种定价方案,或者有不同的使用场景。比如某些节点是带 GPU 的,这种带 GPU 节点的成本比较高,那么应该留给需要 GPU 的 Pod,没 GPU 的 Pod 就不应该跑到这些节点上来占据 CPU 内存。

另外可能有一些不同的节点是存储优化或者内存优化的,可以用 taint-toleration 来区分。当然在 taint-toleration 方案之前,其实 node selector 也可以做这个事情。区别是 node selector 是显示指定 Pod 要去哪儿,而 taint-toleration 是定义 Pod 能去哪儿。

另外就是假如你在公有云上提供一个 PaaS 的平台,并且 Runtime 用的是 docker/containerd/runC 这些原生的容器方案,同时应用是来自于最终用户,其实黑客是可以做一些攻击的。所以在这种情况下,容器的隔离不够强大,我们还可以通过租户间的节点隔离,然后用节点的这层虚拟化去把不同租户的业务 Pod 分开。这样,即便租户的一个业务应用被攻击,或者出现异常行为,影响最多是这个租户自己的业务,其他租户可以不感知,不受影响。

安全容器

另外一种方式就是用安全容器。安全容器大家如果了解过就知道,它其实是一个轻量级的虚机,里面跑着容器。而虚机这层可以做到非常的薄,基本上只有内核加一个运行 Docker 所需的最基本的组件。

它的启动时间也可以优化到跟普通容器基本相同的一个水平,这也是目前我们采用的方案。可以直接把它部署在物理机上,这样一方面是性能非常高,另外一方面租户间就可以不用再做节点的隔离,因为每一个 Pod 的外面都有一层轻量级虚拟化的隔离。实际上来说隔离的力度变得更细了,但是最终性能反而提高了,因为原来的 Pod 是跑在虚机上的,而且还是一个重型的虚机。

网络隔离

租户间网络隔离

网络的隔离其实最需要考虑的就是租户间的网络怎么隔的问题。Kubernetes 里面现在用的方案就是配置 NetworkPolicy。NetworkPolicy 这个概念其实可以完全去类比虚机里面的安全组,它是完全扁平的。

因为 Kubernetes 我们知道它只有一张网络,所以每个租户配的 NetworkPolicy 规则也都是作用在一张网上的。它的隔离性其实比较弱,因为在一张网上,只解决了通和断的问题,像带宽这些都无法控制。并且它的易用性比较差,因为在多租场景下创建 Namespace 时,应该把网络全封掉,包括出口流量和入口流量。然后在租户部署一个应用时,再配置 NetworkPolicy 把应用的 Pod 对应的端口打开,这个就非常麻烦。另外就是社区现在另一个 workinggroup 正在重点讨论的,叫多网络平面,它实际上适用的场景非常多,不仅限于多租户。

这里大概讲一下它在多租户里面是怎么用的。每一个租户可以有一个自己的 Network,最后对应的是一个独立的 subnet,然后不同的租户之间完全是不同的 subnet。你可以去映射到 IaaS 底层的真实网络,比如说 Stackube 里是用 neturon 实现的。这种方案的易用性相对来说比 NetworkPolicy 的方式就好很多。因为首先租户的网络是不一样的,租户间天然隔离;同时你创建出来的应用在你自己的租户内,不需要做任何的配置和修改就可以跟租户内其他的 Pod 通信。这个方案实现成本虽然比较高,但是隔离性很强,易用性也好很多。

DNS 及服务

发现租户间网络隔离做完之后,其实它只是一个底层的网络隔离,我们知道在 Kubernetes 中还有 DNS,还有服务发现,它们其实也是全局可见的。大家知道如果进入一个 Pod 的容器内,可以看到基本所有 service 的访问信息都会以环境变量的方式注入进去,或者你知道一个 service 的 Name,就可以直接 ping 通它。所以在这种多租的场景下要怎么做呢?DNS 我们可以对它做一点修改,或者用 core DNS(它本身已经支持直接通过配置就可以做到)。每个租户的 Namespace 都有一个自己的 DNS,这个 DNS 只过滤到这个 Namespace 下的 Pod 和 service,对它们做服务发现。

快速配置一个多租集群

前面主要是介绍大家在构建多租户集群遇到的最关键的三大块的问题,那么接下来是一个相关主要配置项的汇总。

基础安全首先就是基础安全这块,要把 web UI 不需要的 auth 禁掉。因为 web UI 实际上就是一个受信的用户,你在 web UI 上做任何的操作对 Kubernetes 来说,只能知道是来自于 web UI 的请求,并不知道谁做的这个事情。

另外就是要开启审计日志,所有的操作记录都要人工可追溯。Admission Controller 这里主要是要确保开启这个 NamespaceLifecycle,确保 Namespace 创建、删除时它可以完成对应的这些清理的工作。

NodeRestriction 主要是限制 kubelet 访问 APIserver 的时候,它的权限最小。DenyEscalatingExec 是防止用户在执行 Exec 这个命令的时候越权。而 PodTolerationRestriction 则是用来限制最终用户能够设置的 toleration 范围,在前面我们也提过我要通过 taint-toleration 来设置控制面跟数据面 Pod 运行的 node 是属于两个不同的资源池。同时我们要开启 PodSecurityPolicy。PodSecurityPolicy,这个放了一个链接(以下),里面是详细的配置,比如是否接受开启超级权限的容器,能否用 hostpath,它可以限制到每个 Pod,就不用你再自己开发额外的 Admission Controller 或者做额外的 validation,直接在里面配好就行。https://gist.github.com/tallclair/11981031b6bfa829bb1fb9dcb7e026b0

可见性隔离那么可见性的隔离其实刚才也提到了,主要就是说对于普通的用户,我们要把他们限制到只能访问自己所在的 Namespace 下的对象。当然仅仅做这个是不够的,比如有一个 Pod,在我们 kubectl describe 这个 Pod 的时候,它是可以打印出来一些调度信息的。特别是在 Pod 调度失败之后,它会把调度器里面对某个 node 调度运算的结果,为什么不满足之类的信息打印出来,这就泄露了底层 node 的信息。这个问题目前是社区安全的一个缺陷,还没有好的办法解决。我们现在可做的手段只能是配置 RBAC 来保证对象级别访问的独立隔离。
指导文档:https://kubernetes.io/docs/admin/authorization/rbac/#user-facing-roles

避免干扰

避免干扰其实最主要的就是做到控制面的限流,避免某个恶意用户狂调 API,造成 DoS。另外就是要限制 Root scope 的 API,这里有一个特殊情况,就是要把 Namespace 的创建操作开放给普通用户,不然他们就创建不了租户。

另外 ServiceAccountToken,这个是 Kubernetes 里面默认创建的,用来提供 Pod 跟 K8S APIserver 交互的访问凭据,也就是说所有的 Pod 其实默认都是直接有权限跟APIserver 的通信的。这个在多租的场景里需要关掉,否则就会成为一个默认开着的后门。避免干扰另外这里还涉及到的一些 Admission Controller 的开启,这里主要给大家提一下 AntiAffinity 的。

如果在多租场景里用的是安全容器方案,node 没有做专属化隔离,那么你的 Pod 可以配置硬性的反亲和来排斥别的 Pod 跟你运行在一个节点上。被排斥的 Pod 可以是你自己的,也可以是别人的。这种情况下假如我配置了一个 Pod,在反亲和的条件里面配的排斥作用级别是整个集群,那就会因为部了一个 Pod,导致其他所有的 Pod 都无法调度。当然这个里面我们有一个 Admission Controller 就是可以限制你的 Pod 反亲和规则只能配到 node 的级别,所以也就最多你只能占用一个 node,并不能因为部署一个 Pod,把整个集群都占用掉。

Namespace 相关的默认配置前面也有讲到,创建一个 Namespace 并不代表一个租户正常访问所需要的事都做完了,还需要配置它默认的 resourceQuota,Role,NetworkPolicy 或者 Network。因为 Namespaced Role 实际上是属于每个 Namespace 的对象,只有创建了这个对象,才能定义这个 role 在该 Namespace 下的访问权限。而 role binding 其实就是用户跟角色的绑定关系。


多租在华为 PaaS 的演进

华为在做 PaaS 平台的过程中,其实很早就遇到多租户的诉求,包括我们内部的客户,来自电信软件领域或者 IT 系统的。最开始因为社区讨论方案也非常的少,当时安全容器的技术也还没有优化到一个非常好的性能,所以我们采用的方案就是软多租加专属节点,就是把 node 分组之后分配给不同的租户。

但这种方案有它的缺陷,我们知道 dedicated nodes 实际上配置的是 taints 和 tolerations,而 node 上的 taint、Pod 上的 toleration 是有可能泄露被别人知道的。而攻击者只要在自己的 Pod 也配上相同的 toleration,Pod 就可以上到你的节点,这个根本就不可接受。后来我们又尝试了直接对集群做切分的方案,当然做切分不是因为性能问题。(性能其实我们实测在我们的场景下性能可以达到社区早期的 1000,2000 节点,包括后来的 5000 节点。甚至我们在对 scheduler 以及网络上做一些优化之后可以达到 1 万节点。)我们做这个切分还是为了避免 toleration 和 Taint 被修改的这种情况造成租户间可以越权。

当然这个方案后来也只是停留在某几个版本里。为什么呢?因为社区发布了一致性认证,Kubernetes 的 API,我们知道是它最得意的地方,带来了一个非常活跃的应用生态,所以我们都应该去兼容社区原生的 API,所以这个不兼容的切分方案最后也是停留在了某一个版本。现在我们最终采用的方案就是安全容器,其 Runtime 就是 kata container,前身是 Hyper 的 runV 和 intel 的 clear container,最后它们合并成了现在的 kata container,华为也在这个社区面出了很大的贡献。

网络最后我们采用的是 multi-network plane 的方式,这个在社区我们也有开源的项目。实际上我们在生产中用的还是自研的高性能,多平面的容器网络。关于它的能力或者广告性的特征就不赘述了,这里有个链接(以下)是我们最近发布的容器实例的服务,大家可以去体验一下。未来我们会在社区主推硬多租,就是 Tenant API 的实现。

链接:https://www.huaweicloud.com/product/cci.html


社区后续关键特性

社区后续几个关键要发展的特性,一个安全容器的集成,现在采用的是插件化扩展的方式。它还有很多的问题,包括存储的性能问题,因为中间隔了一层虚机,有很多细节的问题。Sandbox API 实际上就是虚机隔离的边界到底是 Pod 就够了,还是 Pod 内 container 之间要再隔,或者把这个隔离放宽,隔在某一组 Pod 之间,这是社区近期非常活跃讨论的问题。

另外一个就是租户,我们希望在 Kubernetes 原生 API 中实现租户的定义,可以让大家在构建多租方案的时候少很多选型和纠结,社区给出一个推荐的标准,大家照着做就行了。网络社区现在有 Network plumbing working group,这里面有很多多租网络的讨论。多网络平面它其实还有很大一块就是现在 5G 发展得非常快,5G 是重度依赖这个特性的。

                                王泽锋/华为云 Kubernetes 开源负责人,社区 maintainer

多年电信领域系统软件开发和性能调优经验,对深度报文解析、协议识别颇有研究。华为云 PaaS 服务团队核心成员,专注于 PaaS 产品和容器开源社区,目前负责华为云 K8S 开源团队在社区贡献的整体工作。

1412 comCount 0