分享 | eBay TESS,我心中的那朵“云”
供稿 | eBay IE Cloud Team
作者 | 辛肖刚
编辑 | 顾欣怡本文8490字,预计阅读时间26分钟更多干货请关注“eBay技术荟”公众号导读
eBay是在全球领域最早开展电子商务的互联网公司之一,发展至今已有25年的历史。除了电商业务在不断进化,在技术领域也一直保持着前沿的积累。今天,我们有幸邀请eBay基础架构云开发经理辛肖刚,来讲述一下他在eBay的这五年里,对于TESS——新一代基于Kubernetes的基础架构云平台的一些感受,以及eBay在基础架构的发展和对未来的展望。
作者的话
Q1
eBay为什么要做TESS?
不忘初心,方得始终。
A1
不同的团队都要投资一部分工程力量在基础架构的维护上。 资源无法进行共享,难以达到更加优化的使用率。 不同云平台的API接口不一样,很难统一一个PaaS平台以简化上层应用的部署与维护。 在部署规模巨大的时候,经常遇到应用的状态跟期望的不一致。
为了解决这些问题,我们期望能塑造一个类似于漫威漫画中“空间宝石”(Space Stone)一样的平台,它能在刹那间移动,将自己或是所有物体随意移动到任何空间,它也可以按照用户的意志将空间任意扭曲或是重新排序,甚至是创造新的空间。我们希望新的云平台具有类似的能力,可以在任何时候根据用户对自己应用的期望对云上的应用进行重新排列。所以在项目之初,我们选择了TESS作为产品的名字,这个名字也蕴含了我们对这个产品Vision的神化定义:
Q2
为什么选择Kubernetes作为核心?
踏破铁鞋无觅处,得来全不费功夫。
A2
随着互联网行业的欣欣向荣,集所有功能于一身的单体应用已经无法满足如今互联网超高并发和超大规模用户的现状,分布式解决方案也让传统的单体应用更趋向于模块化。把单体应用拆成多个业务相对独立的模块化应用的过程即是微服务化。而容器天然对微服务友好,也造就了容器的快速繁荣。
Docker借此大势迅速在业界站稳脚跟,但是单一容器缺乏力挽狂澜之力量。一个高流量高可用的互联网应用的背后很可能是成千上万的容器部署,所以对于容器编排的需求无处不在。而Google绝对是这个领域的先行者,在2003年,一个约有 3-4 人、与新版的Google搜索引擎合作的小规模项目——Borg系统,在Google内部诞生。经过数年的发展,Borg成为了一个大规模的集群管理系统,它运行着来自数千个不同应用程序的数十万个作业,跨越许多集群,而每个集群拥有多达数万台计算机。Google在2015年已经达到了80多个数据中心,超过一百万台机器,其中大家所熟知的Search,YouTube,Maps,Gmail等产品,都是基于容器在运行。这些容器的数量是巨大的,官方称之为每周运行20亿个容器,而管理这些容器的系统就是Borg。Google于2014年推出了开源简化版的Borg:Kubernetes,把10年的沉淀推向社区。而eBay在那个时候正在寻找一个先进的容器云解决方案。当然在那个时候,社区也存在多种容器编排方案,比如,Docker Swarm,Mesos。经过一番比较与论证,我们最终选择Kubernetes作为我们的发展方向,是基于以下几点考虑:Kubernetes先进的应用描述语言 Kubernetes清晰的架构 轻量级的Golang 活跃的社区 Google的背书
01
传统云解决方案所遇到的难题
把应用直接跑在物理机上
把应用跑在虚拟机VM上
上层应用的灵活性受限。比如,用户想将应用从一个数据中心搬往另外一个,你必须先有跟之前配置一样的“机器”,再在上面部署你的应用。
底层Infrastructure的灵活性受限。比如,安全团队要求我们要给Hypervisor打补丁,我们为了对OS进行升级必须重启机器。在这种场景下,为了保证不影响正在承载业务流量的应用,我们需要询问应用团队在什么时间,以什么策略对底层OS进行升级重启。通常情况下,用户可能会说,我有紧急任务在跑,你不能动我的机器。也可能说,我给你一个API,在动我的机器的时候,你先询问我的API。这意味着做底层Infrastructure需要从语义(semantics)的角度理解应用的语言(API)。
给大家一个更加直观的例子吧。OpenStack云总共管理了2万多台Hypervisor,在eBay运行了数年之久了,迄今为止打一遍OS patching都相当困难。
02
The power of Kubernetes
应用程序启动效率(容器启动速度优势)
更加高效的CICD(容器打包部署优势) 应用程序迁移效率(一次打包随处运行) 物理资源的使用效率(没有虚拟化浪费)
为了更加合理地利用物理资源,我们想对应用进行重新排列以聚合或腾空资源,这很可能需要对应用进行跨集群,乃至跨可用区(availability zone)的迁移。
我们想实现在线业务和离线业务的混合部署,就意味着在在线业务流量回暖时迁走离线业务,而在非流量峰值时缩容在线业务给离线业务使用。
我们发现了Linux Kernel里的安全漏洞,需要在一个月内完成对10万台机器进行打补丁并重启。
我们的物理机每3年进行一次技术更新(tech refresh),需要逐步地对数据中心的机架(rack)进行下架处理。
我们发现了一个批次的机器有固件问题,需要升级固件甚至硬件,影响范围数以千计。
作为应用的owner,你该如何告诉Infrastructure你的应用当前是健康的,可以承载流量的?调用Infrastructure的API不是好的架构,应用的描述应该脱离Infrastructure而存在。
我们这里不详细描述整个Pod的生命周期,但是考虑一个场景。如果我们发现一台节点有些问题,比如raid卡在经过一段时间运行后会出现过热的情况,需要下架修理。而此时机器是正常运转的,你的应用可能正在处理一个重要的事务,你希望得到下架通知并做好进程退出之前的清理工作,我们应该用什么接口互相通讯呢?我们不可能要求应用开发者定期查询底层节点的状态。最好是应用开启一个接口来接收Infrastructure发来的通知。
Kubernetes提供了容器preStop钩子接口(回调函数),在Kubelet杀死容器之前会调用你所声明的preStop函数并进行阻塞式等待。应用程序就可以进行优雅地关闭。如果你没有声明preStop,你的应用就是这样被终止的:Kubernetes通知节点执行docker stop命令,docker会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认超时时间(30秒),就会继续发送SIGKILL的系统信号强行 kill 掉进程。使用preStop的应用终止流程则为:先同步执行preStop函数,函数退出或超时后Kubelet才会发送docker stop命令。Taint/Toleration起初是为特殊条件调度而设计的。在1.6之后使用场景进行了扩大,可以让应用有机会容忍底层的一些故障。
首先,在Infrastructure发生以下故障时,节点会被打上污点标签:node.kubernetes.io/not-ready,节点还没有准备好,对应节点状态Ready值为false。 node.kubernetes.io/unreachable,节点控制器无法触及节点,对应节点状态ready值为Unknown。 node.kubernetes.io/out-of-disk,磁盘空间不足。 node.kubernetes.io/memory-pressure,节点存在内存压力。 node.kubernetes.io/disk-pressure,节点磁盘存在压力。 node.kubernetes.io/network-unavailable,节点网络不可用。 node.kubernetes.io/unschedulable,节点不可被调度。
持有本地数据的有状态Pod,Pod的迁移也意味着数据的迁移,甚至rebalance。 任务类型的Pod,长时间任务被打断,需要重新执行任务。
作为应用,你可能会受到来自底层Infrastructure发起的中断(disruption),这些中断大致可以被分为两类:
Involuntary Disruption指的是那些不可控的(或者目前来说难于控制的)外界因素导致的Disruption,比如:服务器的硬件故障或者内核崩溃导致节点Down了。 如果容器部署在VM,VM被误删了或者Hypervisor出问题了。
集群出现了网络脑裂。
某个节点因为不合理的超配导致出现计算资源不足,触发kubelet eviction时也没有考虑到保证应用的高可用。
删除那些管理Pods的控制器,比如Deployment,RS,RC,StatefulSet。 触发应用的滚动更新。
直接批量删除Pods。
kubectl drain一个节点(节点下线、集群缩容)。
Q3
TESS现在走到哪里了,将要去向何方?
长风破浪会有时,直挂云帆济沧海。
A3
TESS从项目立项到现在已经走了快五年了。这五年其实是一个摸索的过程,因为除了Google,还没有哪家公司有过大规模容器云的构建经验,并且Kubernetes社区也一直在积极地迭代中。时至今日,Kubernetes社区也一直保持着每个季度都有新版本发布。
就个人体会来说,我想把TESS的发展比作以下三个阶段:“社会主义初级阶段”、“社会主义中高级阶段”,以及最终的“共产主义”。
01
“社会主义初级阶段”
应用类型覆盖广泛,说明容器可以在生产环境承载各种类型的应用。 TESS达到了承载生产流量的稳定性。
其他Domain团队用来管理自己应用生命周期的平台可以与TESS很好地对接。
如果从中国革命的角度来比喻的话,我想把现在的TESS称之为“社会主义初级阶段”。它的标志性意义在于从私有土地所有制到社会主义公有制的转变。也就是说,TESS作为eBay统一的基础架构云平台正在从各个Domain团队手里接管计算资源,并通过云的方式把资源作为服务提供给各个Domain团队。
02
“社会主义中高级阶段”
快速OS迭代能力(OS monthly patching) 全局流量拓扑管理(federated access point) 全局资源配额管理(account resource quota)
当然,单靠TESS团队一己之力很难达到上述的灵活性。我们需要Domain团队的配合,充分利用Kubernetes为大家提供的抽象接口,设计适合自己应用的配置来保证应用的高可用。只有获得了这种保证,底层Infrastructure才能有更强的信心来提高Infrastructure的效率。
03
“共产主义”
基于现有的资源管理模型,eBay的应用仍然很难有效地共享资源,因为资源配额是固定分配给用户的,而不是基于流量模型来优化的。真正的“共产主义”实现的是“按需分配”,而这里的“需”并不是人的意愿,而是从业务的角度产生的流量。只有当我们跨越“社会主义中高级阶段”达到应用层和Infrastructure层各自的灵活性,eBay才能最终走到Infrastructure使用的“共产主义”阶段。我把这个阶段称之为“那个美好的Infrastructure”。
Q4
怎么做TESS才能成功?
不积跬步,无以至千里。
A4
做基础架构(Infrastructure)不同于做应用,无法一蹴而就。因为Infrastructure这个领域的特点是东西很杂,很零散,并不是业务逻辑代码的堆砌。那么TESS怎么做才能有所成就呢?首先,我们应该知道如何去定义TESS能在eBay取得的成功。
01
如何定义成功:Scale + Reliability
TESS目前管理了5万台计算节点,最终要把整个eBay将近10万台计算节点全部管理起来。也就是说,eBay10万台节点的计算资源通过TESS统一的API对外提供基础架构服务。听起来是一个非常惊人的规模了,但是我还要在这个规模的基础上加上一条,从5万节点到10万节点的飞跃我们保持团队规模不变。我们并不是依靠铺人力来做这件事情。
单说规模也是片面的,如果我们的服务不可靠,用户用得不爽也白瞎。所以衡量TESS成功的另一个维度就是可靠性。在业界,衡量云服务(特别是基础架构云服务)的可靠性已经不再单一地用几个九来衡量了,在Google经典的Site Reliability Engineering这本书里倡导的是用SLO(Service Level Objective)来衡量各种基础服务的可靠性。
TESS作为一个覆盖“计算”、“存储”、“网络”的基础架构云是由众多的基础架构服务组成的,每一个服务都有多个SLO指标用来全方位的衡量服务可靠性。举个例子,单说卷(Volume)服务,就有99分位provision时间,provision成功率,attach成功率,mount成功率等几个指标。当然单从目前的统计数字上来说,这个服务的可靠性是令人满意的:
(点击可查看大图)
但同样,我也想从另一个侧面来定义一下TESS在可靠性上怎么才算是成功。作为高可用云服务提供者,TESS有7*24的轮值oncall来解决用户碰到的各种问题,目前我们每天有一个工程师做这项工作,来服务于5万节点、60万Pod部署当中遇到的问题。当我们的规模达到10万节点,Pod部署数量超过100万的时候,如果我们的服务足够可靠,也只需要一个工程师做oncall而不需要增加轮值投入。
02
如何达到成功:Engineering Excellence
前面我讲过TESS这五年也走过不少弯路,在刚开始的阶段过于激进。那个时候Kubernetes社区也在疯狂发展中,由于Kubernetes的高可扩展性,社区迅速涌现了一大批以Kubernetes为核心的各种开源产品。从社区活跃度来说,这是个好现象,但是eBay是不是该涉足这些方面,TESS是不是该紧追潮流确实是个值得思考的问题。现在回过头去看,我们当时追求的Scope过于大了,一个服务还没有做好就急于奔向下一个服务,马不停蹄。但结果呢,上线给用户用的时候不可靠,用户怨声载道,我们的oncall每次轮值都像被扒了一层皮一样。
其实TESS的本质是基础架构,如果我们从用户的角度去思考这个问题,用户对基础架构的最根本的期望不是“酷”,不是“全”,而是“稳”。就像这次我在爬黄山的过程中路过的那一个一个的台阶,就是基础架构,最让我安心的就是台阶和旁边扶手的可靠。所以我们选择了Infrastructure,就等于选择了做其他人的基石,如果用户感受不到我们的存在,那就是我们最大的荣誉。这一点也是我跟经常团队讲的话,当我们遇到问题的时候,不要轻易地用workaround和automation去解决。做过Infrastructure的朋友们可能都熟悉所谓的3R大法,其中最经典的就是“重启”。即便是发展的如此成熟的Linux,也有可能会出现不同的系统进程在锁的竞争中出现死锁而挂起的场景。很多底层的问题确实可以通过简单的“重启”把服务恢复回来。
但是请大家考虑我们遇到的这样一个场景:TESS使用containerd作为容器运行时,也就是负责启动,停止容器的主要模块。在目前的规模下,我们每周承载16万Pod的启动,也就是每天启动Pod大概2万次。如果我们按照3个9,也就是99.9%的成功率来计算,每天就会有40~60次的启动失败(每个Pod至少有两个容器)。如果是10万台节点,这个数字还至少要翻个倍,也就是每天会有100+次的启动失败,这对我们来说是一个不可容忍的数字。即便在大多数情况下,重启containerd可以解决问题,但是containerd作为一个开源的项目,我们有能力深入开源代码去研究这些问题。相比做一个自动化工具去重启containerd,我更愿意花费两倍的精力把containerd研究透彻并从根源解决问题。因为一,即便你做了自动化,你接下来还得保证这个自动化一直工作,并要保证自动化不带来其他风险;二,我们还能将根除的fix回馈社区。在我们做一个服务的时候,当你把代码写完,完成单元测试,你觉得离这个服务达到大规模生产的质量要求还有多远?我可以告诉大家,还差80%。这是一个惊人的数字,但确实如此,让我们来看看这80%都有什么呢:
LnP:压力性能测试。
你的服务能承受多大的流量压力?线上流量模型是什么样子?能满足当前业务流量以及预测流量吗? FMA:失效模型分析。
你的服务可能是由多个微服务模块组成的,在各种失效情况下,你的服务会呈现什么状态?与你期望的呈现状态一致吗?
Monitoring:监控。
你最重要的服务指标是什么?这包括user facing指标和性能指标。通过这些指标你是否可以迅速地判断服务等级以及发现问题?
Alerting:告警。
在服务降级的时候,你是否有能力在用户发现问题之前主动发现问题并及时介入?
Production debuggability:生产环境调试能力。
如果生产环境出现问题,你有数据和能力迅速追踪和定位吗?
该如何定义联邦同步服务的SLO?同步应该在1秒,2秒还是3秒完成?这个目标我们该如何制定?拍脑袋不是工程卓越原则,我们是这样考虑这类问题的: 按照eBay的业务量,我们需要支持10k application,每个application大概率有N个Tess object,每个object的数据量在4k-8k之间。所以在联邦(Federation)层我们需要支持20-40GB的数据。按照现有网卡的吞吐量,如果不计网络传输消耗和数据结构序列化反序列化消耗,那么理论值应该是多少?再考虑到上述两种消耗,我们的SLO应该是多少? 是不是轻易的scale out就能解决问题?
是不是轻易的加工作线程就能解决问题?
单instance的处理能力到底是多少?
当单instance的处理能力达到最大的时候,是哪种资源到达了瓶颈?CPU/memory/网络带宽?
找到资源瓶颈的时候我们知道是什么原因吗?能有方法优化吗?是线程模型出了问题还是对数据结构的序列化反序列化出了问题?
我们对于正常用户请求的处理能力如何?
我们对于burst场景的处理能力如何?
如果member cluster出了问题,我们的线程工作模型能应对吗?
Q5
做到心目中的TESS,这条路还有多长?
路漫漫其修远兮,吾将上下而求索。
A5
这几年我深切地体会到做Infrastructure的心境,很多时候要完成一个目标需要极度的专注,也需要时间的沉淀。例如,我们在规模上来之后所碰到的用户关于网络方面的调试需求:用户说我调用某个服务慢了200ms,诸如类似的从现象的角度来看很通用的一些问题。就像是你从上海开车去北京的路途比原来多用了两个小时。可难点是,这条路线上有太多的因素会导致这个两个小时的latency(延迟),我们如何对问题进行快速定位呢?
如果Linux对我们来说是黑盒,那就只能通过尝试的方式,而这种方式既不可控,又全无信心。在一次搜索引擎调优的case中,我们用了三个月的时间进行各种尝试,虽然最终问题解决了,但这种通过“尝试”对问题进行定位排查的方式效率太过低下。我们想做到把Linux剥开,构建对应于Linux Kernel模块的不同的探测工具,在出现问题的时候可以像使用CT机一样使用这些工具,从而拿到Kernel内部的影像信息来帮助我们快速定位问题。Facebook就是在采用类似的方式做问题定位,他们走得比我们快一步,已经积累了100多个线上debug工具。而我们通过半年多的努力沉淀了3个工具。要做到我心目中的TESS,这条路还很长,距离我们期望的那朵“云”还很远。但我想用下面这张在攀登黄山莲花峰的路上拍的照片来说明一下我们的决心,路漫漫其修远兮,吾将上下而求索!图|通往黄山莲花峰之路 辛肖刚摄
作者简介:
辛肖刚,2015年加入eBay基础架构部,任云计算工程师,从事OpenStack reliability相关工作,后加入新成立的TESS团队,现任eBay基础架构云开发经理。目前主要负责新一代云产品TESS的开发与运维,致力打造高效高可用的云基础架构并推动eBay容器化进程。
您可能还感兴趣:
重磅 | eBay提出强大的轻量级推荐算法——洛伦兹因子分解机
实战 | 利用Delta Lake使Spark SQL支持跨表CRUD操作
eBay大量优质职位,等的就是你