导语:K8S是基于容器的集群管理系统,容器有比较多的选择,其中DOCKER作为容器,目前在业界使用比较广泛,我们IEG也大量的使用了DOCKER。跟随IEG游戏的出海,基于IEG游戏出海服务环境和当前业务的需求特点,我们尝试将部分营销应用使用K8S来做管理,效果还不错。本文主要讨论我们在系统选型、架构改造、实际运营上遇到的问题以及解决方案。借机感谢公司内各个平台在日常工作上对游戏营销这块的支持。因业务的实际应用场景存在很多可变性,我们在K8S的使用过程中,做了不少打通和变更的事情,具体的应用还需要看实际的业务场景,实际的方案应以解决业务的实际需求为主。欢迎大家留言指正,互相交流。^_^
文章来源:IEG增值服务部-技术藏经阁
序:K8S简介:
K8S,是Kubernetes(舵手)的简称,是Google在2014年6月开源的一个基于容器技术的分布式集群管理系统。后google捐赠给Cloud Native Computing Foundation(现属Linux基金会)来使用。
K8S使用Go语言开发(目前在我们部门使用GO语言比较普遍,通过蜘蛛支持业务信息、流程、版本、分发的管理),主要用于管理云平台中多个主机上的容器化后的应用,其核心目标是促进容器化的应用方便快捷、快速响应部署,提供跨主机集群的自动部署、扩展以及运行应用程序容器的平台。其中K8S提供了资源调度、部署管理、服务发现、扩容缩容、监控,维护等一系列的功能。它支持一系列容器工具, 包括Docker等。
简言之:K8S是一个基于容器技术的分布式服务系统,自动化部署、伸缩和操作应用程序容器的开源平台。
- K8S GitHub: https://github.com/kubernetes
- K8S 官方站点: https://kubernetes.io/cn/
- K8S 中文社区: https://www.kubernetes.org.cn/meetup
K8S GitHub:
容器的优势:
- 较容易构成 持续的开发、集成,部署:基于镜像的不可变性,可快速转移,开发,上线部署。
- 可转移性强:可在 Ubuntu、RH、CentOS、各种虚拟平台、Google 容器引擎,其它各类平台上运行。作为开发或者测试,可以快速的在个人电脑或者笔记本上安装容器(往往因为程序本身依赖权限的问题,在我们公司在笔记本上重现容器,作用不大)。
- 较好的资源调度:提供了统一硬件资源解耦,更灵活的调度使用
一图展示容器:
K8S的优势:
- 好迁移:各种基于Liunx的系统,公有云、私有云、混合云、多态云等
- 扩展性:模块化、插件化、可挂载、可组合
- 自修复:自动部署、自动重启、自动复制、自动伸缩
腾讯云k8s服务实践
一、背景
在互娱业务中,有众多的内容为业务提供服务。潘多拉为游戏提供了专业的营销解决方案,原生体验植入游戏,精准地向游戏玩家推送营销服务,从活跃、留存、收入等多维度助力游戏运营(更多特性可以参见https://gcloud.qq.com/increment/pandora)。近年来潘多拉以其原生UI体验、便捷的热更新能力、灵活的配置发布功能得到越来越多游戏研发、运营的认可,现已应用于腾讯40余款游戏。下图为潘多拉在游戏内的应用形态。
营销活动的整体解决方案和电商平台类似,有着大量秒杀类的业务场景,跟随者刺激战场、王者 、飞车手游等游戏出海,我们的营销活动也跟随着出海。对比国内环境,海外资源使用上跟国内有不小的差异,国内运营体系照搬海外,存在不小的差异。在实际海外业务服务过程中,使用到了各种非IDC资源,如各种云资源。大部分云资源的成本都高于国内的成本,综合考虑各种因素。在海外业务支撑上,我们对海外资源存在跟国内一样的弹性扩容的管理,在某些类似秒杀,访问量毛刺化比较严重的高pv的营销活动中,弹性的管理尤为重要。
本文主要介绍了我们使用腾讯云的k8s服务的经验,以及传统业务迁移改造到容器平台所踩的坑。
二、现状
我们所负责的王者荣耀海外版的潘多拉模块成功迁移至腾讯云K8S集群,打通蜘蛛平台(营销活动项目管理平台)和腾讯云k8s接口,在不改变开发同学营销项目开发流程习惯前提下实现代码发布更新迭代等流程。截止目前稳定运行近半年。
三、平台对比选型过程
在腾讯云使用容器集群可以有3种途径
(1). 腾讯云容器服务
https://cloud.tencent.com/document/product/457/
简单地说就是在腾讯云购买虚拟机(CVM),加入腾讯云的K8s托管云,支持容器编排,支持大部分常见的K8S功能,需要预先购置虚拟机。
(2). 腾讯云容器实例服务
https://cloud.tencent.com/document/product/858
直接购买腾讯云官方K8S集群生产的容器(DOCKER),相当于买了容器当虚拟机用,不支持容器编排,不需要预先购置虚拟机,成本最低。实际使用请参看腾讯云官网文档。
以上两种服务容易混淆,简单的说,腾讯云容器服务是在腾讯云上购买虚拟机,在上面部署腾讯云k8s系统,生产的容器也仅跑在所购买的虚拟机上,类似于传统idc上托管物理机的概念,资源是独享的。腾讯云容器实例服务在腾讯云k8s购买容器使用,存在和其他用户共享资源的现象,相对于托管物理机,你可以把它理解成购买公有云的虚拟机这个概念。
(3). 购买虚拟机搭建自定义集群
有能力管理好K8s或者想体验完整的K8s功能的可以选择购买虚拟机自己搭建,更有利于拓展和理解整体结构。
为了验证可行性以及测试压测数据,我们从腾讯云购买了4台标准的centos7,搭建单主多从集群,使用kubeasz的AllinOne部署。
性能测试对比,压测数据
选取相同配置,3个环境外加虚拟机用unixbench跑个分,尽享保证硬件平台一致性。
环境 | 虚拟机 | 自建k8s环境 | 腾讯云容器实例 | 腾讯云容器服务 |
---|---|---|---|---|
分数 | 841 | 646 | 1173 | 1268 |
后两者的分数比前者高的原因是因为cgroup 隔离做的不好造成的。这4种平台的实例在性能上并无大的差别。详细跑分报告在附件
四 、系统架构
(1). 镜像里面集成了我们部门在海外的一些基本组件,比如海外的L5(腾讯内部使用的名字服务负载均衡系统) ,海外的tnm2 agent。
为了降低国内代码迁移到海外的难度,我们部门开发了L5的海外版本。容器镜像里面安装了l5agent,测试结果如下:
此外,我们还开发了海外版本的tnm2,使得国内代码可以无缝迁移过来。
(2). 打通我们的蜘蛛系统和腾讯云镜像仓库接口,原来 下发文件=》重启程序 的流程变成编译镜像=》上传腾讯云仓库=》更新容器。对于开发而言,操作过程不变。
配置项通过蜘蛛系统接口注入容器环境变量中。
注入之后再系统环境变量可以读取到
(3). 以往我们的配置文件都是采用文件下发的,在本案例中,我们将原本下发到机器的配置文件上传至腾讯云对象存储,改造程序去从腾讯云对象存储拉取配置文件并于本地缓存。
考虑到安全性,建议:
- 程序访问对象存储时候使用独立的 密钥,该密钥设置成仅仅能访问对象存储,无其他资源权限,降低密钥丢失带来的损失;
- 对象存储存储桶设置为私有读写;
- 考虑到容器调用腾讯云对象存储实用的是公网连接,因此建议加上本地缓存。
(4). 日志采集。原本打算采用容器前端打印log=》腾讯云的kafka=》腾讯云的Elasticsearch的一条龙服务,但是因为腾讯云部分节点还没上线kafka服务,最终采用的是蓝鲸的数据平台来采集日志。
蓝鲸的日志平台需要设置采集的日志的目录,我这边采用的方式是在docker母机上安装蓝鲸agent。在母机上找到容器挂载点的方式去进行日志上报。
腾讯云默认使用overlay2的文件存储驱动。
如图可以看到一个 overlay被联合挂载到了 /var/lib/docker/overlay2/303ce271aea8196201ffb80bfd0fa4e34a6509574efd1c8059e5cc9833578f68/merged
也就是容器的根目录。蓝鲸这边支持文件路径的通配设置
/var/lib/docker/overlay2//merged/data/log/nginx/.log
使用以上设置可以采集到该母机下的所有容器内/data/log/nginx/*.log的文件内容
以上的措施大大降低了开发同学将传统应用迁移到容器云的改造成本。
五 、经验心得
(1). 深入理解docker的哲学:开箱即用,用完立刻抛弃。
在docker的世界里,程序如果需要更新的话是通过重新编译新的镜像并发布的的方式,而不是去更新已有容器实例里面的文件的方式去实现,需要持久化的存储尽量不要与容器板内部落地。
(2). 充分利用按量付费
代码语言:txt复制按量付费是指按照实际使用时间来计算腾讯云资源的账单,如果不使用则不收费。营销活动有区别于游戏服务器的特殊性,往往峰谷差别更为明显,并且有一定规律性。
以上为为某营销活动的访问量截图,可以看到每天晚上某个整点有一笔比平时增大3倍的量。我这边采用的方法是,每天提前20分钟自动购买n台机器加入集群,并增加容器副本数,在30分钟之后左右降低副本数,并将购买的实例退还。综上每天支付的费用仅仅是n*1小时的服务器租赁费用。
(3). 监控
在开源的k8s监控prometheus、蓝鲸、海外tnm 3种方案,我们采用的方案是
基础数据监控 日志采集搜集采用蓝鲸平台, 业务数据上报采用海外tnm2接口,需要在容器里面安装海外tnm2的agent。
实际效果如下
(4)、镜像版本控制
默认情况下,腾讯云只能存放100个版本的镜像,并且不会自动删除老的
到达到配额之后,会报错
需要人为的设置一下镜像的自动滚动滚动机制。
我们这边用打包时间作为版本控制的索引
(5)、版本迭代
k8s支持滚动更新,也就是自动的一台机器流量掉零,等完全没有流量再杀死容器,启动新的镜像。以上功能我们实际运用下来 基本满足无状态短链接的无损发布需求
详细功能可以参考 k8s 官网
https://kubernetes.io/zh/docs/tasks/run-application/rolling-update-replication-controller/
(6)、操作系统选择
项目初期使用的是标准的最小化安装的centos7镜像,后期更换为tlinux2.2镜像,
镜像大小为2.2g,因为docker镜像采用增量发布方式,故只会在第一次发布的时候上传整个镜像。另外以上镜像原生是为了idc内网设计,需要一定的定制化才能在海外腾讯云环境使用。
(7)、自动扩容.在腾讯云上设置了根据cpu使用率来自动调节容器副本数
以上设置表示:在10-20个容器数量中,尽可能保持总cpu使用率为为70%。
举例:当我有14台机器,平均cpu使用率为50的时候。设置以上规则,会导致系统自动调配实例数量到 14*50/70=10。
实际使用
我们可以看到当活动发布后,cpu使用率由50迅速飙升到90,触发了扩容的阈值,当系统扩容之后,cpu使用率开始下降,当低于阈值之后会停止扩容。
实际上我们使用的规则是比较复杂,还需要根据业务实际情况进行调整。
几个注意事项:
- 必须为容器设置 CPU Request;
- 策略指标目标设置要合理,如设置 70% 给容器和应用,预留 30% 的余量;
- 保持 Pod 和 Node 健康(避免 Pod 频繁重建);
- 保证用户请求的是负载均衡,而不是直接请求容器ip;
- 在计算目标副本数时会有一个 10% 的波动因子,如果在波动范围内,并不会调整副本数目;
- 如果服务对应的deployment.spec.replicas值为0,弹性伸缩将不起作用;
六 、小结
通过整个项目的实施我感到k8s混淆了运维和开发的边界。
传统模式下:开发只负责写代码,不关心系统架构,网络架构 ;运维只负责将开发的代码部署上去。
在k8s的环境中:开发要熟悉整个环境的架构,使得自己的代码去司陪环境,运维也要关心代码原理,甚至参与一部分的代码修改。