标签:适配 互联网 网络资源 tag 地址匹配 gitlab 端口冲突 定制 情况下
Kubernetes实战——谈谈微博应对春晚等突发峰值流量的经验导读:本文由Kubernetes在微博落地的具体工作整理而成。通过围绕业务需求和大家分享下企业内部如何使用Kubernetes来解决具体的业务问题和相应的方案。文中分享了基于Kubernetes的PaaS层弹性混合部署方案,其中有Kubernetes的优点,也有部分Kubernetes在企业落地的缺陷,欢迎大家一起讨论和建设Kubernetes。希望本文对大家有一定的借鉴意义。
彭涛,主要负责微博容器平台的开发工作。Kubernetes代码贡献者。曾就职于百度基础架构部,百度公有云事业部。长期从事云计算行业。熟悉网络虚拟化,SDN,OpenStack,Kubernetes。致力于推动Kubernetes在微博的应用落地,构建高效的PaaS平台
王琨,微博平台高级产品运维工程师,主要负责微博feed、用户关系、架构业务的运维支撑及改造工作。擅长大规模分布式系统集群的管理与运维,疑难问题分析,故障定位与处理。致力于推进运维自动化,构建微博平台高效的运维平台。
一、微博容器平台
2016年微博平台实现基于混合云的弹性平台DCP,提升了Feed、手机微博、广告、搜索、话题、视频、直播等多个核心业务热点应对能力。2017年微博平台率先探索基于Kubernetes的PAAS层弹性混合部署解决方案,并且积极的和社区保持同步。2018年实现CI/CD与生产环境混合部署,2019年春晚实现部分核心业务混合部署与弹性伸缩。
本文主要介绍微博平台落地Kubernetes过程中的一些经验教训。
二、为什么选择Kubernetes
因为历史原因,微博docker容器治理是采用独占物理机(虚拟机)模式,直接使用物理机的网络协议栈,服务治理采用服务池方式。随着设备计算能力的提升,这种治理方式有几个问题急需解决:
Kubernetes提供标准化的容器管理,CNI网络虚拟化,自定义弹性调度策略,能够很好的解决上述问题。但是Kubernetes面向公有PAAS的实现方案在内网环境下有些方面不适用,主要有如下几个方面:
我们基于Kubernetes搭建了一套PaaS平台,对Kubernetes进行了改进,提供了以下功能:
三、整体方案
图一
整体方案如图一,微博容器平台划分出如下几层:
三、容器弹性化扩缩容平台建设
微博容器弹性扩缩容平台,是在Kubernetes基础上进行了改进,充分利用了微博平台已有的资源。避免重复造轮子。具体的工作如下:
3.1 基础建设之网络虚拟化
之前已经说过了,微博的容器会独占物理机的网络协议栈,虽然能够做到网络效率的最大化,但是会导致多容器部署时出现端口冲突。为了解决端口冲突需要使用虚拟化网络技术提供容器独立的IP地址。多个容器独立IP需要解决以下的三个问题:
第一个问题因为采用Kubernetes IP分配都是通过记录在etcd中,所以不会出现分配重复或者分配错误的问题,而第二个问题社区里面通常会采用隧道类型方案和BGP方案。以下是隧道模式和BGP模式的优缺点对比如表一, 性能测试如表二(BGP主要工作是路由交换,转发等不受影响,等同于物理机性能。)
表一
表二
在测试结果中显示vxlan因为需要封装和解封隧道导致带宽损耗过5%,所以隧道方案不适用于内网的网络环境。而BGP的方案Calico会引入iptables去做ACL,不仅在业务峰值流量的情况下会触发nf_conntrack表被打满丢包的风险。而且BGP方案在公有云和内网落地的时候也存在问题:
公有云方面:
内网方面:
图二
微博虚拟网络主要是四方面内容:
图二左侧是简化后的内网网络拓扑,容器的虚拟网卡通过MacVlan与物理网卡的网卡子接口相连,发出的报文会带上网卡子接口的Vlantag,而这部分的流量上到上联交换机之后就和物理机发出的没有任何区别,之后的都是交换机和网关去解决掉路由的问题。这个方案的设计对现有的环境依赖最小。同时改动量少。实现机房物理网络与容器网络的扁平化,解决了容器网络和物理网络互联互通的问题,由于没有隧道解封性能问题。性能基本上持平物理机性能。 本质上这是一个私有云的网络解决方案,但是很好的解决了问题。
图二右侧是简化后的公有云网络拓扑,通过把物理机上的网卡迁移到容器里面来间接的实现多IP。由于是虚拟机的弹性网卡,等同于虚拟机上的物理网卡,性能没有问题。
3.1.1 虚拟网络后续的演近
对Calico进行改进取消iptables依赖。利用Calico去解决内网网络方案中ip浪费的问题。同时可以对Calico做进一步的研究,如动态迁移容器如何保持ip漂移。
3.2 基础建设之调度管理
容器调度,其实是为了提高资源利用率,同时减少资源碎片化。Kubernetes的调度策略做的相对灵活,对Pod的调度通过三个阶段来实现,初筛阶段用于筛选出符合基本要求的物理机节点,优选阶段用于得到在初筛的节点里面根据策略来完成选择最优节点。在优选完毕之后,还有一个绑定过程,用于把Pod和物理机进行绑定,锁定机器上的资源。这三步完成之后,位于节点上的kubelet才能开始真正的创建Pod。在实际的接入过程中,Kubernetes的基础调度策略不能满足平台的业务需求,主要有如下两点:
3.2.1 整体方案
图三
整体的调度管理分成如下几层:
3.2.2 调度管理之接口层
锁定库存接口层的逻辑:
释放库存接口层的逻辑:
3.2.3 调度管理
图四
初筛层:对上述的cache部分里面的Node节点进行CPU,内存,硬盘和带宽的初步筛选,返回通过筛选的所有物理机节点。
优选层:对上述的物理机节点信息进行打分,对节点进行排序。然后根据请求所需部署的容器数量,按照物理机节点的进行模拟部署(挑选物理机按照分数从高到低排列),直到全部节点上可部署容器数量为0,统计每个节点能部署的容器个数。
部署策略层:根据请求参数的不同(目前只支持集中/平铺),锁定物理机上的IP地址(调用kubernetes的API 把物理机上虚拟IP的label置为Using状态),并且返回这些IP地址。
3.2.6 整体流程图
图五
3.2.7 后续演进
支持调度优先级,且能根据实际的资源使用情况进行调度而不是Kubernetes预分配的资源进行调度。
3.3 基础建设之资源隔离
Kubernetes支持CPU、内存的隔离。在宿主机层面支持驱逐模式。通过虚拟化网络的方案,主容器网络和混部容器的网络分割开来。整体的资源隔离目标是为了隔离开主容器和混部容器对资源的使用。以下是我们做的一些改进。
计算资源隔离
存储资源隔离
网络资源隔离
3.3.1 后续的演进
资源隔离的后续方向很多,首先要解决的是Kubernetes如何能动态设置资源阈值。其后需要能够设置内存OOM优先级,以及满足资源超卖的需求
3.4 基础建设之CI/CD
平台于2018年基于gitlab开发了CI/CD,通过CI/CD和Kubernetes的配合来完成从代码提交到上线的完整流程,其中使用Kubernetes的上线流程(如Deployment)的滚动发布存在着容器IP不固定,动态化的问题。是因为Kubernetes的设计原则中对集群的管理尤其是服务升级过程中需要保持“无损”升级(升级过程中提供服务的副本数一直符合预期)。如果对一个Deployment进行滚动升级,那么这个Deployment里面的IP地址和滚动升级之前的IP地址是不会相同的。而如果集群够大,一次滚动发布就会导致负载均衡变更 (集群副本数/滚动发布步长)次。对于微博服务来说,频繁变更会导致这个负载均衡辖下,所以后端实例的接口不稳定。
而平台内部的之前的上线系统是根据业务冗余度及业务实际需要来调整上线的步长,减少在上线过程中业务的抖动,也就是通常说的In-place rolling updates。保证在上线过程中容器的IP不变。
整体流程的核心思路为:
针对该问题,容器平台没有使用Kubernetes的原生滚动发布而是做了以下几个改进和适配:
主要流程有
图六
由于给机器打好了虚拟IP标签,所以Pod的创建会被分配给固定的物理机去执行,配合修改之后的CNI就能创建指定新tag+固定IP的Pod来提供服务。滚动发布和回滚变成了删除Pod,创建Pod的固定化操作。
3.5 基础建设之模块化运维
由于之前的容器是独占物理机的模式,所以对于容器的运维也是在物理机上进行的,一些功能如日志处理、域名解析、时钟同步、运维Agent管理以及定时任务等都是在物理机层面操作。如果开始多容器混合部署,以上的功能都兼容改动工作量大。再加上平台面向的业务方众多,需求各不相同。例如日志推送的方式已经出现scribe、flume、filebeat等不同的方式,业务运维需要根据自身去定制运维容器,由此可见模块化运维的必要性。我们基于Kubernetes的Pod概念做了如下的工作,整体架构见图七。
图七
3.5.1 模块化运维之定时任务
物理机上的定时任务以来于crontab,而crontab会由systemd来启动。在容器中使用systemd启动会涉及到提权问题,在实践过程中发现用systemd如果权限控制不当会造成容器被Kill的情况,所以单独开发了兼容linux crontab语法的定时任务工具-gorun,把这个工具集成在了运维容器里面,替代了crontab来完成定时任务。
3.1.5.2 模块化运维之日志处理
日志的处理主要包括监控采集、日志推送、日志查询、日志压缩清理四方面:
图八
通过上述手段,能够利用现有的日志体系,同时开发的工作量最小,通过这样的操作,以后的容器想要接入,只需要在Pod的配置文件里面多写一个container的配置即可。
3.5.3 后续的演进
后续的运维容器将会进一步的拆分,做成标准化的服务,例如域名解析容器,日志推送容器。让业务的接入变得更加的容易。
3.6 基础建设之弹性扩缩容
弹性伸缩在微博的应用很广,作为支持了全公司春晚扩容的DCP系统其主要能力就是进行IAAS层虚拟机的弹性伸缩。是对业务进行保障的重要手段之一。弹性扩缩容保证在峰值流量来临时通过扩容提高接口的可用性,在业务量级下降后回收资源节省了成本,而PaaS层的扩缩容比IaaS层的扩缩容更具有优势,一来是因为PaaS的启动更轻,没有虚拟机的初始化阶段。所以启动更快,二来是因为我们的弹性调度系统能提前锁定IP,可以做到业务容器和变更Nginx同步进行。所以在PaaS层的弹性扩缩容,我们目前做到了如下几点工作:
定时扩缩容是复用了DCP系统的定时扩缩容功能,并做了一定的适配,目前可以选择使用原生扩容模式(IaaS层)和Kubernetes扩容模式。选择好了模式之后需要填的就是Pod的调度参数和本身Pod的标准化json文件,之后就是常规功能。
自动化扩缩容的实现,是基于CI/CD系统中的放量系统完成的,CI/CD会在上线过程中有单机放量的步骤,其中会采集放量容器的监控数据,业务数据和日志数据。横向对比当前服务池的整体接口耗时和纵向对比历史七天内单机的接口耗时。通过这套系统,把相关的阈值指标导出之后,集成到监控系统中,如果判断接口的QPS和耗时产生了恶化,会相应的触发扩容操作,不同于IaaS层的扩容,PaaS的扩容在存量机器上是免费的的。例如前端某接口的QPS过高,处理不过来了可以在机器学习服务池的机器上进行容器扩缩容去先扛住量。
3.1.7 基础建设之负载均衡
微博平台的7层负载均衡方案是使用Nginx。目前仍使用的是静态文件的进行路由信息管理,nginx变更系统实现了一套动态的解决方案,将upstream与对应的服务池进行关联,确保对应的接口由对应的服务池来提供服务,当服务池内有节点变更时,自动触发配置下发进行nginx的变更。
Kubernetes从最开始的Service上就开始了负载均衡和服务发现的尝试,例如在Service上利用Iptables进行请求的随机负载(问题在于后端某个实例的压力已经很高了,由于是iptables的硬负载不能感知到,依然把请求传递过来)。而且和网络虚拟化一样引入Iptables会有nf_conntrack打满的风险,考虑到公司内部的已经有成熟的负载均衡系统,这块进行了一个适配。
由于弹性调度的功能,我们会在创建Pod之前就可以锁定的IP地址。当IP地址锁定后,我们可以同步的变更我们的负载均衡系统+启动我们的业务容器。能够更快的响应业务请求(见图九)。
图九
3.8 基础建设之监控系统
监控和日志都是平台内部成熟的组件,通过模块化运维中日志信息的采集推送,监控数据采集推送已经兼容原有方式推送到监控平台。而物理机监控已经通过运维物理机部署Agent来采集,不需要重新引入别的工具去完成。整体的监控总共有如下的几个部分:
图十
图十一
基础平台的建设不限于上述的部分,还做了鉴权,DNS优化等相关服务。限于篇幅不便展开,于此同时微博平台Kubernetes也在积极的与社区保持迭代,争取做到能回馈社区。
四、业务落地
2019年春晚期间,后端服务支持红包飞业务,如果按照传统方式需要近百台的公有云设备按需成本。我们通过把垂直业务从大容器中抽离形成微服务,利用Kubernetes PaaS整合能力,在未增加资源成本的情况下完成春晚红包飞保障。
目前有6大服务池接入Kubernetes PaaS,共管理数千核CPU,数TB内存的计算资源。通过Kubernetes整合闲散资源与合理的混合部署,可提供近整体的30%的弹性伸缩能力。
综上,是微博平台在探索Kubernetes与业务更好结合道路上的一些体会,实际业务接入过程中依然会有很多的挑战。但是在团队成员的努力下,最终实现了方案的落地并保障了春晚的线上业务的稳定。通过这次的平台建设充分体会到只有和业务结合,并且服务好业务才能更好的促进自身架构的成长,很多时候看似很完美的方案,面对真实的业务需求还是会出现纰漏。我们会吸取历史的教训,总结经验。争取利用先进的技术来为公司创造更大的价值。
五、展望未来
未来我们将长期运行混合部署的微服务架构,优化调度系统,对接更多的IAAS层提供商。更进一步提高接口可用性和资源利用率,也会对服务的稳定性和资源的利用率做进一步探索,利用技术提升研发效率也是我们后续的方向。在探索的同时我们也会对ServiceMesh、Serverless持续关注,结合着业务需求,更进一步优化容器基础平台。
相关阅读:
转载本文请注明出处,技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。
Kubernetes实战——谈谈微博应对春晚等突发峰值流量的经验
标签:适配 互联网 网络资源 tag 地址匹配 gitlab 端口冲突 定制 情况下
原文地址:https://blog.51cto.com/14977574/2546666