蚂蚁金服 Service Mesh 渐进式迁移方案|Service Mesh Meetup 实录

小蚂蚁说: git

本文是基于在 Service Mesher Meetup 上海站的主题分享《 蚂蚁金服 Service Mesh 渐进式迁移方案》 内容整理,完整的分享 PPT 获取方式见文章底部。 github


敖小剑,蚂蚁金服高级技术专家,十六年软件开发经验,微服务专家,Service Mesh 布道师,Servicemesher 社区联合创始人; 龙轼,阿里巴巴技术专家、前京东 Hadoop 负责人、Hadoop 代码贡献者、现负责UC 基于 Kubernetes 自研的 PaaS 平台总体的稳定性。 编程

640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1


你们好,今天给你们带来的演讲主题是《蚂蚁金服 Service Mesh 渐进式迁移方案》,给你们介绍一下咱们蚂蚁金服主站的 Service Mesh 迁移方案,在稍后的内容中我会给你们解释什么是“渐进式”。今天的演讲方式有些特殊,将会是两位讲师合做。我是敖小剑,来自蚂蚁金服中间件团队,另一位讲师 龙轼 ,来自 UC 基础研发部。 json


Service Mesh 演进路线 后端

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


今天的内容将会有四块主要内容: api

  1. Service Mesh演进路线:介绍蚂蚁金服计划在主站落地Service Mesh的方案,因为涉及到大量的存量应用和超大规模,又要保证迁移过程的平滑,所以咱们的落地方案相比社区方案要复杂的多。 缓存

  2. 实现平滑迁移的关键:介绍在整个迁移方案中,为了实现平滑迁移的几个关键作法,而后今天咱们将详细展开其余的一个关键点:DNS寻址方案。 安全

  3. DNS寻址方案的演进:详细介绍Kubernetes/Istio/SOFAMesh一路演进过来的DNS寻址方式 服务器

  4. DNS寻址方案的后续规划:介绍咱们在DNS寻址方案上的后续规划 网络


前两块内容将由我来为你们介绍,后两块内容将由个人同事 龙轼 为你们介绍。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


在展开内容以前,先看一下背景,Service Mesh在蚂蚁金服主站落地的背景:

  • 目标:须要知足咱们对长期目标的承认,具体指服务间通信走Service Mesh,并且是Istio这种带完整的控制平面的Service Mesh形态,基础设施要构建在k8s之上,而应用的形态要向微服务靠拢。

  • 现状:而现实是存在不少挑战,首先还有不少应用没有实现微服务化,并且咱们的k8s普及程度也不够,还有很是多的应用没有运行在kubernets之上。Istio的成熟程度也稍显不足,不够稳定,更大的挑战的是Istio目前没法原生支持咱们蚂蚁金服的规模,咱们还在试图对Istio进行改进和扩展。最后,在落地时必须考虑的很是现实的一点:现有系统中为数众多的应用不可能一晚上之间所有迁移。

  • 关键需求:所以在落地实施时,很是重要的需求是:要实现平滑迁移。简单说,微服务 + Service Mesh + kubernetes 是咱们的目标,可是如何从现有体系出发,向目标平稳和坚实的迈进,必须给出可行的实践指导。


今天演讲的内容,要给你们介绍的就是,在这样的背景下,咱们蚂蚁金服选择的Service Mesh主站落地演进方案。这个方案预期会在2019年初全面铺开。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


主站落地方案的实施原则,这是咱们在过去半年的实践中,总结概括出来的行为指导:

  • 符合远期规划:必定要有清晰的长期目标,明确的知道将来的大方向。避免走弯路,避免浪费投资,理想状态是计划中的每一步均可觉得下一步奠基坚实的基础。即便由于某些缘由不得已妥协或绕行,也应该清晰的知道后面应该如何回归,谢绝中途推倒重来——代价过高,没法承受。

  • 按部就班:认清现实,如此之大的变革,必定是须要分步进行,不要心存一步登天的幻想,现实可行的方式是小步快跑。将整个过程拆解为若干个大步骤,每一步的工做量和复杂度都控制在一个能够接受的范围内,以保证每一步都简单方便,切实可行。

  • 有可操做性:在操做层面上,要有足够的弹性,即每一个步骤中的工做内容,都应该是能够分批进行。以步步为营的方式,逐步扩大战果,杜绝一刀切。


在接下来的演进路线中,你们将会体会到这三个原则在实际落地时的指导做用。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


这个图的信息量有点大,描述的是 Service Mesh 和 k8s 落地可能的多种演进路线。


咱们先从最下面开始看,这是当前蚂蚁金服主站大多数应用的现状:即应用"部署在非k8s上",应用也"不是Service Mesh形态"。 而后看最上面,这是咱们指望的蚂蚁金服主站将来的应用终极形态:应用"部署在k8s上",应用也迁移到了"Service Mesh形态"。


这里有个特别的地方,咱们将Service Mesh形态细分为两种模式:

  1. Sidecar模式:只有Sidecar,没有控制平面,和外部系统的各类集成都是在Sidecar中直接进行。这是第一代的Service Mesh,Linkerd/Envoy都是如此,华为基于ServiceComb演进而来的mesher,新浪微博的Mesh,包括咱们蚂蚁金服基于MOSN开发的用于取代多语言客户端的Mesh方案。

  2. Istio模式:有完善的控制平面,能够提供强大的控制能力,并且从数据平面分离,这是第二代的Service Mesh,典型如Istio和Conkduit/Linkerd 2.0。


之因此将Service Mesh形态细分,是由于咱们有着这样一个特殊背景:目前的原生Istio没法支撑咱们蚂蚁金服的规模,所以在改进完善Istio以前,咱们不得不暂时在Sidecar模式下短暂停留。另一个缘由就是考虑到存量应用的迁移,多一个Sidecar模式做为中间缓冲,会让整个迁移过程平滑不少。


如今咱们来介绍图中展现的四条演进路线:

  1. 左边的路线1,思路是先将应用迁移k8s部署,再迁移到Service Mesh形态。这条路线的最大好处,是过程当中每一个阶段的绝大多数投资都将最终得以保留,由于符合k8s+service mesh的远期目标

  2. 右边的路线2,思路是跳过k8s,先迁移到Service Mesh形态,一路演进到Istio模式,而后最后迁移到k8s。

  3. 中间的路线3,直接一步到位,这个路线是Istio默认的方式,或者说Istio根本没有考虑过迁移的问题,默认客户已经有完善的k8s,而后将改造好的应用直接部署在Istio上。这个路线对于蚂蚁金服主站的复杂场景,固然是不现实的。(补充:只是对蚂蚁金服主站不合适,对于大多数公司,规模不是那么巨大,也没有历史负担,也有k8s基础,彻底可行。)

  4. 还有一条特别的路线4,走位飘忽,先和路线2同样迁移到Sidecar模式,而后走回路线1,上k8s,再在有k8s支持的状况下继续演进到Istio模式。


下面咱们来详细分析各条演进路线的优劣和实施条件。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


演进路线2,和路线1的核心差异,在于:是先上k8s,仍是先上Service Mesh。并且路线2是在非k8s条件下一路演进Service Mesh到咱们指望的终极形态Istio模式,这意味着过程当中和最终目标有很是大的偏移。


演进路线2的好处,在于第一步很是的天然:

  • 没有k8s的限制,所以不依赖基础设施,实施方便。毕竟,k8s普及度是个大问题

  • 在原有的侵入式框架的客户端SDK基础上,经过包裹一个proxy,重用原有SDK的能力,能够很是快速的获得一个基本可用的Sidecar

  • 除了多一个proxy外,没有引入太多的新概念和新思想,符合现有开发人员/运维人员的心智,容易接受


所以,路线2特别容易落地,能够快速达成短时间目标,直接拿到Service Mesh的部分成利,如:多语言支持,方便类库升级等。


可是,这个路线的问题在于再日后走,开始完善Service Mesh的功能以向Istio模式靠拢时,因为没有k8s的底层支持,所以不得不作大量的工做来提供类k8s的功能。尤为是Istio的非k8s支持,官方方案基本上只是一个demo,彻底不具有生产可用性,要完善好,工做量很大。而关键点在于,这些投入,在迁移到k8s时,又由于和k8s提供的功能重复而被放弃。


所以,结合咱们前面的原则(符合远期规划,不浪费投资),路线2对蚂蚁金服主站落地是不合适的。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


演进路线4是一个很是特殊的路线,能够理解为路线1(先上k8s再上Service Mesh)的短时间妥协版本。由于路线1的前提条件是要先大规模铺开k8s,将现有应用迁移到k8s以后再继续往Service Mesh演进,这对于尚未普及k8s的公司来讲是一个很是高的门槛,很容易所以受阻而没法启动。


所以,若是暂时不具有k8s条件, 又不想就此止步,那么选择路线2是惟一的出路。而上面咱们分析过,路线2虽然可以在第一步快速拿到短时间红利,可是因为偏离长期目标后续发展会有问题。怎么办?


路线4能够是这种场景下的一个折衷选择:在k8s没有铺开以前,第一步沿路线2走,先吃下非k8s下Sidecar模式快速落地的红利。而后第二步避开非k8s下继续演进到Istio模式的大坑,切换到路线1,回归长期目标。


好处很是明显:

  • 在k8s未铺开前,先往前迈进一步,避免就此卡壳

  • 和路线2同样,第一步能够快速的拿到短时间红利

  • 后续转为路线1后,由于符合远期规划,所以后续演进不存在投资浪费的问题


缺点就是存在少许的投资浪费,毕竟非k8s下的Sidecar模式仍是有些工做内容在迁移到k8s以后会有改动。不过,这个改动不会太大,和拿到的红利相比仍是值得的。


路线4在操做时,存在一个变数:现有应用在向Sidecar模式的Service Mesh迁移,是须要必定时间的。有一种可能,就是在迁移过程当中,k8s的普及开始了。这个变数的发生,取决于Sidecar模式的Service Mesh普及快,仍是k8s的普及快。


对路线4的分析结果:这是(k8s没有普及的)特殊时期的选择。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


在对四条可能的演进路线分析完成以后,咱们来具体介绍蚂蚁金服的最终选择。


坦言说,在过去半年中,咱们的演进路线有几回摇摆和修订,今天咱们公布的路线,和过去几个月中咱们经过 meetup/技术大会/博客文章 等方式透露出来的方式会有一些变化。主要缘由是在过去的这半年中,一方面咱们对Sercice Mesh的认知更加深刻,另外一方面是蚂蚁金服的k8s背景也在变化。


首先,在今年年初,咱们确认Service Mesh大方向时,k8s尚未在蚂蚁金服普及,并且也没有明确的时间表。所以,咱们在一番调研以后,选择了两条腿走路的方式:

  1. 在非k8s环境下,以Sidecar模式先进行少许落地,主要是替换掉原有的多语言客户端 (拿短时间红利)

  2. 开发SOFAMesh,集成MOSN到Istio,增长对多种RPC协议的支持,增长对RPC服务模式的兼容(为最终目标作准备 )


在今年6月底的杭州第一届Service Mesh 线下 meetup 中,咱们公布了 SOFAMesh 项目,我当时作了一个演讲 大规模微服务架构下的Service Mesh探索之路 ,有兴趣的同窗能够去回顾一下咱们当时的背景/需求/设计方案。


大概在今年九月,咱们完成了对非k8s下运行istio的深刻调研,得出的结论是要实现这个模式须要很是多的工做。并且,咱们对Service Mesh的认知也更加深入,明确了经过Service Mesh将传统中间件能力向以k8s为表明的基础设施层下沉的战略方向。期间,内部也明确了k8s普及的大方向,所以,综合这两个重要输入,咱们选择放弃继续在路线2上继续演进(即 istio on 非k8s)的想法。关于这一点,有兴趣的同窗能够去阅读我在10月份QCon大会上的演讲内容 长路漫漫踏歌而行:蚂蚁金服Service Mesh实践探索 。


最近,k8s普及的时间表再一次明确提早,蚂蚁金服将会在短期内开启k8s的大面积普及。所以,咱们的演进路线再一次发生变化。目前最新的演进路线将会是这样:

  1. 当前尚未开始迁移的应用(处于演进路线图最下方),将按照路线1的方式进行迁移:先迁移到k8s,再迁移到Sidecar模式的Service Mesh

  2. 目前部分已经迁移的应用(路线2/4的第一步,非k8s部署的 Sidecar 模式),将沿路线4迁移,和路线1会师

  3. 因为应用众多,所以预计到 k8s + Sidecar模式 的迁移工做会持续比较长时间,在此期间,咱们会同步完善Istio,和Istio官方一块儿合做来实现Istio对超大规模部署的支持

  4. 最后一步,迁移到最终目标(固然这一步的方案依然有不少待定内容,继续努力)


须要强调的是:这个演进路线针对的是蚂蚁金服主站的特殊场景,并不具体普适性。你们能够在理解咱们演进路线背后的思路和权衡方式以后,再结合自身的实际状况进行决策。好比,咱们在UC落地时,因为UC有完善的k8s支持,并且目前落地的规模没那么夸张,所以是直接从"部署在k8s上" + "不是Service Mesh形态",直接迁移到终态的。预计在金融云落实时,也会是如此,由于客户也不会有如此规模。


总结:前面咱们介绍了当应用程序向Service Mesh和K8s迁移时的几种可能的演进路线,分析了各条路线的利弊。并以蚂蚁金服主站为例,介绍了咱们迁移的背景和演进路线的选择思路,但愿可以帮助你们更好的理解Service Mesh的落地实践,以便在将来设计自家的落地方案时能有所参考。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


实现平滑迁移的关键

前面给你们介绍了蚂蚁金服主站的Service Mesh演进路线,期间谈到要实现现有应用的平滑迁移。今天的第二个内容,将给你们介绍平滑迁移实现中的几个关键作法。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


首先,第一个关键是尽可能保证迁移先后服务间网络互通。


以向k8s迁移为例,在非k8s环境,典型的服务间访问方式是这样:

  • 每一个服务向注册中心注册

  • 客户端发起访问前,经过注册中心获得目标服务的实例列表信息,如IP地址/端口等


在向k8s迁移的过程当中,咱们的作法是保证k8s内外网络打通,即服务的IP地址(在k8s中是pod ip)是能够相互直接访问的。基于这个前提,服务在迁移到k8s的过程当中,原有的服务注册/服务发现/发起请求等逻辑都无需修改,是否是在k8s内,是否是pod ip,对原有服务化体系彻底是透明的。


所以,向k8s的迁移能够作到对业务应用很是的平滑,基本感知。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


透明拦截在迁移过程当中,能够起到很是关键的做用。


以Service-A要访问Service-B,在应用向Sidecar模式的Service Mesh迁移先后,会有有四种排列组合场景:

  1. Service-A和Service-B都没有迁移到Serive Mesh:此时请求会直接从Service-A发送到Service-B,称为直连,这是应用在开始迁移到Service Mesh以前的标准工做方式

  2. Service-A已经迁移到Service Mesh,Service-B尚未:此时Service-A发出来的请求,会被劫持,而后发送到和Service-A一块儿部署的Sidecar(称为Outbound Sidecar),此时链路中只有一个Sidecar,称为(客户端)单跳

  3. Service-B已经迁移到Service Mesh,Service-A尚未:此时Service-A发出来的请求,在到达Service-B时,会被劫持到和Service-B一块儿部署的Sidecar(称为Inbound Sidecar),此时链路中也只有一个Sidecar,称为(服务器端)单跳

  4. Service-A和Service-B都迁移到Serive Mesh:此时Service-A发出来的请求,会被两次劫持,分别进入Outbound Sidecar和Inbound Sidecar,此时链路中有两个Sidecar,称为双跳。这是Istio的标准工做模式,也是咱们迁移完成以后的最终工做模式。


在这四种场景中,全部的网络请求,请求报文都是彻底一致的,即无论是否被劫持到Sidecar,对请求报文都没有影响,也就是对发出请求报文的客户端和接受请求报文的客户端都是透明的,彻底无感之。


所以,在迁移过程当中,能够单个服务逐个迁移,甚至服务的单个实例逐个迁移,而无需修改应用自己。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


在展开第三个关键点以前,咱们来探讨一下:在Service Mesh时代,理想的客户端应该是什么样子?


图中咱们列举了一个传统的侵入式框架的客户端所包含的功能,在侵入式框架中,大部分的功能都是由客户端实现,所以会包含很是多的功能,如服务发现、负载均衡等基本功能,加密、认证、路由等高级功能。在应用迁移到Service Mesh以后,这些功能都下沉到Service Mesh中。所以,Service Mesh下的客户端能够进行大幅度的简化,成为一个新的轻量级客户端。


对于这个轻量级客户端,咱们但愿能够尽量的作的轻薄通用:实现简单,无论哪一个编程语言均可以作到轻松实现,所以跨语言就方便了。并且越简单以后升级的可能性就会越少,以免升级客户端。


那咱们来继续看,这个轻量级客户端里面最后还能剩下什么内容?


图中列出了三个,其中最重要的,也是必不可少的是目标服务的标识,即不管如何简化,最低限度应该告之要访问谁吧?而后是序列化,对于RPC类确定须要提供编解码功能,不过对于HTTP/REST类不少语言直接内置了标准实现。而后链路追踪,须要作一点工做来传递诸如SpanID之类的参数,一样这块也有可能经过自动埋点来实现。所以,最理想最单薄的客户端,可能只保留最后一个信息:目标服务的标示。


在侵入式框架下,目标服务的标示是和服务注册/服务发现是直接关联的,这个标示一般都是服务名,经过服务发现机制实现了一个服务名到服务实例的寻址方式。在Service Mesh机制下,因为服务发现机制被下沉到Service Mesh中,所以只要底层Service Mesh能支持,这个目标服务的标示能够没必要拘泥于服务名。


那么,问题来了,对客户端来讲:最简单,最通用,支持最普遍的寻址方式是什么?是DNS!


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


在咱们的迁移方案中,咱们考虑引入DNS寻址方式。除了前面说的DNS是支持度最好,使用最广泛的寻址方式,在全部的编程语言和平台上均可以支持以外,咱们还但愿将DNS寻址方式做为将来产品的长期方向:

  • 在SOFAMesh和SOFAMosn中,咱们已经基于名为x-protocol的方式实现了DNS通用寻址方式,用来解决Dubbo/HSF/SOFA等传统SOA服务模型在Service Mesh下的访问问题 (备注: 具体内容请见个人博客文章 SOFAMesh中的多协议通用解决方案x-protocol介绍系列(1)-DNS通用寻址方案 )

  • 将来在咱们的serverless产品中,咱们但愿能够为运行其上的Function提供DNS寻址支持

  • 可能还会有其余更加普遍的使用场景。

所以,在咱们的演进过程当中,对于客户端SDK,咱们有这样一个思路:

  • 一方面简化原有的SDK,去除和Sidecar重复的内容(知足短时间需求)

  • 另外一方面,考虑到必然有一次客户端SDK的更换过程,那么咱们但愿在简化的同时引入基于DNS的通用寻址方式,以便在将来的后续迁移和功能扩展中能够依托这个机制来实现 (符合长期目标)


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


图中描述的是在Service Mesh下,客户端经过域名来指定要访问的目标服务,而后经过DNS解析机制来串联底层的服务注册/DNS记录更新/透明劫持传递原始信息/Sidecar查找路由目标等详细实现机制。


这里仅作简单示意,我就不详细展开了。在接下来的内容中,个人同事,来自UC基础研发部的 龙轼 同窗,将为你们详细的展开DNS寻址方案的细节实现。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


DNS寻址方案的演进

你们好,我是来自UC基础研发部的龙轼。 感谢小剑老师给咱们介绍了蚂蚁和UC共建的Service Mesh的演进路线和实现平滑迁移的关键。


接下来由我来向你们分享下实现平滑迁移的关键中的DNS寻址方案的演进。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


你们能够看上面的所示的DNS寻址方案的演进,咱们先了解下各个服务寻址方案的背景。


从 SOA 的寻址,到 Kubernetes 的寻址,而后再到 Istio 的寻址,最后是咱们的 SOFAMesh 的DNS寻址方案。


它们的寻址方案有什么不一样,咱们将一一分析它们的细节和整体寻址方案的演进路线。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


如今你们能够先来看下 SOA 架构下基于服务注册和服务发现的寻址。


咱们能够看到图中的 SOA 实际上是单进程多接口的,依赖于 SOA 的服务注册与服务发现的。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


接下来咱们看下 Kubernetes 的 DNS 寻址方式,它的寻址方式实际上是经过DNS 的。


从图中咱们能够看到部署到K8S 上面的userservice 服务会生成一条DNS记录指向K8S 的ClusterIP。


咱们在 Pod 里面发起请求时经过 DNS 的 SearchDomain 域名补全规则就会从 DNS 里面查询获得ClusterIP,咱们能够看出 Kubernetes 的寻址方案是单进程单接口的。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


看完 Kubernetes 的服务发现以后咱们继续来看 Istio 的服务发现。


从图中咱们能够看出以前的流程都和 K8S 一脉相承,不一样的地方在于 Istio 里面有个 SideCar 它把ClusterIP 拿到以后根据 ClusterIP 从 VirtualHost 里面匹配到 Rule 规则 转发给目标的 Pod 地址。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


最后咱们来看下 SOFAMesh 的 DNS 通用寻址方案。

  1. 根据咱们以前分析的 SOA 寻址方案和 Kubernetes 寻址方案,咱们能够看出若是咱们的微服务不通过拆分和改造想上 Service Mesh 的话咱们须要支持SOA以前的那种单个Pod 多个接口的。

  2. 从图中看就是咱们须要支持 com.alipay.userservice.interface1, com.alipay.userservice.interface2 这些接口解析到 ClusterIP, 咱们知道k8s 中的service 是不支持的。

  3. 那该如何是好,咱们只能在DNS 上作文章修改DNS的记录来实现这一功能。肯定了这一方案以后咱们来看下咱们设计的DNS寻址方案实现细节。



640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


你们看这张图:

  1. 咱们用 CRD 定义了一个 RPCService 和以前的 Service 有一样的 selector 的标签。

  2. 而后用 RPC Service Controller 对 RPCService 作 Watch,当 RPCService 有更新的时候咱们就把接口就是上述的 com.alipay.userservice.interface1 的记录写入 CoreDNS 里面

  3. 而 interface 是经过 Pod 里面的 Register Agent 来获取 Dubbo 里面暴露的。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


好的,说完这个方案的细节以后。咱们能够看出其实其余的问题都不大,可是要更新DNS的这个咱们须要支持。


一开始咱们 K8S 集群里面是用 Kube-DNS 来作 DNS 寻址的,但咱们看这张 Kube-DNS 的架构图。


能够看出修改它成本是比较大的,并且全部的DNS 都在同一个域里面,这个风险系数很高。 若是一旦修改错误势必会影响到以前的 k8s 的 service,致使线上的故障。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


  1. 这个时候咱们跟踪到社区的 CoreDNS 项目,咱们来看下 CoreDNS 的具体的架构。  它采用做为 Web 服务器 Caddy 的服务器框架,延用了Caddy 中的插件机制,大大的增长了 CoreDNS 的灵活性。

  2. 它的插件机制也特别简单,把全部的插件注册进一个Map里面来,在调用的时候从Map拿出他们有共同接口的函数。有兴趣的同窗能够看下 Caddy 的插件代码实现。  

  3. 它的 DNS 协议库采用是由 Google 工程师 Meikg 开发的 DNS 库,他同时也是 SkyDNS 的开发者。

  4. 后端能够采用 UDP/TCP、TLS 或者 gRPC 做为后端数据查询。上面有个Google工程师用 gRPC 作了一个 CoreDNS 插件的后端数据查询例子,有兴趣的同窗能够看下。




640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


OK,既然 CoreDNS 的 Plugins 这么强大,咱们可不能够用它来实现咱们刚才说到的 Renew DNS的机制。 答案很显然是能够。


咱们看下上面的图,实现CoreDNS 的插件很简单,只须要继承上面的接口就能够了。 CoreDNS 官网有具体的教程在教咱们怎么写一个插件。这个就不具体的展开了。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


  1. 到了咱们最关键的点了:咱们应该怎么更新咱们的DNS。其实这点 CoreDNS 社区里面已经有人提出需求用 REST API 的形式提供更新 DNS 的接口。

  2. 互联网任务工程小组也早在 rfc2136 定义了标准的 DNS UPDATE。 Google Cloud 和AWS 都有相应的实现。

  3. CoreDNS 社区其实已经把接口实现了,可是后端存储是基于file 的,数据没有落地。 蚂蚁和UC 这边扩展了 ETCD 插件的接口,把对应 DNS UPDATE 接口给实现了,实现 DNS 数据写入ETCD 里面。

  4. 从图中咱们能够看到 rpc.cluster.local 这个域 和 k8s 域 cluster.local 是在不一样的插件链上的。
    这样在k8s域中没有 dynapirest 插件,咱们就不能对k8s域中的DNS进行更新,这样就把以前Kube-DNS改造以后会对k8s域里面形成影响给去除了,更加的安全。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


咱们能够看下 CoreDNS 后端存储的接口,其实和咱们以前对数据操做的接口是没有什么差异的。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


目前 CoreDNS 的 DynAPI 还在主库代码没合并的状态。以后 DynAPI 这个项目会独立成一个插件项目。咱们能够看下 CoreDNS 社区的 DynAPI 插件进展。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


OK,咱们来看下咱们的DynAPI 实现DNS 更新的一个效果。从图中咱们能够看出 record.json 里面的一个域名的更新。经过 DynAPI 咱们成功把 record.json 的DNS 记录给更新进去而且dns正常工做了。到如今咱们经过CoreDNS 的插件就把DNS 更新的需求给解决了。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


其实CoreDNS 官网还有许多有趣的插件,能够丰富 CoreDNS 的功能和提高 CoreDNS 的性能。 你们能够看下中间的 autopath 插件,他把咱们屡次的在 searchdomain 拼凑的 DNS 记录的查询在在服务器上给实现了。 避免了屡次的 Client 端和 Server 端的数据交互。有兴趣的同窗能够看下 A-Deep-Dive-into-CoreDNS-2018


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


咱们把 CoreDNS 的功能开发完了,上线的话不少人关注它的性能。 咱们这边作了一个简单的性能测试,能够看出 CoreDNS 和 Bind DNS 这种如今比较通用的DNS的性能仍是有点差距的。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


可是,咱们经过上面的图能够看到在必定的QPS 下,CoreDNS 的延时是很低的。 咱们能够看到全部的延时都落在4ms 以内。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


为了解决QPS的问题,咱们经过 Kubernetes 的 HPA 给 CoreDNS 进行横向的扩展。


一开始咱们只是经过CPU的维度给 CoreDNS 扩展,但发现波动有点大。 以后咱们切换成经过QPS的维度来进行扩容。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


CoreDNS 将会在Kubernetes 1.13 以后成为 Kubernetes 的默认的DNS服务。咱们将会紧跟社区实施咱们的方案而且反馈给社区。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


DNS寻址方案的后续规划

咱们再来看下咱们后续的一些规划。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


能够看到咱们的 DynAPI 其实在安全上仍是有欠缺的。咱们后续会把 HTTP 增强成 HTTPS 协议来加强 DynAPI 的安全性。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


还有若是咱们 CoreDNS 的后端变化的更新的 Watch 因为 Watch的范围过大的话,会返回过多的数据。这样会影响到 Watch 的性能,CoreOS 在 ETCD3.2 增长了proxy 可让咱们根据不一样的 ETCD KeySpace 去Watch,这样大大的提升了Watch的性能。


640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


最后一个,咱们建议在建立 Kubernetes 集群的时候把 idc 的信息给带进Kubernetes的后缀域名中。这样咱们以后能够经过 kubernetai 插件把不一样的 Kubernetes 集群的域名进行整合经过本 IDC 缓存提升跨 IDC DNS 的访问速度。


总结

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1

640?wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1


最后咱们总结下,整体方面小剑老师给咱们讲了蚂蚁金服主站 Service Mesh 的渐进式演进路线和实现平滑迁移的几个关键。 具体细节方面咱们经过CoreDNS 的单点突破解决了 SOFAMesh 的 DNS 寻址的问题。


感谢你们,但愿此次演讲能让你们有所收获。


视频回放与资料下载

地址:https://tech.antfin.com/activities/2/review(点击阅读原文可跳转到该网页)


相关连接:

SOFA 文档:  http://www.sofastack.tech/

SOFA:  https://github.com/alipay

SOFAMosn:

https://github.com/alipay/sofa-mosn

SOFAMesh:

https://github.com/alipay/sofa-mesh


640?wx_fmt=jpeg&wxfrom=5&wx_lazy=1&wx_co=1



来自 “ ITPUB博客 ” ,连接:http://blog.itpub.net/31560885/viewspace-2284592/,如需转载,请注明出处,不然将追究法律责任。

转载于:http://blog.itpub.net/31560885/viewspace-2284592/