一般来讲,在云端构建大规模计算集群是难以实现完整的资源自治的。那么在计算任务运行容器化之后,应当如何进行云上构建计算集群并对大规模容器进行管理呢?请看这篇文章。
以下内容整理自分享:
我是来自晶泰科技的林帅康,今天我想和大家分享的主题是《云上构建容器化的科学计算平台》。
晶泰科技(XtalPi)介绍
在讲之前,我会对公司有一个简单的介绍。这张图主要表现的是在药工业里面做一款药,从这个图可以看出,大概会经过七个大的步骤,会花费 6-10 年的时间以上,才可以有一款真正上市。右边看,药最终到药监局审批的时候,可能需要临床实验,小白鼠或者更高级的临床实验。我们主要关注的领域不会在这里,主要是在前期的临床研究。在临床研究中,这是化合物的集合,我们需要从一万个化合物选择出 250 个可以符合临床研究的化合物,从这里再挑选 5 个精型出来做成一些药制,然后开始临床实验,最终才会有一款药真正上来,比如说可能是一个抗癌药物。所以这属于一个重磅药物,经历的时间周期比较长,毕竟生命还是很可贵的,做这种东西要非常小心才行。
晶泰主要致力于通过分子模拟平台以及药物动力学、剂型预测技术,减少在药物前期的研发周期,从 6-8 年可以减少到 4-5 年时间。它所依赖的技术,最右边会有量子算法,这主要是和科学计算相关,它可能会包括大家听说过的蚁群算法以及退火算法等东西。再结合 AI 的融合,最终这两部分会跑在超算的平台上面,例如我们熟知的天河 2 号或者新出的中国最大的超算中心。但是因为超算上面使用的资源可能会有申请的过程,而且使用量会有一定的限制,比如说一个小企业申请,有可能会限制只可用几十台或者上千台,比较困难。
我们就会想到,现在云计算发展得非常快,很多企业已经从传统企业转换成云上企业,已经成功落地。能否把传统的科学计算移到云上面?当然,现在很多公有云平台已经在做,比较典型的产品可能是批量计算、高性能计算。我们把这两部分技术结合之后,借助腾讯云和 AWS 去构建一个大规模的 HPC 集群,可能会达到百万核实量级。核实在科学计算里面是一个通用的概念,主要衡量计算池的标准,和超算用浮点的计算能力是一样的,100 万核实怎么换算?比如说每一台机器会有 24 核或者 32 核,1 万个核需要 300 台机器,100 万可能会到几千上万级的机器集群。
为什么会需要那么大量级的集群呢?这是我们的一个小分子药物的剂型预测流程,我简单介绍一下,大家有流程不清楚没有关系,我可以打一个简单的比方。左边是分子输入结构,你们可以理解为它是一个小的文本文件,里面包含了一些化学参数,描述分子的见长和角度的旋转。经过这个输入,我们会有一个结构的搜索算法,会产生亿级的晶体结构处理,也就是很大的输入池。
我们区别一些大数据公司,大数据可能有几个 T,或者 PB 级别的数据,在上面进行并行分析计算,而我们的输入很小,就是几 KB,但是中间会产生大量的数据。我们可能还会经历在科学里面的能量筛选,以及基于 CPU 的聚合聚类算法,还有高精度晶体结构的排位,最终得到我们想要的能量式图的结果在里面。这个流程中每个流程都需要计算来支持,这个图是说每个过程中可能会需要多少量极资源在里面。前期的几个流程来看,需要的资源都可以在规模不大的集群里面满足需求。后面比较大,而且比较高,占据了计算的很大部分,这就需要我们借助云计算的云在里面,可能需要把多个云融合在一起,去构建一个比较大规模的资源池,在里面跑相关的计算任务。
计算平台演变
刚才的介绍是想说明未来支撑比较特别的场景,可能需要一个大规模的资源池的支撑。在构建这个资源池的时候,有一个计算平台演变的过程,这个演变过程就不放太多的架构图,稍微解析一下。我们公司从 2015 年成立的时候,也是从超算这边开始脱离出来使用的。当然了,我们第一代平台有一个 PBS 调度系统,一般跑在超算上面都会有一个任务调度系统。相对于 K8s 这种复杂的容器编排来说是比较轻量级的。
还有一个 NFS,可能大家对此比较清楚。当然了,超算的 NFS 工程和我们自己建的 NFS 肯定不一定,它是高通量以及 IOPS 都是几十兆到上百万兆网卡的支持。我们第一平台很简单,都是使用开源的,在云上主结点搭建 PBS 几个 G 的内核就可以支持了,NS 也是直接用开源的 ABD Get 一下,就可以产生一个挂载点,然后再挂几十台,这样基本满足了我们前期使用的需求。
但是随着业务的递增,我们需要计算量越来越大,这两个也有它们的局限性,例如有些资源利用率的不足以及 LPS 的性能不足,LPS 压测可能会焊住以及假死等等状况。这样我们就会有第二代平台的迭代更新在里面,蓝色这边是我们开使用 Mesos。我们 2016 年也有关注 K8s,有一个简单的转型,但是当时 K8s 还处于比较早期的状态,而且也没有太支持批量计算服务在里面,我们就选用了 mesos。当时 mesos 比较火,在国内有很多公有云都会根据它做一些第三方的插件调度软件之类,我们也会拿 mesos 来管理我们的集群。
2016 年 2 月份,我们开始用 mesos,以及开始我们的容器化之路,真正开始用 Docker 去封装一些高性能的计算算法。在 2016-2018 年这两年之间,基本还是沿用了 mesos。中间这些都是为了去拓展、递增我们资源池的实力数,比如我们开使用竞价实力,一开始国内的竞价实力还没有兴起,会使用不同的类型,这两个也是出于成本的考虑,竞价实力以及多个实力类型的搭配可以降低我们的计算成本。然后用 Golang 去重构我们的调度系统,因为任务量比较大,用来只用排产,性能上面会有一些瓶颈。
使用多个公有云厂商,也开始接触国外的谷歌、亚马逊,以及国内的腾讯云,我们有个多云资源弹性伸缩与监控,最终就会开始使用 K8s 集群去管理现在超算上面也能跑的任务。这里基本介绍了我们平台演变的历程。
下面是现在的三代平台技术站。上面是我们现有的计算产品,主要是晶形搜索服务以及高峰量、精度比较高的计算服务,以及最终产出的报告工具。中间是刚才说的我们自研的算法,以及融合现有算法进行二次开发、封装,打包成一个 Docker 镜像,业务人员只要去使用这个 Docker 镜像,就可以运行在超算上面的高精度的一些分子计算以及一些通用力场的计算。下面是支撑上面计算的平台架构的高性能平台,最上面就是云资源。
它的架构是这样的。左边是业务前端,我们使用的 Jupiter 的 Web 服务,Jupiter 大量用于科学家在线编程以及机器学习。下来是我们对输入的文件进行一键化清洗和初步的分析,最终会到以对象存储以及其他存储空间组成一个数据壶,中间融合了一定的 workflow 操作在里面,业务人员随着提交任务计算,会不停的在每个阶段对计算出来的结果进行分析,再去重新生成新的任务。
最右边是计算平台的架构图,有任务的管理、任务队列、中间件,例如使用一个 MQ 对接了不同云的集群,下面是某一个公有云集群,例如是腾讯云 TKE 容器集成在里面。当然,我们还是会有兼任 mesos 集群在里面管理。
腾讯云容器服务实践
这是我站在使用腾讯云 TKE 的场景去做一些讲解,没有涉及 K8s 太深入的东西。我会在使用腾讯云中做一个大集群构建时遇到的问题,也是大家可能面临过,以及通用的一些解决方法,希望和大家有技术上的交流。
需要说明一下,我们关注的更多是超算计算和现在做的服务发布以及编排,可能有比较大的差异。科学计算工作负载的特点,主要是计算是密集型,时间持续比较久。虽然时间比较久,但是还是一次性任务,可能会持续几个小时,几天或者几个一星期,最终有一个完成态的结果。它会追求算法的执行效率,算法直接导致了我们计算的成本,如果算得越快越准确,计算成本就可以压缩下来。它会以一些工作站以及超算为主,传统来说都是这样的,直到这几年超算开始搬上云,才有云超算系统。右边是信息服务的特点,K8s 应用的主要模式。
容器镜像
云容器服务,我可能会分几部分来讲。一个是镜像,可能大家都使用过,但是对于超算,镜像会和大家平时使用的镜像不一样,可能会包含一些比较大的科学计算软件在里面,每个科学软件可能达到 GB 的级别,我们曾经打成一个包,可以达到 10GB 的镜像在里面,后面也有优化和分解,但是分解也有 2-3G 级别。
下面说集群空间以及集群扩容。扩容集群对于我们很重要,也是关于到成本的问题。因为我们扩容对于云服务还是要求比较苛刻的,我们要构建一个一台台到三台台 24 核的机器,要求在 20 分钟完成,有不停的任务去提交。而且在提交的过程中,我们要求这个集群里面的负载是达到 80-90%以上的。
我们使用 CI 也比较简单,触发一个 drone 的 CI,然后输入的 SDK 库,SDK 库是我们一些科学家和量化工程师开发的专有算法,去打包或者其他软件,通过这个私有库下载到 Docker 镜像,根据 Dockerfile 去构建。拉取一些基础的镜像。然后把镜像同步了 AWS 或者腾讯云上面来,最终有一个发布通知的过程。
右边有一个镜像分层的结构在里面,基础镜像比较熟悉了,第二块比较特别一些,有 HPC Images 在里面。我们会使用一些现有比较有名的二进制软件在里面,这些软件都是在固定的平台去编译的,有的有源代码,有的没有源代码,他们在固定平台编译的时候,因为云服务发展得比较快,例如腾讯云可能又推出一些新的机器类型,它的 CPU 指定级以及其他一些架构有变化,老的 NEG 系统跑起来,可能跑着跑着就会死掉,还有一个性能的问题,它可能没有用到一些优化的 CPU 指令集,比如说 ABS 的一些指令集,然后会导致效率上下降 20-30%。
如果大批量使用,这是很大的成本量。我们会针对不同的平台有智能化的构建,去适配不同的当前在腾讯云上面用的机型,以便它能对应在某一台机器跑的时候,不至于是跑了一个错误的镜像在里面。下面有一个工程的镜像在里面,就是刚才说的算法开发组上传的一些 SDK,最终是 Docker 跑起来运行池状态。
镜像负载我刚才稍微解析了一下。有一些科学技术软件可能会达到 GB 的级别,打包几个进去可能就会达到几个 G 或者上 10G 的样子。我们可能会对镜像进行一些裁减,裁减完之后可能会有一个镜像预拉取,也会考察当前能否有一些方法可以加速镜像的拉取。因为我们最终裁减还会会有一些软件保留在镜像里面,所以在公有云这边,例如腾讯云提供的 TKE 来进行镜像任务编排的时候,有时也会发现大批量拉取的时候,镜像拉取比较慢,而且会有超时操作动作,有可能是云服务镜像仓库的问题,也有可能是因为网络的问题以及等等问题。
虽然腾讯云已经在上面提供了自建的平台,但是我们也要看是否有一些优化的方案。现在是 K8s 集成云来托管,但是也许有一天我们可以提供 A 准的主机径下功能可以定制化开发的,我们可以改变参数。后来我发现,最新版的 K8s 已经支持动态修改 Kubulet 参数。
下面这三个参数可能会涉及到镜像拉取的性能以及并发率。第一是串行镜像拉取,通常情况下是 forest,官方文档上面说,如果执行错,可能会对老版本的 Docker 以及使用 NUSFS 的后端存储会造成一些影响。我们现在平台上的 Docker 版本都比较新,这个参数开启可能会对我们有一些帮助。第二是镜像拉取超时,到底要设多久,可能和我们大镜像经验值有关,可能会有 10 分钟。Docker 这边可能会有并发拉取的参数在里面,也可以去调节,加速任务分发时减少镜像拉取时间,尽快把任务跑起来,毕竟时间就是金钱。
讲完镜像,开始真正讲 K8s 集群的构建。我们当然是基于腾讯云服务器的 TKE 来构建,之前是叫 CCS,现在叫 TKE 了。它现在的构建方式相对于之前我们自己手动构建的方式更加方便,基本一键就可以构建出一个带有 Master 的 K8s 小集群在里面,有点像集群即服务,我这个集群可以通过一种服务的方式提供出来,你可以随时删掉或者创建。
腾讯云这边也打通了和其他每个一些云服务的服务,例如监控、hap、安全的以后一些服务在里面,用起来还是比较方便的。TKE 会提供一个 API 出来,但是它提供的 API 主要还是针对一些服务编排,真正去做高性能计算的任务提交,我们现在还是用原生的 client-go 来做的。右边是一个 K8s 高可用的集群架构。
我们来看一下,现在 K8s 已经发布到 1.11。现在它支持不超过五千个结点,在集群里面不超过 1.5 万个 pod,以及不超过 30 万个容器,大概结点不超过 100 个 pod。会有这些限制在里面。对应到我们的应用需求,我们当前的大概集群规模可能会达到 100-3000 个结点,可能大家会觉得这会小于它的结点数,应该比较安全。但是因为我们用的是大机器类型,每个机器都是 24 核或者 32 核类型,如果稍微拆小一点,用 18 核或者 16 核,可能机器数就会翻倍。
下面有一个红色标,这个 pod 数就会超出了它的限制,可能是 1000-70000 个 pod。容器和上面相同,稍后我会解释为什么相同。pod 单个结点一般会有 1-24,我们目前是用 24 的机器。下面产生这个数据的原因有这么几点,我们的 SBC 单机的配置要求比较高,可能是 24 核或者 32 核的大机器类型,现在一个 pod 对应一个 tast,就是一个 pod 会跑一个任务。
我们最小的一个 pod 是多少?需要的 CPU 是一个核,24 核在最极端的情况下会跑 24 个任务,就会有 24 个 pod 在跑,这样算起来就超过它的限制。我们还会有单次提交任务量比较大的情况,例如我们单次会提交 10 万个任务,如果你不控制任务提交速度,把 10 万个任务都提交到 K8s 里面去,即使资源都起来 100 台,但是已经有 9 万多个任务在等待了,这对它的其他组件是有一个冲击性的,特别是一些周期性查询的组件在里面。
我之前使用腾讯云,坦白讲还是遇到了一些问题,毕竟现在国内公有云上的 K8s 集群还相对来说不是完全的特别成熟,特别是面对我们这种使用情况比较特殊的,构建集群也比较大,任务队列也比较长,这需要有个定制化开发,或者慢慢去调试的过程。左边是我们遇到的一些问题,比如说 Kubectl 请求超时,推荐一个命令,加-V 可以打印每请求一步请求到哪里,以及到哪里去超时,可以定位到相应的问题是请求到一个 API 还是别的地方。K8s 调度严重延时,这也是因为任务队列过长的一个主结点集群性能下降,可能会有调度的退避算法在里面,即使 Node 上面有资源,但是这里卡住了,不会把相应的 pod 调进去。
还有 K8s-dns 负载过高,如果每个 pod 里面都会有一个 dns 请求,就可能单次有上万个 pod 去跑,对 K8s-dns 去请求。因为 K8s-dns 还是比较轻量级的,它虽然有一个负载过程在里面,但是还有可能会拉垮它,API 不可能开始出来,以及 ETCD 读取延时变大,因为提交任务比较大,每个任务通过 job 去创建,那么在 ETCD 上面就会有对相应的数据存储,以及 ETCD 可能还会有一个事件对象存储在里面。K8s 容器网络不可用也是和其他相关的。
这边中间是我们和腾讯云这边有一个测试过程,发现了一些问题,刚才的导师也说针对一些特殊的任务,要做定制化 Master 集群的构建,要把大集群拆分,以及把 Master 配置上升,通用可能会上升到最顶配,32 核或者是 60G 的内存级别。ETCD 原来只是一些机械存储,也可以改成 SSD 的存储。etcduf 的分离和读取时延时优化相关,数据拉取和数据事件响应可以分开,通过前面的负载可以保证 Kubernete、Kubecontrol 以及其他一些事件请求可以得到及时的响应。
右边是我们自己做的调度系统的优化过程,尽量用 K8s 的 job 类型,因为经过测试,相比 job 类型,它在 EDG 上面存储的数据会多一些,数量比较大,可能就会有上 G、上 10G 的差别在里面。我们也会控制任务的提交速度,我们之前也有考虑过这一点,但是当时也是比较信任 K8s,所以一股脑把很多任务都积压上去,不用去管,让它慢慢去调度,保证整个集群都是一直高负载的,不然我们可能调度这边还要周期性轮巡当前 K8s 的自营状态。
而我们从 mesos 切换到 K8s 这边,就是想不需要管控当前集群中结点的资源状况,我们只需要把任务提交上去,它就负责把我们的 job 合理编排到合适的结点上面去,以达到集群的高负载状态。原来 mesos 是一个二层的调度框架,第一层调度框架是把整个集群的资源返回给我们,我们开发一个二层调度框架,根据这些资源去匹配任务队列里的不同任务,去分发到对应的结点。这里会有一个装箱问题,这是一个非常难的问题,有几个箱怎么去通过装箱算法达到最高的利用率,K8s 解决了我们部分的装箱问题,减轻了我们对资源式图的依赖。
在 Netwook host 方面,一些批量的任务之间没有网络通信,都是独立的离线任务,它用容器网络和不用区别不大。DNS host 方面,腾讯云的同事反映,访问外部服务时可以直接通过主机的 DNS host 就可以,不需要走 K8s-dns。后面我们还有另外一些任务类型需要 DNS host、K8s-dns 来支持。这边主要是一些优化的点。
K8s 官方也提供了一些构建大集群的辅助文档在里面,但实际上你在构建的时候还是会有形形色色的问题在上面是没有提及到的。
K8s 主结点集成已经由腾讯云给我们构建出来了,接下来肯定是要添加计算结点在里面,通常情况下都会提供弹性伸缩组融合在里面。目前大多数都会实现了 K8s 官方的社区版实现。我们的要求主要出于节约成本的目的,一定要高度弹性的以及快速扩缩容,因为它会涉及到我们案例报告产出,我们有一个案例有一个周期,需要在特定的时间内输出这个报告。
但是我一次性提交 10 万个任务,可能会要求几天之内要把这个任务算完,所以单次的弹性资源有可能是 0-1000/2000 个结点一起跑,然后跑完之后又从 2000 个结点缩放到 0 的结点,会有这种场景在里面。大概是这样子,也就是说我 8 点的时候就开始提交任务资源,从 8:20 提交得队列比较长在这里了,我们就会限制一个流控。稍微了解一下 K8s 弹性伸缩的原理,是根据 pending pod 的数目进行触发的。
我们可能要求 20 分钟之内扩到 4 万个资源在里面,也就是 2000 台机子在里面。这个任务量比较大,算的时间比较久,可能从今天 8 点算到明天 9 点大概会算完,因为任务的输出很多时候都会有相似性,所以计算的周期相似,那么就会有一大批任务会释放出来。到这里就会有一个比较长的曲线在里面,这也会影响我们的成本,我们称之为长尾的任务,也是一个遗留的装箱问题,我们还没有实现 K8s 的重调度以及任务可重调度断点去算的功能在里面。
稍微提及一下,因为了解 K8s 的可能都会知道。刚才我们提到了扩容机制,可能调度失败的 pending pod 数量同我们配置伸缩组里面的配置,例如有一个 1 万个是调度失败的,那么我们现在配置的伸缩组可能就是每个机器类型是 24 核,它就会计算出相应的机器类型,会有分批的添加计算资源,达到调度的效果。
缩容方面,目前官方文档也有一个触发条件,是当前 Node 一个(英文)的 CPU 可能会少于 50%,K8s 这边伸缩容不会考虑实际上的机器负载,主要是针对 pod 来调度,如果 pod 没有可调度的资源,它就会进行扩容,如果 Node 结点有一些 CPU 的(英文)值,例如 24 核当前只跑了 8 核任务,它也可能会触发调度,最终从三个结点把 pod 漂移到两个结点上面去,这种情况对于我们做 HPC jop 会有影响,我们 HPC jop 是一次性的,并不像服务可以随时漂移,它需要一次性算完就算完,中间如果打断,有可能浪费前面 10 个小时计算的机时。
基于这种情况,我们会想怎么阻止 pod 被重调度漂移,官方提供了一些参数,例如在 cistern 上面的空间,这些 pod 不会漂移,还有一些外部存储的 pod 也不会漂移。但是我们不让它漂移,刚才有一个长尾的情况在里面,最终到 9 点的时候,因为这一千台机器的任务都是分散调度的,在调度时并不知道这个任务是多长多久的,最终会导致有一些长任务分布到每一台机器上面去,所以大部分任务跑完之后会发现有很多机器上面单独跑了一两个任务,每个任务可能就占 8 核,那可能每台机器有 16 核的浪费,有几百台机子都是 16 核,其余去等待几小时让它算完,就有资源浪费的情况。
当时我们考虑支持断点续算的功能,断点续算在我们这边的实现原理也比较简单,可能说当 HPC job 周期性算的时候,我们有(英文)的动作在里面,把中间的结果保存下来,就像进程调度一样,有上下文压占和出占一样,就是说开个(英文)上传到对象存储,过了几个小时,发现有大批量的释放之后,整个集群的资源利用率会下降,这时候就可以触发这个重调度,把这些占用了结点资源,但是只是占用了小部分可以做一个漂移,它漂移到另外新的结点,就可以从对象存储里面把之前的上下文下载下来,重新开始它上一步计算。当然,这个重调度计算还是会有一定的机时在浪费,因为(英文)这边有一个周期,可能会浪费一个小时,我们通过这个情况缩短了它浪费的力度。这里主要是资源利用率的问题。
搞定了集群的构建以及快速的扩缩容之后,就开始提交任务。稍微解释一下,现在高性能迁移的任务过来有哪些。从时候维度来看,分短时间任务和长时间任务。当然,其实它对应的具体实现算法可能是只要在单结点里面跑就 OK 了,还有需要多个结点协同去跑的,比如说那些流体计算,可能一个任务拆解成了几十个小任务,需要在几十台或者上百台机器上面去跑单个任务。
二是低精度和高精度任务。在药物计算里面中会有精度要求,从右边图来说,不同的科学计算软件对于输出进行不同的算法计算,会有一个精度的差别,也会反映在时间上面。往往低精度的算法要求的时间比较低,但是高精度算法比较耗机时,使用资源量比较大,最终计算的精度就比较高一些。上 K8s,我们选择过用 developm 还是用 job 类型,我们曾经用过 developm 来做,但是对于 K8s 主结点还是产生压力比较大,job 类型在今年算是比较成熟的类型了,也是面向高性能计算来定义的。我们的任务类型从核数来说,分为 1、2、4、8、16 核,也是为了实现装箱的问题,提高资源利用率。
当然,可能还会从其他维度来分,它是一个计算型,里面可能又分为计算需要的内存比较大一级计算需要的存储比较大。当然,目前大部分都是普通的计算型,就是说存储和内存一般按机器分配 1:2,比如说按 4 核来说,就会有 48G 内存,1:2 就 OK 了。右边是我们现在使用到的 job 类型,可能看得不太清楚,里面会有红颜色标志下来比较重要的参数。我们会用到一些外部挂载,例如腾讯云的 CFS 这种情况,还会用到一些 Docker 或者 K8s 默认的内存共享会比较小,比如说几十兆、上百兆,其实有的科学计算软件可能需要几百兆共享内存,如果运行池比较小,就会导致宕机,目前我们会通过某些解决方案让它扩大,我们之前也在 K8s 上有提及这种方案,挂载了外部一个 Net host 进入里面去充当共享文件存储,但是往往挂载的是一个的文件类型,会导致 pod 无限重启的问题,有待后续开发方面有更新的支持。
任务装箱现在主要是依赖 K8s,我们后期也会考虑有一个对等调度 K8s 支持的定制化调度,这样 K8s 本身的功能会退化成资源的管理者,有点像回到了 mesos 开发模式在里面,但是它提供了其他的特性,我们还是可以用到,例如它的容器网络以及一些外部可插拔的硬件,例如一些 GPU、IP 网络或者是一些高性能的网卡。然后是 job 的生命周期管理,这比较简单,每个 job 都会有一个生命周期管理,我们定义成它是一个 rending 或者是被杀死、休眠状态以及被(英文)状态,最终会反映到我们的队列数据库上面,它是实时和 K8s 的 job pod 状态去同步的。
这边是一个单结点的任务定义,下面说我们现在支持的 HPC 多结点并行的任务。了解过高性能计算的人,都会通常意识到现在一些公有云的普通网络没有办法满足 MPI 数据并行任务。MPI 需要一个高性能的网络,可能是几倍、几十倍的万兆网卡,需要一些专有的网卡去支持远程的直接内存访问。
通用的概念是,有两台机子,这台可以通过网络去访问那一台的内存,就像我在本机访问的速度一样,延时是非常低的。当然,这需要一些专有的网卡。运行任务的运行周期会相对长一些,右边是我们在 K8s 实现的 MPI 任务。刚才提及现有的 TKE 提供的网络没有达到通用的 MPI 的网络要求,但是我们会其中筛选出一些可以在云上面跑的 MPI 任务。它们结点之间的数据交互通常是比较少的,这样它们走的网络数据传输也比较少,这样就可以避免高性能网络的限制,但是还是会有很大的局限性,在网络发展里面肯定会接触很多流体力学计算在里面,现在这种情况是没有办法满足的。
但是刚才看老师的解析,我们也关注到现在公有云陆陆续续会上一些裸金属的机器在里面,机器上面会配备一些高性能的网卡。并且 K8s 这边有一个叫做(英文)插件支持的机制在里面,可以直接把 RDMA 网卡或者其他高性能的网卡插到上面去,跨过了 OS 以及 TCBIB 网络层,可以实现低延时的数据分发在里面。右边这个图是 InfiniBand 性能和百兆网卡性能(英文)区别,可以看到它的测序是 OpenMPI 以及 MPICH 两个开源的 MIP 库,右边时间明显比左边时间长很多,因此它是依赖于高性能网络提高计算效率的。可能大家还是接触比较少,我稍微提及一下。
任务的性能监控刚才已经提及到了,容器云这边已经提供了比较健全的服务监控。当然,我们可能会出于一些其他的需求,需要实时监控 pod CPU 以及内存。目前不会去监控网络吞吐,所以我们也会搭一个 heapster+influxdb+grafana 开源架构在里面,去收集我们想要的信息,去对比算法版本更新的时候会否导致 CPU 的运行效率下降和内存变多,但是因为任务量比较多,所以存储的数据会比较大。
下面有个 kubelet10250 端口的参数,我们之前碰到一次,刚刚创建集群的时候,在安全组上面太粗心大意了,没有把计算结点 10250 端口封掉,导致会被人家入侵,因为它开启了 enable-debugging-handlers=true 的情况下,外部可以直接通过这个端口,到 pod 里面进行集群调试,我们发现有人通过扫描机器,在上面跑了一些外挂程序。大家使用的时候稍微注意一下,官方已经有一个 PR 在里面。
日管理依赖腾讯云,对接了 Kafka 和 ELK,不详细说了。前面是腾讯云的容器服务实践,遇到了一些痛点。腾讯云容器发展得还是比较快的,但是它也不可能覆盖所有的应用场景,通过我们和它的合作,一是满足业务的需求,一是可以推进它更好的做一些比较少见的服务,例如高性能计算,在这方面可以完善得更好。
未来规划
下面是我们对未来的一些规划。我们也比较关注云容器实例服务,这已经在 K8s TKE 层面上再推进了一步,集群的主结点创建和弹性伸缩都不需要管理了直接通过腾讯云这个接口提交相应的任务,上面就可以跑起来了。所以这方面落地更加方便一些,serverless lambda 大家也比较了解,在高性能应用中也会使用到,一些比较小的排位任务,可能是一分钟的任务,但是它有几百万量级的东西,就可以通过 serverless lambda 来实现。完善的作业工作流管理刚才在架构图中也提到过,对于一些复杂的预测流程,任务之间有严重的依赖关系。例如这个图中,job2、job3、job4 是依赖 job1 的输出文件作为输入文件,后面的 job5、job6 也是依赖前面文件的。如果中间有一个任务出错了,在开发的过程中可以重走这个工作流去,节省到前面几个任务的计算流程直接到 job6,继续往上面走,继续修复以及类似的循环这样去做。
作者介绍:
林帅康,晶泰科技云计算平台技术总监,2015 年加入晶泰科技,主要负责晶泰科技高性能计算平台(majorana)的研发工作,专注于在公有云上通过 mesos/k8s 构建大规模的容器化高性能科学计算平台,以实现高效,低成本,灵活的云上超算系统。
本文转载自公众号云加社区(ID:QcloudCommunity)。
原文链接:
https://mp.weixin.qq.com/s/cR3WoVYU9nKoMiqX3eC4mA
评论