一、背景
在互娱业务中,有众多的内容为业务提供服务。潘多拉为游戏提供了专业的营销解决方案,原生体验植入游戏,精准地向游戏玩家推送营销服务,从活跃、留存、收入等多维度助力游戏运营。近年来潘多拉以其原生 UI 体验、便捷的热更新能力、灵活的配置发布功能得到越来越多游戏研发、运营的认可,现已应用于腾讯 40 余款游戏。
营销活动的整体解决方案和电商平台类似,有着大量秒杀类的业务场景,跟随者刺激战场、王者 、飞车手游等游戏出海,我们的营销活动也跟随着出海。对比国内环境,海外资源使用上跟国内有不小的差异,国内运营体系照搬海外,存在不小的差异。在实际海外业务服务过程中,使用到了各种非 IDC 资源,如各种云资源。大部分云资源的成本都高于国内的成本,综合考虑各种因素。在海外业务支撑上,我们对海外资源存在跟国内一样的弹性扩容的管理,在某些类似秒杀,访问量毛刺化比较严重的高 pv 的营销活动中,弹性的管理尤为重要。
本文主要介绍了我们使用腾讯云的 K8S 服务的经验,以及传统业务迁移改造到容器平台所踩的坑。
二、现状
我们所负责的王者荣耀海外版的潘多拉模块成功迁移至腾讯云 K8S 集群,打通蜘蛛平台(营销活动项目管理平台)和腾讯云 k8s 接口,在不改变开发同学营销项目开发流程习惯前提下实现代码发布更新迭代等流程。截止目前稳定运行近半年。
三、平台对比选型过程
在腾讯云使用容器集群可以有 3 种途径
(1). 腾讯云容器服务
简单地说就是在腾讯云购买虚拟机(CVM),加入腾讯云的 K8s 托管云,支持容器编排,支持大部分常见的 K8S 功能,需要预先购置虚拟机。
(2). 腾讯云容器实例服务
直接购买腾讯云官方 K8S 集群生产的容器(DOCKER),相当于买了容器当虚拟机用,不支持容器编排,不需要预先购置虚拟机,成本最低。实际使用请参看腾讯云官网文档。
以上两种服务容易混淆,简单的说,腾讯云容器服务是在腾讯云上购买虚拟机,在上面部署腾讯云 k8s 系统,生产的容器也仅跑在所购买的虚拟机上,类似于传统 idc 上托管物理机的概念,资源是独享的。腾讯云容器实例服务在腾讯云 k8s 购买容器使用,存在和其他用户共享资源的现象,相对于托管物理机,你可以把它理解成购买公有云的虚拟机这个概念。
(3). 购买虚拟机搭建自定义集群
有能力管理好 K8s 或者想体验完整的 K8s 功能的可以选择购买虚拟机自己搭建,更有利于拓展和理解整体结构。
为了验证可行性以及测试压测数据,我们从腾讯云购买了 4 台标准的 centos7,搭建单主多从集群,使用 kubeasz 的 AllinOne 部署。
性能测试对比,压测数据
选取相同配置,3 个环境外加虚拟机用 unixbench 跑个分,尽享保证硬件平台一致性。
后两者的分数比前者高的原因是因为 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). 充分利用按量付费
按量付费是指按照实际使用时间来计算腾讯云资源的账单,如果不使用则不收费。营销活动有区别于游戏服务器的特殊性,往往峰谷差别更为明显,并且有一定规律性。
以上为为某营销活动的访问量截图,可以看到每天晚上某个整点有一笔比平时增大 3 倍的量。我这边采用的方法是,每天提前 20 分钟自动购买 n 台机器加入集群,并增加容器副本数,在 30 分钟之后左右降低副本数,并将购买的实例退还。综上每天支付的费用仅仅是 n*1 小时的服务器租赁费用。
(3). 监控
在开源的 k8s 监控 prometheus、蓝鲸、海外 tnm 3 种方案,我们采用的方案是
基础数据监控+日志采集搜集采用蓝鲸平台, 业务数据上报采用海外 tnm2 接口,需要在容器里面安装海外 tnm2 的 agent。
实际效果如下
(4)、镜像版本控制
默认情况下,腾讯云只能存放 100 个版本的镜像,并且不会自动删除老的
到达到配额之后,会报错
需要人为的设置一下镜像的自动滚动滚动机制。
我们这边用打包时间作为版本控制的索引
(5)、版本迭代
k8s 支持滚动更新,也就是自动的一台机器流量掉零,等完全没有流量再杀死容器,启动新的镜像。以上功能我们实际运用下来 基本满足无状态短链接的无损发布需求
详细功能可以参考 k8s官网
(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 的环境中:开发要熟悉整个环境的架构,使得自己的代码去司陪环境,运维也要关心代码原理,甚至参与一部分的代码修改。
本文转载自公众号云加社区(ID:QcloudCommunity)。
原文链接:
https://mp.weixin.qq.com/s/KEb31PQdoi7rXYVPoMLFVw
评论