华为云容器实例服务,它基于 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容器和多租隔离等场景的能力补齐和生态发展。

12-01 03:04