专栏名称: IT大咖说
大咖干货,不再错过。 让不在大会现场的程序猿、攻城狮也能体验现场的精彩瞬间。
目录
相关文章推荐
AIbase基地  ·  最好的 Manus 复刻项目?GAIA ... ·  昨天  
AIbase基地  ·  最好的 Manus 复刻项目?GAIA ... ·  昨天  
融云攻防实验室  ·  漏洞预警 绿盟 SAS堡垒机 chgxxx ... ·  昨天  
融云攻防实验室  ·  漏洞预警 绿盟 SAS堡垒机 chgxxx ... ·  昨天  
福州新闻网  ·  华为,突传消息! ·  2 天前  
福州新闻网  ·  华为,突传消息! ·  2 天前  
四川政法声音  ·  这15款App被通报!谨慎下载使用! ·  2 天前  
四川政法声音  ·  这15款App被通报!谨慎下载使用! ·  2 天前  
51好读  ›  专栏  ›  IT大咖说

kubernetes在腾讯游戏的应用实践

IT大咖说  · 公众号  · 科技自媒体  · 2017-07-10 21:24

正文


内容来源: 本文转自数人云公众号(dmesos)。

摘要


腾讯游戏 是国内最大的 网络游戏 社区, 致力为游戏玩家提供完整的快乐解决方案。腾讯互娱高级工程师黄惠波通过一些实际场景为大 家解析kubernetes在腾讯游戏中的应用实践。


腾讯在线游戏的容器化应用场景


2014年,我们开启了容器化探索之路,先回顾一下之前遇到的一些问题。


在物理机时代,资源的交付时间较长,资源的利用率较低,也不能做到隔离。到了xen\kvm虚拟机时代,问题得到了初步的解决,但在弹性伸缩方面仍有不足。 随着Docker技术的兴起,我们开始调研Docker在游戏容器化方面的应用。我们的目标有两个,一是提高资源利用率,二是通过Docker镜像来标准化部署流程。


选择Docker技术之后,我们开始了容器调度平台的 选型。 我们当时也调研了其它的一些组件,比如Shipyard、Fig等,但这些组件无法支撑海量游戏容器调度。而自建调度平台的话,时间成本非常的高。就在那时,Google开源了kubernetes(当时的版本是 kubernetes v 0.4),我们基于这个版本进行了定制和开发,使其成为我们游戏容器的调度管理平台。



在2015年初的时候, TDocker 平台上线。之后,我们开始逐步接入业务。一开始的模式非常简单,就是把Docker当成虚拟机来使用,但这不意味着游戏全容器化的实现。


大家知道,对于一项新技术来说,大家都很谨慎,会通过不断的灰度上线,由点到面的策略推动。截至目前,在全国各地以及加拿大等地区,都有我们的部署点;接入容器数超过两万,接入的业务也有两百多款,包括手游、端游、页游。在这么多的业务中,主要分为两种场景,第一种场景是轻量级虚拟机模式,这类容器承载多个服务进程,需要一个具体的内网IP,可以通稿SSH登录。另一种是微服务化模式,这种模式会拆分得非常细,每一个容器对应一个服务进程,不需要对外可见的内网IP,可以使用虚拟IP。


接下来会对每一个场景做一些分享。首先来看一下传统游戏下的架构。这是非常典型的三层服务架构,包括了接入层、逻辑层、数据库层。同时,游戏又分为:全区全服、分区分服两种类型。对于分区分服类游戏,滚服对资源的调度非常频繁,所以我们需要一个高效的调度平台。



容器资源的调度管理基于kubernetes v0.4版本,上图是一个简化后的调度框架。在Master端包括ApiServer和Scheduler,接收Web请求,然后做资源调度。在每个node节点上,包括agent进程、Docker进程,还有Lxcfs进程。在镜像存储方面,当时用的是Registry V1版,后端用的是ceph存储。 现在,我们自己维护了一个分支,功能上已满足当前的游戏需求,并保证运行的稳定。所以在虚拟机模式下,我们不会升级kubernetes,而是把一些好用的功能合并进来。


基于Kubernetes的功能定制与优化



首先讲调度器,调度器为数以万计的容器提供了一个灵活、稳定、可靠的底层资源计算调度引擎。资源的合理分配像是一场博弈,里面有很多矛盾的地方,需要我们根据游戏的特点做取舍。



我们在原有的调度策略上根据游戏特点做了一些定制。 比如在网络方面,传统游戏的每个容器都需要一个对外可见的实体IP,用户可以通过SSH登录到容器里面,因此对网络资源进行调度。部署容器的时候,会申请network的资源(比如IP)然后进行划分,绑定到minions对象。这样调度器调度的时候,就可以通过这些配置信息给容器分配好网络资源。



在社区中,CPU的分配用的是共享CPU的方式,游戏采用的是一种混部的模式。也就是说,将不同游戏业务部署到同一台母机,采用绑定核的方式。这样做一方面可以防止不同游戏之间的CPU抢占,另一方面对游戏成本的核算也会更加精细。例如,某个游戏用了多少CPU这些指标都是可以量化的。在容器分配CPU时,结全numa技术,对于CPU CORE的分配会尽量地分配到同一个numa node上,这样可以提升性能,因为同个numa node的CPU访问只需通过自身的local memory,无需通过系统总线。



在磁盘容量分配方面,由于游戏业务是有状态的服务,需要存储,所以我们把磁盘也作为一个可调度的资源分配给容器。 还有非亲和性的调度。我们知道,在容器的可靠性与碎片优化之间需要一个权衡,让用户根据这些策略去选择、部署自己的容器。例如在非亲和性的策略中,用户希望把容器是分散到各个母机上的,在母机宕机时,可以减少对游戏的影响。



在IDC Module分配方面,游戏容器的部署会按地区划分,比如按照上海、深圳或天津地区的IDC来划分,所以我们提供了IDC部署策略。由于游戏需要考虑IDC的穿越流量问题,还有网络延时的问题,所以同一个游戏的的不同模块一般会部署到同一个IDC Module下面。


海量应用过程中遇到的问题与解决方案




以上是基于游戏行业特点定制的调度规划。在资源调度过程中,也遇到过一些问题,例如容器资源的重复调度。首先在调度过程中它会跟ScheduledPod(已完全调度的容器)进行比较,判断现在是不是有足够的资源分配给待调度容器,最后通过Bind(异步)把Pod信息写入到ETCD。这里就会出现一个问题,那就是异步写入慢了或者ScheduledPod同步慢了导致ScheduledPods不能及时刷新,Scheduler计算出错,从而造成资源重复计算。针对这个问题,我们的解决方案是在资源调度完成后,做一个检测的逻辑,检测调度的容器信息是否已在ScheduledPod Cache这里,然后再进入下一个容器的调度。当然这会带来一定的性能损耗。


解决了这个问题,又产生了另外一些问题,那就是性能的问题。在0.4版本的 pod接口 是非常低效的,在查每一个pod状态的时候,会通过实时查所有的Host来确定,设计不太合理。社区也做了一些方案,当时我们也是参考了社区的一些方案做了一些改造,把pod状态放在Cache里面,定时更新,从而提高查询效率。



还有一点就是RESTClient。在kubernetes中,rest API大部分是异步进行,对于这些异步的接口的请求,并不会立刻返回结果。这里有一个轮询检测状态的逻辑,在检测轮询的时候有几秒的休眠,然后进再行下一个轮询。默认的休眠时间是2秒,这个时间对大部分场景来说有点过长,我们通过一些功能点的调整,从物理机的小时级到虚拟机分钟级的调度,再到还未调整之前的秒级调度,到现在达到的毫秒级调度,现在的调度能力已能满足游戏的需求。


讲完调度,再看一下网络方面。网络是非常关键、也是最为复杂的一环。 在虚拟机模式下,结合公司网络环境为游戏提供高性能、稳定的网络环境,包括Bridge+VLAN\SR-IOV两种方案。



先来说,Docker的网络还有kubernetes的网络。对于Docker的NAT网络来说,性能是最大的瓶颈,同时它与物理机或虚拟机的通信路径不一致也会对业务带来一些未知的影响。比如,外界不能看到容器真实的IP(必须要使用主机IP+port方式,端口本身就是稀缺资源,并且ip+port的方式,无疑增加了复杂度),TGW仍然可以为业务程序服务。Host模式没有隔离,也不符合需求。在kubernetes中,pod作为最小调度单元,每个pod有两个容器,一个就是网络容器,接管pod的网络,提供网络服务,并与其它容器共享net\IPC。另一个是App Container,也就是业务容器,使用第一个网络容器的网络。在这种模式下,容器之间的通讯是非常简单的。对于pod到pod、pod到物理机、物理机到pod的通讯,我们为每个pod分配一个内网IP,对外可见,也可以互相通讯。



接下来,通过两个方案给大家分析。首先是Bridge+Vlan的方案,母机都是部署在虚拟化区上,通过Vlan做网络的隔离。在母机上架部署时,创建Bridge设备和VLAN设备并将它们进行关联。创建容器的时候,使用pipework脚本创建容器所需要的虚拟网卡设备,并把它们绑定到容器和Bridge上,同时会设置容器内的IP、MAC地址以及路由等信息。从而打通容器到外界的网络通信。这里也做了一些优化以提高性能,这里可以看到一个性能的对比,其中Bridge相对NAT网络有相当大的提升。这种方式可以满足一部分游戏的需求,而有一些业务,像FPS、Moba游戏等大流量,对网络要求非常高的业务,还有类似MySQL-Proxy这种组件,在Bridge场景下是无法满足需求的。


所以我们探索了另一种网络方式,就是SR-IOV模式,这种模式在zen\kvm虚拟化上用的比较多,游戏也需要这种网络方案,因此我们把这种网络方案也结合到Docker容器里面。



这里需要硬件的支持,结合 SR-IOV 技术的网卡,在Docker容器内就可以直接通过驱动来加载虚拟的网卡并使用。使用的方式就如同在一台物理机上使用一个真实的物理网卡一样,这个虚拟网卡也拥有驱动程序,也拥有PCI BUSID,因此所有的虚拟机网络操作都如同操作普通网卡一般,从而在性能上得到提升。为了进一步发挥SR-IOV的网络性能,还需要对容器的相关网络参数进行配置,主要包括以下几个方面:VF中断CPU绑定;关闭物理机的irqbalance;容器内设置RPS(软中断均衡)网卡不能中断均衡,对高性能的网络形成了阻碍。为了解决这个问题,需要设置容器内的软中断均衡。通过上述的调整,性能得到了大幅度提升。







请到「今天看啥」查看全文