全量容器化:腾讯云日志服务CLS的云原生破局之道
腾讯云日志服务(Cloud Log Service,CLS)是腾讯云全自研的一站式、高可靠、高性能日志数据解决方案。支持各种数据源 PB 级的数据接入,提供日志采集、存储、检索、统计分析、数据加工、消费订阅等能力,可以帮助客户大大降低日志运维门槛,并解决业务数据处理的各种诉求。
CLS 产品能力概览
由于日志和业务属性关联强,业务的高低峰也会直接导致日志量的高低峰,所以与单个业务相比,日志服务的流量洪峰波动状况更加频繁,也更加不可预估,可能瞬间就有几十万 QPS、GB/s 日志写入;日志数据应用场景也更加敏感,大量客户会直接基于日志配置告警、监控等实时性要求强的场景,就要求日志从产生到可检索出来的延迟一定秒级,更精确的来说要在 3s 以下,不然此时日志的价值将大打折扣。
此外,CLS 在商业化初期,产品迭代非常快,日志量从每天几千万条增长到十万亿条级别,拥有百亿级数据秒级检索分析能力。新增客户的需求多且复杂,技术架构和基础设施陈旧,在应对规模增长、性能要求、迭代需求等多方面压力下,整个服务稳定性不足,研发团队也频于救火,甚至影响客户口碑、影响收入,这也是为什么我们必须要在技术上实现彻底的改造和升级。
云原生技术对于我们而言究竟意味着什么,这里总结出“三个代表”:
云原生代表着最先进技术生产力的发展方向:云原生技术(容器、K8S、Serverless 等)都是如今基础设施先进生产力的代名词,技术成熟且被广泛应用;相反,如果基础设施 / 技术理念还保持陈旧思路,那必然无法满足当今业务需求,也会成为企业 / 产品发展的阻碍。
云原生代表着技术企业产品竞争力的发展要求:爆炸式的扩张和增长已成为当今新产品和新应用的典型特征,因此产品的研发、测试、发布、交付、运维效率就直接决定了产品迭代周期,研效的提升一定程度上决定了我们的产品是否可以在关键时刻做到“快人一步”。
云原生代表着企业降本增效的技术保障:企业内独立的资源池、资源 Buffer 会导致业务之间严重的“贫富差距”,资源弹性能力差、低效使用直接影响企业运营成本;此外,企业内不同团队的技术栈、架构和重复造“轮子”也会导致研发成本居高不下。
所以,在如今想要实现应用的现代化,云原生技术改造已经成为企业发展的必然选择。
对日志服务 CLS 而言,在架构上面临的每一个问题都能决定产品最终的成败,例如基础设施混乱、应突发能力差、性能和稳定性差、服务治理困难以及资源浪费严重,运营成本高等。
CLS 在 21 年绝大部分资源都还是物理机和虚拟机,这会带来一系列问题。
首先是资源环境复杂,无论是机型差异、内核版本还是系统参数等,都会在某个不经意的时间点导致同样版本的应用行为不一致,对资源上线和维护的要求非常高。
物理机以及虚拟机扩容耗时又是另一个大问题,从提出资源需求到资源到位有时候需要几个小时甚至几天,导致业务侧不得不提前囤资源,但即使囤积 20% 的资源对于业务也是一块不小的成本;其他基础设施的混乱,例如本地 IDC 和云上管理运维系统不匹配,监控告警以及观测能力不一致等,成为传统应用面临的最痛点。
基础设施的发展也经历了从物理机 - 虚拟机 - 容器的演进:
服务器:一个服务器里面运行多个业务进程,服务器为物理机或虚拟机,正常每个业务进程是独立的,也存在单个服务多进程的模式。
富容器:富容器是企业打包业务应用、实现业务容器化过程中,采用的一种容器模式。在业务容器化过程比较受欢迎,因为类似服务器模式,业务无需大的改造成本,也不会对开发和运维造成任何侵入性。一个容器运行多个进程,容器运行时内部自动运行 systemd 等进程作为 1 号进程,然后自动将业务进程和其他辅助进程拉起。公司内部有 Tlinux 镜像,支持业务使用富容器。
Sidecar 容器:容器内部只有一个业务进程。容器内的 1 号进程就是业务进程,一个应用可以由一个或多个容器组成,他们彼此独立,可以单独升级。
富容器优点在于基本不改变业务代码和运维代码情况下,快速从 CVM 迁移到容器;但本质上是服务器模式到容器的过渡,没有从根本上改变应用的管理模式,只是把底层介质从服务器转变为容器。
但随着容器技术的发展,这种模式逐渐消失,更多的还是回到容器本质,一个容器一个进程的模式。随着 K8S 成为容器编排的事实标准,这种模式更符合云原生的技术要求,也成为当前容器化的标准范式。
云原生改造过程中,业务无法规避的问题是如何对有状态应用和无状态应用容器化,CLS 在实践过程的经验是:尽量实现全部应用为无状态应用。
无状态代表应用随意横向扩容、宕机甚至随时随地被删除,对服务本身都不会有影响,以此提供高并发的服务能力和更高的容灾能力。
有状态和无状态相比:
有状态本身需要保存状态或用户会话,这一定程度上就增加了处理的复杂性,而无状态则不需要存储任何信息;
有状态中一个请求只能被一个实例处理,无状态中任何请求可以被任何实例处理;
与无状态应用相比,有状态应用更加复杂,扩展更难;
有状态对于故障的容忍度低,有时候需要迁移和同步数据;而无状态应用则不需要,这也是为什么我们期望,最好服务不存在有状态的应用。
传统业务大多都是有状态的应用,那我们应该如何去改造应用架构呢?
常见的可以通过两种方式将服务从有状态转变为(近)无状态的服务:
实现多个实例可以互相同步数据,任何一个实例异常都是对等的,可以容忍任意删除和扩容;
实现数据集中存储,将状态信息转变为存储,实例只需从集中存储拉取数据到本地缓存即可。
云原生改造过程会有一个新的问题是,在复杂的云原生应用程序中管理配置信息是非常困难的,似乎到处都有配置。在使用基于微服务架构的云原生应用程序中,配置问题会成倍增加。有针对网络的配置,比如路由规则、端口控制、负载均衡;有针对数据库的配置,服务器的配置,还有众多微服务中间件的配置。这些配置大多是零散存储,并且缺乏管理的。
所以首先要为所有配置统一可信来源,统一配置管理,或者叫配置中心。
此外,配置有些时候会被复制到各处。将一台服务器中使用的配置复制到另一台服务器,然后再复制到另一台服务器。最终,可能会有数百个相同或几乎相同的配置副本。
所以配置的版本管理就非常重要,保留对配置的所有更改的历史记录;进行更改时,可以记录更改人和更改原因。
随着时间的推移,配置会发生漂移,导致配置错误、应用程序故障甚至安全漏洞。其实每个副本的配置其实不尽相同,每个配置副本都需要进行小的更改,就需要定义变量并自动以完全相同的方式维护类似的配置文件,且不会在每次使用配置时发生变化漂移。
这就要求我们要能进行自动化的配置管理,使用 CI/CD 管道是现代云原生应用程序的标准策略,部署管道应部署所有配置以及所有代码。这可以实现变量的一致应用和对宏的更改,并确保所有更改都部署在需要配置的所有组件中。
为了实现这种升级,我们需要改造老服务兼容新的配置模式,因此我们要解决另一个问题,就是如何平滑升级?
架构升级对业务无感知是我们追求的最终目标,要求我们要具备平滑的升级流程、可靠的灰度策略以及完善的可观测能力。
我们的过程很清晰:
金丝雀模式:从小地域、部分客户开始切换,逐步灰度完成全部流量的切换;
过程:老服务保持不变,新服务切换完成后仍旧保留 2 周,后续再下线;
风险:风险极小,出现问题可随时切回;
在升级之前我们需要做好很多工作,包括新老服务的兼容,方便随时回滚切换;也包括升级预案的准备,以及我们如何验证切换到新服务。
实现弹性服务,就离不开弹性伸缩能力的建设。我们面临 3 大主要场景的问题:首先是突增流量我们如何应对?提前扩资源势必会导致大量的资源浪费;第二个是扩容资源量上来后,什么时候缩容呢?不缩容造成资源浪费,缩容得快又怕来回抖动;最后一个是周期性的流量如何保护链路更加稳定?
在业务场景,我们首先需要实现的是应对突发流量,解决了这个痛点后,我们才会考虑降低成本,成本有了保障后,我们才会进一步考虑如何让我们的服务更稳定。所以,从这几种场景我们可以总结弹性伸缩的“应突发、降成本、保稳定”的 3 步走策略:
应突发: 利用 HPA 实现在正常水位之外的突增流量自动弹性扩容,保证服务质量;
降成本: 利用 HPA 实现节省成本并且能够应对突发;
保稳定: 能够感知服务链路上下游同步扩缩,以及用户自定义指标弹性伸缩。
在实际的策略应用过程,我们还需要关注扩容和缩容的技巧:
快扩容:尽快扩容出来 Pod 来承担增长的流量;
慢缩容:CPU 使用率短时间波动较大,缩容速度如果过快,很有可能导致缩容后利用率上升又需要扩容。
践行这样的策略和原则,弹性伸缩就能发挥最大的价值。
日志服务其实是非常多业务的集合,同时面临对外和对内两方面的风险治理。
因此,CLS 设计了全链路接入和流量治理能力,可以应对每一个已知场景的问题:包括客户端本地缓存、退避重试、异常上报实现端到端的观测能力,接入链路实现基于泛域名的 DNS 隔离、限流、限频、隔离拉黑等,可以应对异常上报和攻击等;内部首先全弹性能力接入,实际场景可以实现分钟级扩容上万核心资源,针对依赖系统的容灾降级以及最终的兜底恢复。
最后但也是最重要的问题:系统的可观测能力。
被动发现问题:问题发现依赖客户反馈,发现问题就是工单或故障;
故障持续时长过长:发现问题过晚,故障可能已经持续了很久,影响大;
故障范围未知:很难给客户及时反馈故障影响范围以及恢复速度和预期;
频于救火:研发团队苦,经常半夜和节假日处理故障,产品稳定差,导致业务口碑差,丢单风险大。
应用的可观测其实已经超越了我们使用的监控和告警本身,需要从用户视角、应用本身、中间件系统、基础设施等多方面进行数据收集和分析,实现从代码到用户的端到端可观测能力建设,包括监控大盘、业务分析、链路追踪和智能运维等,实现统一的应用可观测能力。
研效的提升主要有两点:
CI 流水线的建设:我们现网有非常多的工单和问题,工单处理在某半年成为负担最重的任务,基于问题的自动化用例建设每次发布都回归历史问题,为了在短时间内将工单快速收敛,CLS 建设了 1000+ 用例,保障版本迭代的兼容性和稳定性;也包括代码分析、单元测试覆盖率等门禁。
应用的发布编排:云服务产品有几十个地域,发布任务之前每周需要投入 2-3 个人力,基于应用的编排在效率的提升非常明显,也减少了人工犯错的概率。
经过上述一系列云原生改造,最终日志服务 CLS 实现的全自研架构目标:围绕云原生技术(容器、K8S、声明式 API、弹性伸缩等),建设符合现代应用和数字化业务的发展需求架构。
整个架构演进花费了近 1 年的时间,经历了三个比较大的阶段,实现了从 0 到 95% 以上应用的容器化,运营成本节省 2 千万 +/ 年,减少 2+HC,节省了 10 万 + 核的资源,同时扩缩容耗时降低 90%,资源利用率提升 40%+。
同时日志服务 CLS 产品稳定性可达 99.99%+,拥有适应客户场景 PB 级突发流量的弹性接入能力;作为平台级云服务,自身的云原生改造也进一步助力客户数字化升级的快速迭代和价值交付。
上海站圆满结束,深圳站精彩继续。7 月 21-22 日,我们将继续在深圳举办ArchSummit 全球架构师峰会,会议主题还是会围绕数字化,架构思维,和架构师成长来展开。如果你想要分享演讲话题,可以在这里提交议题思路:https://jinshuju.net/f/7wUiwn 点击阅读原文了解详情
微信扫码关注该文公众号作者