PaaS容器集群优化之路
1. 性能优化面对的挑战
以下是整个PaaS平台的架构
其中主要包括这些子系统:
- 微服务治理框架:为应用提供自动注册、发现、治理、隔离、调用分析等一系列分布式/微服务治理能力,屏蔽分布式系统的复杂度。 
- 应用调度与资源管理框架:打通从应用建模、编排部署到资源调度、弹性伸缩、监控自愈的生命周期管理自动化。 
- 应用开发流水线框架:打通从编写代码提交到自动编译打包、持续集成、自动部署上线的一系列CI/CD全流程自动化。 
- 云中间件服务:应用云化所需的数据库、大数据、通信和应用中间件服务;通过服务集成管控可集成传统非云化的中间件能力。 
面对一个如此复杂的系统,性能优化工作是一个非常艰巨的挑战,这里有这么一些痛点:
- 源代码及开发组件多,100+ git repo,整体构建超过1天 
- 运行架构复杂,全套安装完需要30+VM,200+进程 
- 软件栈深,网络平面复杂 
- 集群规模大,5k — 10k节点环境搭建非常困难 
- 系统操作会经过分布式的多个组件,无法通过单一组件诊断发现系统瓶颈 
- 无法追踪上千个处于不同层次的API的时延和吞吐 
- 大部分开发人员专注于功能开发,无法意识到自己的代码可能造成性能问题 
2. 优化分析
那么,对于这么一个大的、复杂的系统,从方法论的角度来讲,应该怎么去优化呢?基本思路就是做拆分,把一个大的问题分解为多个互相不耦合的维度,进行各个击破。从大的维度来讲,一个PaaS容器集群,可以分为3个大的子系统。
- 控制子系统:控制指令的下发和运行(k8s),例如创建pod 
- 业务流量子系统:容器网络(flannel)、负载均衡(ELB/kube-proxy) 
- 监控子系统:监控告警数据的采集(kafka, Hadoop) 
这个看起来仅仅是一个架构上的划分,那么如何和具体的业务场景对应起来呢?我们可以考虑如下一个场景,在PaaS平台上大批量的部署应用。看看在部署应用的过程中,会对各个子系统产生什么压力。
- 应用软件包大小:400M 
- 应用模板大小:10M 
- 1000个节点,每个节点一个POD,一个实例 
- 10种类型的软件包,依赖长度为3,10GB 网络 
- 调度及资源管理 3VM 
这是一个典型的部署应用的一些规格,那么对于这样的一个输入,我们可以按照架构把压力分解到每个子系统上,这样得出的子系统需要支撑的指标是:
- 控制子系统: kubernetes调度速度 > 50 pods/s,仓库支持300并发下载,>40M/s 
- 数据子系统:overlay容器网络TCP收发性能损耗 <5% 
- 监控子系统:在上面这个场景中不涉及,但可以从别的场景大致告警处理能力100条/秒 
这里的业务场景:架构分析:子系统指标,这三者是m:1:n的,也就是说在不同场景下对不同的组件的性能要求不同,最后每个组件需要取自己指标的最大值。
指标决定了后续怎么进行实验测试,而测试是要花较大时间成本的,所以在指标的选取上要求少求精,尽量力图用2-3个指标衡量子系统。
3. 优化测试 & 工具
上面讲的还是偏纸上的推演和分析,接下来进入实战阶段

对于服务器后端的程序来讲,推荐使用Promtheus这个工具来做指标的定义和采集。Promtheus的基本工作原理是:后端程序引入Promtheus的SDK,自定义所有需要的测量的指标,然后开启一个http的页面,定期刷新数据。Promtheus服务器会定期抓取这个页面上的数据,并存在内部的时间序列数据库内。这种抓而非推的方式减少了对被测试程序的压力,避免了被测程序要频繁往外发送大量数据,导致自身性能反而变差而导致测量不准确。Promtheus支持这几种数据类型:
- 计数(对应收集器初始化方法NewCounter、NewCounterFunc、NewCounterVec,单一数值,数值一直递增,适合请求数量统计等) 
- 测量(对应收集器初始化方法NewGauge、NewGaugeFunc、NewGaugeVec,单一数值,数值增减变动,适合CPU、Mem等的统计) 
- 直方图测量(对应收集器初始化方法NewHistogram、NewHistogramVec,比较适合时长等的统计) 
- 概要测量(对应收集器初始化方法NewSummary、NewSummaryVec,比较适合请求时延等的统计) 
我们可以看看在kubernetes项目里面是怎么用的:
var ( // TODO(a-robinson): Add unit tests for the handling of these metrics once // the upstream library supports it. requestCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "apiserver_request_count", Help: "Counter of apiserver requests broken out for each verb, API resource, client, and HTTP response contentType and code.", }, []string{"verb", "resource", "client", "contentType", "code"}, ) requestLatencies = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "apiserver_request_latencies", Help: "Response latency distribution in microseconds for each verb, resource and client.", // Use buckets ranging from 125 ms to 8 seconds. Buckets: prometheus.ExponentialBuckets(125000, 2.0, 7), }, []string{"verb", "resource"}, ) requestLatenciesSummary = prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "apiserver_request_latencies_summary", Help: "Response latency summary in microseconds for each verb and resource.",// Make the sliding window of 1h. MaxAge: time.Hour, }, []string{"verb", "resource"}, ) )
在这里,一个http请求被分为verb, resource, client, contentType, code这五个维度,那么后面在PromDash上就能图形化的画出这些请求的数量。 从而分析哪种类型的请求是最多,对系统造成最大压力的,如图

除了Promtheus,还可以引入其他的测量手段,对系统进行分析。

- 在kubernetes调度过程中,各个状态Pod的数量,看哪一步是最卡的 

- go pprof分析,哪些函数是最耗CPU的 
4. 优化开发
发现了瓶颈之后,下一步就是解决瓶颈,和具体业务逻辑有关,本文在这里就不做过多的阐释。需要对相关代码非常熟悉,在不改变功能的情况下增强性能,基本思路为并发/缓存/去除无用步骤等。
5. 优化成果
这是我们在kubernetes项目上控制面优化的成果
| 控制面指标 | 华为分支数据 | 社区版数据 | 
|---|---|---|
| Master节点数量 | 5 | 无明确数据 | 
| Node节点(kubemark模拟)数量 | 10000节点 | 5000节点 | 
| 部署吞吐率 | >100 pod/s | 约为50 pod/s | 
| Pod端到端延时 | <2s | <5s | 
| API延时 | <79.321ms | <1s | 
这里仅仅显示了控制子系统的指标,其他子系统还没有支持那么大的集群,尤其在网络方面,不同用户的网络架构差别很大。所以数据仅供参考。
6. 优化的优化
在上面的优化过程当中,基本上工程师要做几百次优化的测试和开发。这里会产生一个循环:
- 测试寻找瓶颈点 
- 修改代码突破这个瓶颈点 
- 重新测试验证这段代码是否有效,是否需要改优化思路 
这就是一个完整的优化的迭代过程,在这个过程当中,大部分时间被浪费在构建代码、搭建环境、输出报告上。开发人员真正思考和写代码的时间比较短。为了解决这个问题,就需要做很多自动化的工作。在kubernetes优化的过程中,有这么几项方法可以节省时间:

- kubemark模拟器 :社区项目,使用容器模拟虚拟机,在测试中模拟比达到1:20,也就是一台虚拟机可以模拟20台虚拟机对apiserver产生的压力。在测试过程当中,我们使用了500台虚拟机,模拟了10000节点的控制面行为。 
- CI集成:提交PR后自动拉性能优化分支并开始快速构建 
- CD集成:使用I层的快照机制,快速搭建集群并执行测试案例输出测试报告 
以上都是在实践过程中总结的一些点,对于不同的项目工程应该有很多点可以做进一步的优化,提升迭代效率。
在搭建完这套系统后,我们发现这个系统可以从源头上预防降低系统性能的代码合入主线。如果一项特性代码造成了性能下降,在CI的过程当中,功能开发者就能收到性能报告,这样开发者就能自助式的去查找自己代码的性能问题所在,减少性能工程师的介入。
PaaS容器集群优化之路的更多相关文章
- 测试环境docker化—容器集群编排实践
		本文来自网易云社区 作者:孙婷婷 背景 在前文<测试环境docker化-基于ndp部署模式的docker基础镜像制作>中已经详述了docker镜像制作及模块部署的过程,按照上述做法已可以搭 ... 
- Kubernetes容器集群管理环境 - Prometheus监控篇
		一.Prometheus介绍之前已经详细介绍了Kubernetes集群部署篇,今天这里重点说下Kubernetes监控方案-Prometheus+Grafana.Prometheus(普罗米修斯)是一 ... 
- Kubernetes容器集群管理环境 - 完整部署(上篇)
		Kubernetes(通常称为"K8S")是Google开源的容器集群管理系统.其设计目标是在主机集群之间提供一个能够自动化部署.可拓展.应用容器可运营的平台.Kubernetes ... 
- Kubernetes容器集群管理环境 - 完整部署(下篇)
		在前一篇文章中详细介绍了Kubernetes容器集群管理环境 - 完整部署(中篇),这里继续记录下Kubernetes集群插件等部署过程: 十一.Kubernetes集群插件 插件是Kubernete ... 
- 重磅!容器集群监控利器 阿里云Prometheus 正式免费公测
		Prometheus 作为容器生态下集群监控的首选方案,是一套开源的系统监控报警框架.它启发于 Google 的 borgmon 监控系统,并于 2015 年正式发布.2016 年,Prometheu ... 
- Kubernetes——容器集群
		kuberneteskubernetes(k8s)是google的容器集群管理系统,在docker的基础之上,为容器化的应用提供部署运行.资源调度.服务发现和动态伸缩等一系列完整的功能,提高了大规模容 ... 
- 打造云原生大型分布式监控系统(四): Kvass+Thanos 监控超大规模容器集群
		概述 继上一篇 Thanos 部署与实践 发布半年多之后,随着技术的发展,本系列又迎来了一次更新.本文将介绍如何结合 Kvass 与 Thanos,来更好的实现大规模容器集群场景下的监控. 有 Tha ... 
- vivo 容器集群监控系统架构与实践
		vivo 互联网服务器团队-YuanPeng 一.概述 从容器技术的推广以及 Kubernetes成为容器调度管理领域的事实标准开始,云原生的理念和技术架构体系逐渐在生产环境中得到了越来越广泛的应用实 ... 
- (转帖)开源容器集群管理系统Kubernetes架构及组件介绍
		最近在搞Docker还有她的管理工具,选型Kuberetes后,被她的术语和概念搞得晕头转向...看了一篇文章还不错,放到这里分享出来. 地址:http://www.linuxidc.com/Linu ... 
随机推荐
- iOS技术面试01:多线程与网络
			1. 多线程的底层实现? 1> 首先搞清楚什么是线程.什么是多线程.多线程的使用场合(线程有时被称为轻量级进程,是程序执行流的最小单元.多线程是指软件或者硬件实现多个线程并发执行的技术.多线程的 ... 
- 【c# 学习笔记】委托链的使用
			委托链其实就是委托类型,只是委托链把多个委托链接在一起而已,也就是说,我们把链接了多个方法的委托称为委托链或多路广播委托.如下: public delegate void DelegateTest() ... 
- Rhino脚本引擎技术介绍
			引用:http://p.primeton.com/articles/54c1e255be20aa4735000001 http://blog.csdn.net/u013292493/article/d ... 
- 【转帖】循序渐进Oracle:数据库的字符集和字符集文件
			循序渐进Oracle:数据库的字符集和字符集文件 https://blog.csdn.net/Enmotech/article/details/100869162 2019年09月15日 18:23: ... 
- 20191011-构建我们公司自己的自动化接口测试框架-testrun最重要的模块
			testrun模块呢就是最终自动化测试入口,调用前面封装的各个模块主要流程是: 1. 获取测试集种待执行的测试用例 2. 处理测试用例获取的数据,包括转换数据格式,处理数据的中的关联等 3. 处理完数 ... 
- 关于arm 的字节对齐
			一.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这 ... 
- MySQL AND 和 OR 联合使用带来的坑
			MySQL 基础篇 三范式 MySQL 军规 MySQL 配置 MySQL 用户管理和权限设置 MySQL 常用函数介绍 MySQL 字段类型介绍 MySQL 多列排序 MySQL 行转列 列转行 M ... 
- hdu 2647 还是逆向拓扑
			Problem Description Dandelion's uncle is a boss of a factory. As the spring festival is coming , he ... 
- CCF 201712-1 最小差值
			题目: 问题描述 给定n个数,请找出其中相差(差的绝对值)最小的两个数,输出它们的差值的绝对值. 输入格式 输入第一行包含一个整数n. 第二行包含n个正整数,相邻整数之间使用一个空格分隔. 输出格式 ... 
- 七、Flex 布局
			布局的传统解决方案,基于盒状模型,依赖 display 属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. 2009年,W3C 提出了一种新 ... 
