5

Kubernetes与游戏架构搭建(GKE搭建游戏实操)

 2 years ago
source link: https://my.oschina.net/u/4763244/blog/5280281
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【本文内容基于9月份Cloud Ace CTO 江文远分享的线上研讨会内容整理而成。】

摘要

Kubernetes,简称K8s,是Google开发的,目前最为流行的容器编排和管理引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。K8s的特性使得它适用于架构复杂且要求高的服务,也就是游戏架构的搭建。

由于Cloud Ace为谷歌云代理公司,所以我们本次分享的实操是在谷歌开发的Google Kubernetes Engines上运行的,GKE是谷歌基于K8s所开发的Kubernetes管理平台,主要在谷歌云平台上运行。

Kubernetes与微服务架构

随着应用的发展,程序变得越来越复杂,传统一体化架构的服务会造成巨大的不便,比如说:新增功能与测试放在一起,使得程序十分复杂;开发和利用新语言和新框架的效率低;安全性低,所有的模块构建在一个process里,一旦出现bug可能牵一发而动全身。

而微服务 (microservices) 架构正好解决了这样的问题,将每一个具有商业逻辑的服务独立出来,例如不再将所有资料都写入同一个资料库,而是每个单独的服务都有一个最适合自己本身结构的资料库。好处是让每个服务都可以用最适合自己的语言、资料库来开发。在实操时,每一个商业功能/服务都可能是一台 VM 或者一个容器。

微服务架构的出现给了游戏一个新的选择,下图的两个架构就是游戏使用的架构,都是通过不同的功能模块来划分的,按功能模块划分不同的服务,前端通过HAProxy来代理用户请求,后端服务可以根据负载来实现扩缩容。在服务发现模块中,通过registrator来监视容器的启动和停止,根据容器暴露的端口和环境变量自动注册服务,后端存储使用了consul,结合consul-template来发现服务的变化时,可以更新业务配置,并重载。

v2-46434598d3429dad15b32faaa3d7042e_720w.jpg

游戏的微服务架构示例

K8s就是微服务架构

v2-cc69ea1583c2de9b07dd408b732f1212_720w.jpg

前面提到K8s适合微服务架构,为什么呢?

因为k8s的架构与微服务十分相似,在某些功能上是一致的,第一就是k8s的master和node,可以实现不同功能不同服务器之间的隔离;第二是k8s上面提供了API server,基本上可以等同于网关;第三是k8s的服务编排性能好,可以实现弹性伸缩;第四点是k8s的configmap基本上可以作为配置中心;第五是k8s可以通过在node上部署agent来实现日志的收集和监控。

Kubernetes 将数个容器组合起来成一个服务(Service,注:Service 是 K8S 的专有名词,下面会介绍),Kubernetes 也提供了良好的服务发现(Service discovery)机制,让每个服务彼此可以通信。最重要的是 K8S 强大的编程可以自动扩展服务,甚至还可以对大规模的容器作滚动更新 (Rolling update) 以及回滚机制 (Rolling back/Undo),更可以整合 CI/CD 等 DevOps 的工具。

K8s在游戏架构搭建上的优势

基于前两者,我们总结出来K8s在游戏架构搭建上的优势为:

  1. 定制的网络与调度方案,为游戏容器的运行提供基础环境;
  2. 域名服务与负载均衡,解决游戏高可用、弹性伸缩问题;
  3. 通过性能数据、日志的收集、统计分析,及时发现程序问题与性能瓶颈,保证游戏容器稳定、可持续性运行;
  4. 基于image的发布扩容,使得游戏部署流程更加标准化以及高效。

v2-ec7ad33955bd2d7845aafac95540a3db_720w.jpg

Google Kubernetes Engine(GKE)游戏架构搭建实操

我们的实操参考的是谷歌的技术文档来搭建的。

游戏:Open Arena(雷神之锤)---开源游戏

游戏架构如下图,今天我们只讲关于dedicated game server这一部分。

v2-b66b49372c5309250e418ab1de03c556_720w.jpg

游戏环境设定如下:

v2-afdfd087c1e46f17ffc830af88869b10_720w.jpg

游戏设定1

v2-f2865c987f46716614201515adff35ca_720w.jpg

游戏设定2

为什么这么设置呢?

第一是处于占用资源上考虑,如果是地图比较大的游戏,打开地图就会需要比较长的时间去载入,同样的,你时间越长需要载入的资料越多,占用越多的资源,因此大部分游戏都会定义时间限制,因为一旦有玩家在玩,主机就无法关闭,造成大量的资源浪费。

第二点是出于成本控制上设置的,因为线上游戏需要弹性,高峰期和非高峰期的人数差异较大,因此需要尽可能的match更多地玩家进来,把玩家集中在一个服务器上玩,这样对vm的需求会比较少,有利于成本控制。

第三点是考虑到游戏技术上的难度,如果说玩家出现问题掉线了,那么就直接重开游戏,不要恢复它的状态,因为恢复状态对技术要求非常高。

GKE搭建后台示例如下:

v2-3bbc9dcb3e73382e5c339640c28444d8_720w.jpg

首先我们先从右上角开始,右上角就是一个基本的游戏的组成,DGS也就是delicate game server ,它是一个open source的套件,可以在GKE上运行。

这里涉及到两个VM,第一个VM用来搭建image,第二个VM用于加载数据/资料片,也就是Asset Disk,我们把Asset Disk挂起来后,VM2我们就直接删掉,VM2是不会留下来的,我们只要留下Disk就可以,之后一旦GKE的class开起来,也就是把gke-dgs image部署出来,部署出来之后,这边就他会去把资料片挂起来。

在K8s上的话,有个点需要注意,如果pod想用到disk里面的资料,那么disk需要做成PV,也就是群集中的资源。PVC是对这些资源的请求,只有用户请求后发送了PVC才能访问存储的资料片。

一轮游戏一个回合,能够允许的玩家是有一定限制的,如果说node上有两个pod,两个pod能够允许20个人玩,那么当玩家数量超过了20个人的时候,就需要系统及时监控到这个情况,开新的pod,这里就涉及到了scaling manager。

Scaling manager翻译过来叫缩放管理器,它其实就是不断的在监控整个class里的每一个node的状态。在k8s里面有个功能叫HPA,Horizontal Pod Autoscaler,HPA可以实现 Pod自动弹性伸缩,HPA是怎么实现自动弹性伸缩的呢?是通过对Pod中运行的容器各项指标(CPU占用、内存占用、网络请求量)的检测,实现对Pod实例个数的动态新增和减少。

但是这里会产生一个问题,比如一个游戏回合,因为会设定游戏时间,因此可能玩家都退出了,但是游戏可能还在进行。HPA这里检测到的依然是游戏占用了很多资源,所以会认定pod不能关掉,但是玩家其实都退出了。这里涉及到了一些底层的监控和运算公式在里面,相对比较复杂。所以在实际的操作过程种,工程师需要去设置监控和弹性缩放的逻辑和算法。

游戏服务器经常会碰到的问题就是如何实现自动扩展和缩放,这里我们总结了一下:

v2-7819c1ef43d450b8317d59915ddc91b0_720w.jpg

v2-77f8394a24e3c9ca68fd26591f78a2a2_720w.jpg

v2-fa7a75f8b55db9b7a632c0b3bd4f4824_720w.jpg

重点讲一下cordon指令,cordon指令是什么意思呢?就是说pod在缩放的时候,如果确定某个node的玩家都退出了,要把 node撤掉的时候,要标记为不可调度。因为GKE的规则是,只要今天有玩家进来玩,scaling manager就会自动分配pod给他。如果我们想删减node,可是scaling manager发现 node的上面没有任何的pod在跑,它就会自动在这个我们想删减的node上面开pod给玩家,就会发生冲突,因此如果我们要删除node,需要把它标记为不可调度。

当这两个程序如果之间没有做好沟通的话,一个在砍node,一个在加node的,或者是一个在砍pod,一个在部署pod,两个就会互相冲突,所以这边就是要注意,你要让想办法让另外一个程序知道说我这个node不要再用。

还有就是abandon instance,按照谷歌云的instance group原先的规定,比如我设定了node是20个,那么当我们缩减掉一个node的时候,instance group为了确保node数量满足20个,会自动增加新的node,这里也是冲突的,我们缩减一个node,它自动增加一个新的node,因此我们就需要通过abandon instance指令来缩减node。abandon instance命令下去之后, node会直接变少,不会增长。

以上就是我们本次分享的内容,这里附上qwiklab的链接,有需要的可以在qwiklab上进行游戏架构搭建的实操。

https://www.qwiklabs.com/focuses/617?catalog_rank=%7B%22rank%22%3A1%2C%22num_filters%22%3A0%2C%22has_search%22%3Atrue%7D&parent=catalog&search_id=9874060

11月4日Cloud Ace工程师将分享关于谷歌推出的Cloud Spanner——全球分布且强一致性的企业级数据库服务,欢迎各位报名参加。

v2-e39f10fb12bc687d2000accbe4847ee0_720w.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK