基于 K8S 构建企业级 Serverless Container 平台的探索与实践

前言

当前 Kubernetes 已经成为名副其实的企业级容器编排规范,不少云平台都开始提供兼容 Kubernetes 接口的容器服务。而在多用户支持方面,多数平台选择直接提供专属虚机集群,用户须要花费大量精力处理集群规模、资源利用率、费用等问题。 本次分享带来的是华为云在基于 K8S 构建企业级 Serverless Container 平台过程当中的探索与实践,涉及容器安全隔离、多租管理、Serverless 理念在 Kubernetes 平台的落地等相关内容。docker

Kubernetes 在华为云的历程

首先来了解一下华为云在 Kubernetes 的发展历程。2014 年,华为云就开始研究并使用 Kubernetes,早期的重点是将 Kubernetes 应用在私有云环境中。2016 年,华为公有云上发布了容器引擎平台 ( CCE),它的形式与市面上多数的公有云 Kubernetes 服务(如 GKE、AKS) 相似,是给用户提供完整一套托管的K8S集群。而在今年年初,华为云发布了 Kubernetes 容器实例服务(Serverless Container),不过它与业界一些传统的容器实例服务不太同样。后端

容器的三大好处,为应用而生

众所周知,容器技术有三大好处。安全

  • 一是它提供资源隔离,用户很容易经过应用合设来提高资源利用率;
  • 二是,它具有秒级弹性的能力。由于容器自己技术特色,不用加载重型虚拟化,因此它能够作到很是快速的弹性扩缩容;
  • 三是,容器镜像技术,解决了包括应用及其依赖环境的一致性问题,简化业务交付流程。
    但在实际环境中,容器技术带来的终端便利有多少呢?这还得从Kubernetes的使用形态谈起。

Kubernetes 的常见使用形态

私有云部署Kubernetes

人们使用 Kubernetes 的一种常见形式就是在本身的数据中心搭建集群。网络

这种作法的优势在于:less

  • 第一,能够享受DIY过程带来的乐趣和成就感(固然也可能随使用时间的增加,问题愈来愈多而变成苦难)。
  • 第二,在全套私有化的模式下,数据请求都在本地处理,不会存在隐私顾虑。
  • 第三,资源规划、集群安装部署升级,都是用户本身端到端控制。

可是缺点也很明显:首先,不少人在自建时只看中了 Kubernetes,对周边配套并没作过很深度的研究,在实施过程当中就会面临网络、存储等配套系统的选型问题。其次,用户须要负担 100% 的运维成本,并且资源的投入每每是一次性(或阶段性的),投入成本门槛很是高。此外,在自建的环境中 Kubernetes 的集群数量、中的单个集群规模每每不会很大,因此业务部署规模比较大时,弹性伸缩还会受限于底层资源规模,恰恰硬件资源的扩容速度每每慢得不可想象。最后,开发者习惯于作比较多的资源预留,所以资源利用率也很是有限。也就是说,自建者还要为全套资源利用率买单。 运维

公有云半托管Kubernetes专属集群

第二种 Kubernetes 的常见形态是公有云的(半)托管集群。性能

能够这样理解,用户购买一组虚机,云平台则自动在这些机器上部署一套 Kubernetes,而半托管含义在于有些平台,它的控制面多是附送的。测试

这种形态的优势是:优化

  • 用户本身拥有集群,不用担忧与其余用户共用一套 Kubernetes 可能引发一系列干扰问题。
  • 云平台在提供 Kubernetes 服务时,每每通过大量的测试和调优,因此给出集群的配置是在自家平台上的最佳实践。用户经过这种模式在云上运行 Kubernetes,能够得到比本身部署运维好不少的体验。
  • Kubernetes 社区发布新版本后,云平台会至少作一轮额外的测试、问题修复,再上线并推荐用户升级。这用就节省了用户对升级时机评估的工做量。而直接使用开源版本的用户,若是对新版本跟进太快,本身要踩不少坑,但要延后到哪一个版本再升,则要持续跟进社区bug和fix的进度,费时费力。
  • 当用户的 Kubernetes 出现问题时,能够从云平台得到专业的技术支持。因此在公有云上使用(半)托管的 Kubernetes 服务,是一种很好的成本转嫁方式,运维成本与云平台共同分担。

固然仍有一些明显的缺点spa

首先仍是价格,当用户购买一组虚机,须要付出的价格是 虚机 Flavor 单价 乘以 节点数量 N。其次,由于用户独占一套 Kubernetes 集群,规格不会太大,总体资源利用率仍然比较低。即便尝试调优也效果不大,何况多数状况下用户名不能彻底自定义控制面组件的配置。另外,当集群空闲资源很少而业务须要扩容时,还必须先扩集群,端到端的扩容会受限于虚机的建立时间。

容器实例服务

第三种,严格说是用户使用容器的形态,使用公有云的容器实例服务。

它的优势显而易见:

  • 用户不感知底层集群,也无需运维;
  • 资源订价颗粒度足够细,用多少买多少;
  • 真正的秒级扩缩容,而且是秒级计费。

其缺点在于:

不少平台的容器实例服务主要提供私有API,并不能很好兼容kubernetes的API,并且容易被厂商绑定。

迫于知足用户使用K8S API的需求,这些容器实例服务也推出了基于virtual-kubelet项目的兼容方案。经过把整个容器实例服务虚拟成 Kubernetes 集群中的节点,对接 kubernetes master 来处理 Pod 的运行。

然而,因为整个容器实例服务被虚拟成了一个超级节点。Kubernetes 中本来针对多节点精心设计的一系列应用高可用相关特性都没法生效。另外一个问题是这个基于 virtual-kubelet 项目的兼容方案在数据面并不完整,这里包括项目成员在Kube-proxy部署层级位置上的摇摆,以及仍无音讯的容器存储如何兼容。

看了前面这么多的背景,你可能不由要问: 为何不尝试使用 Kubernetes 的多租方案来构建 Serverless Container 服务?

实际上基于 Kubernetes 多租来构建容器实例服务,优势有不少,最大的在因而支持 K8S 原生 API 和命令行。用户围绕 Kubernetes 开发的应用都以直接在基于 K8S 的 Serverless Container 上部署和运行。由于容器能够作到秒级计费,用户能够享受容器实例服务价格门槛较低的特色。另外,这种形态下一般是云平台来运维一个大资源池,用户只需为业务容器的资源付费,不须要关心底层集群的资源利用率,也没有集群运维的开销。

这种形体现存的主要挑战是 K8S 原生只支持软多租,隔离性等方面还有有欠缺。

接下来咱们回顾一下 K8S 中典型的多租场景。

  • 第一是 SaaS 平台。或其余基于 K8S 封装提供的服务,它不直接暴露 K8S 的 API。由于有一层本身的 API 封装,平台能够作不少额外工做,好比本身实现租户定义,因此对于 k8s 控制面的租户隔离要求较低。而应用来自最终用户,并不可信,因此实际上在容器运行时,须要较强的数据面资源隔离和访问控制。
  • 第二小公司的内部平台。用户和应用都来自于公司内部,互信程度比较高,控制面和数据面都不须要作过多额外的隔离加强。原生的 K8S 就能知足须要。
  • 第三是大型企业的平台。这种场景下 K8S 的用户,基原本自于企业内部的各个部门,开发部署的应用也是通过内部的验证以后才能够上线。因此应用的行为是可信的,数据面不须要作太多的隔离。更多的是要在控制面作一些防御控制,来避免不一样部门、业务之间的管理干扰,如API调用时,须要实现针对租户的限流。
  • 第四种场景,在公有云上对外提供一个多租的 K8S 平台。它对控制面和数据面的要求都是最高的。由于应用的来源不可控,极可能包含一些恶意代码。而 K8S 的 API 直接暴露给最终用户,控制面的隔离能力,如区分租户的API限流、访问控制等都是不可或缺的。
    总结一下,对于 K8S 来讲,若是要在公有云场景下提供 Serverless Container 服务,须要解决三大类挑战。
  • 一是租户概念的引入、访问控制实现。目前 K8S 仍然没有原生的租户概念,以 Namespace 为边界的并不能不少好适配多租场景。
  • 二是节点 (计算资源) 的隔离还有 Runtime 的安全。
  • 三是网络隔离,K8S 默认网络全通的模式在这种景下会有不少问题。

华为云的探索与实践

下图是华为云容器实例服务的全貌,它基于 Kubernetes 打造,对最终用户直接提供 K8S 的 API。正如前面所说,它最大的优势是用户能够围绕 K8S 直接定义运行应用。

这里值得一提是,咱们采用了全物理机的方案,对于端到端资源利用率有一个很大的提高。而在 K8S 之上咱们经过一层封装实现了超规模资源池。你们知道 K8S 现开源的版本最大只能支持到 5000 节点,而且这是在 Google 云上的验证结果,而在不少其余的云平台每每达不到。主要是受限于底层网络和存储系统。

因此在华为云,咱们的作法是经过一层封装和引入 Federation 来得到总体服务的超大规模。同时由于 K8S 原生多租能力很是有限,因此咱们选择将额外基于租户的验证、多租限流等工做放在这一层封装中实现。但对于应用定义等接口,则是直接透传 K8S 原生的 API 数据,只是在调用过程当中增长如请求合法性等的校验。图中右侧的容器网络、容器存储,现有的开源方案是没法知足的,因此华为云采用自研的策略。

租户概念和网络隔离

前面已经讲过,K8S 原生并无租户概念,只有一层以 Namespace 为边界的隔离。在 Namespace 这一层,除了API对象的可见性隔离,K8S 还提供了 Resource Quota(资源总和限制)以及 Limit Range(定义每一个Pod、Container能使用的资源范围)等精细的配额管理能力。而在华为云上,咱们设计的租户模型是:租户(用户)、项目、Namespace 三层模型,方便用户管理多个项目的开发、测试、生产等不一样阶段。

网络隔离方面,采用多网络模型,一个项目中能够定义多个VPC,VPC 和 Namespace 是一对多的关系。用户能够结合实际须要将开发、测试阶段的应用部署在同个 VPC 的不一样 Namespace 中便于调试和问题定位,生产环境部署在拥有单独 VPC 的 Namespace 保证不受其余活动干扰。

Runtime安全与隔离

再看 Runtime,因为是全物理机的模式,节点被不一样的租户共享,普通docker容器没法知足Pod间的隔离性要求,Runtime采用的是安全容器(即早期的runV,如今的Kata Container)。使用安全容器的主要思路,就是在Pod外围包一层轻量级虚拟机,这样既保证了Pod间的隔离性,又兼容了K8S原生Pod内容器共享网络和存储的设计。而包装这层轻量级的虚机,由于里面只须要运行容器,能够经过裁剪等手段优化到与普通容器相同数量级的启动时间。

接口层面,按照社区如今的进展,推荐的作法是使用 CRI (container runtime interface) 直接对接安全容器的 CRI-shim 实现。不过由于项目启动很早,CRI 还没有成熟, 咱们采用的是在 Docker 内部分支处理的方案:在容器引擎服务中,仍然是原来的逻辑,直接建立普通容器;而在咱们的容器实例服务里,经过 Docker API 调用建立出来的则是安全容器。用户本来使用 Docker 容器的习惯几乎没有改变,在指定容器镜像时也是须要指定所需运行的 Docker 镜像,外层轻量级虚机的镜像直接由宿主机提供。这样既解决了安全隔离的问题,又不会给用户带来额外的切换成本。

最后,让咱们来回顾一下本次分享的关键内容。

  • 首先,咱们基于 Kubernetes 构建了华为云容器实例服务的核心部分,在其上封装实现了多租户的定义和访问隔离。对用户来讲,最大的好处是可使用原生 K8S 的 API 和命令行,不须要感知 K8S 集群和底层资源,不须要在使用前建立集群,使用过程当中也不用担忧集群出现任何问题,彻底由平台自身来保证服务的可用性。
  • 其次,在计算资源隔离方面,咱们采用是Docker原生API后端对接 kata container,能够最大限度兼容两个项目的生态。而对于最终用户来讲,用户只须要知道安全隔离足够可靠。而在网络隔离方面,采用多网络的模型,用户能够定义多个 VPC,将 Namespace 和应用建立到不一样的 VPC 中,以此实现彼此之间的隔离。
  • 此外,针对高性能计算场景,咱们还完成了GPU、FPGA加速芯片的分配调度优化,配合高性能网络与本地存储加速,进一步提高了端到端计算性能。

结语

以上是华为云对Kubernetes在Serverless Container产品落地中的实践经验。随着产品的成熟,咱们也计划将一些共性的加强点回馈社区,推进Kubernetes在面向Serverless容器和多租隔离等场景的能力补齐和生态发展。

相关文章
相关标签/搜索