microservice

microservice

什么是服务网格?

grace_shi 发表了文章 • 0 个评论 • 293 次浏览 • 2019-06-04 22:29 • 来自相关话题

服务网格 是一个可配置的低延迟的基础设施层,目的是通过API(应用程序编程接口)处理应用程序服务之间的大量基于网络的进程间通信。服务网络确保容器化的短暂存在的应用程序的基础结构服务之间的通信快速,可靠和安全。网格提供关键功能,包括服务发现,负载平衡,加密,可观 ...查看全部
服务网格 是一个可配置的低延迟的基础设施层,目的是通过API(应用程序编程接口)处理应用程序服务之间的大量基于网络的进程间通信。服务网络确保容器化的短暂存在的应用程序的基础结构服务之间的通信快速,可靠和安全。网格提供关键功能,包括服务发现,负载平衡,加密,可观察性,可追溯性,身份验证和授权,以及对断路器模式【1】的支持。

服务网格是如何实现的呢?它通常会为每个服务实例提供一个称为边车(sidecar)的代理实例。这些边车会处理服务间的通信,监控和安全相关的问题, 以及任何可以从各个服务中抽象出来的东西。这样,开发人员就可以专注于服务中应用程序代码的开发,支持和维护,而运维团队可以负责维护服务网格以及运行应用程序。

Istio,由Google,IBM和Lyft支持,是目前最著名的服务网格架构。Kubernetes,最初由Google设计,是目前Istio支持的唯一容器编排框架。供应商正在寻求商业版本的Istio。如果Istio能添加到开源项目中,将会带来更大的价值。

Istio并不是唯一的选择,其他服务网格实现也在开发中。目前边车代理模式是最受欢迎的,例如Buoyant,HashiCorp,Solo.io等项目都使用了这种模式。与此同时,Netflix的技术套件使用了一种替代架构,他们使用了应用程序库(包含Ribbon,Hysterix,Eureka,Archaius)来提供服务网格功能,而Azure Service Fabric等平台在应用程序框架中嵌入了类似服务网格的功能。 服务网格包含一些专业术语来描述组件服务和功能:

  • 容器编排框架。随着越来越多的容器被添加到应用程序的基础架构中,用于监视和管理容器组的容器编排框架变得至关重要。
  • 服务和实例(Kubernetes Pod)。实例是微服务的单个运行副本。有时实例是一个容器;在Kubernetes中,一个实例由一小组相互依赖的容器(称为Pod)组成。客户端很少直接访问实例或Pod,通常他们会访问服务,服务通常是一组可扩展且具有容错性的实例或Pod(副本)。
  • 边车代理。 边车代理与单个实例或Pod一起运行。 边车代理的目的是路由或者代理从容器发出或者接收的流量。 边车与其他边车代理进行通信,编排框架会管理这些边车。许多服务网格的实现会使用边车代理来拦截和管理实例或Pod的所有进出流量。
  • 服务发现。当实例需要与不同的服务进行交互时,它需要找到 - 发现 - 其他服务的健康的,可用的实例。通常,这个实例会执行DNS查找来寻找其他服务的实例。容器编排框架保留实例列表(这些实例都可以正常接收请求),并且框架会提供DNS查询的接口。
  • 负载均衡。大多数编排框架已经提供了第4层(传输层)的负载均衡。服务网络实现了更复杂的第7层(应用层)负载均衡,具有更丰富的算法以及更强大的流量管理。同时可以通过API修改负载均衡的参数,从而可以编排蓝绿部署【2】或金丝雀部署【3】。
  • 加密。服务网格可以加密和解密请求和响应,因此每个服务不需要额外对请求进行加密,减少了负担。服务网格还可以通过优先重用现有的持久连接来提高性能,这减少新连接的创建(创建新连接十分耗费计算资源)。一般实现加密流量都是用双向TLS(mTLS),其中公钥架构(PKI,public key infrastructure)生成并分发证书和密钥,提供给边车代理使用。
  • 身份验证和授权。服务网格可以授权和验证从应用程序外部和内部发出的请求,仅向实例发送经过验证的请求。
  • 支持断路器模式【1】。服务网格可以支持断路器模式,这可以隔离不健康的实例,然后在安全的情况下逐渐将它们恢复并加入到健康的实例池中。

服务网格应用中管理实例之间的网络流量的的部分称为数据平面。另外有一个独立的控制平面负责生成和部署数据平面的配置(这个配置可以控制数据平面的行为)。控制平面通常包含(或被设计为连接到)一个API,命令行界面和用于管理App的图形用户界面。

*服务网格中的控制平面在数据平面中边车代理上分发配置*

服务网格架构的一个常见用例是在使用容器和微服务时解决非常苛刻的操作问题。微服务领域的先驱包括Lyft,Netflix和Twitter等公司,这些公司任何时间都能为全球数百万用户提供强大的服务。 (请参阅我们对Netflix面临的一些架构挑战的深入描述。)如果应用程序对这方面要求比较低,那么更简单的架构就足够了。

服务网格架构不可能解决所有应用程序操作和交付问题。架构师和开发人员可以选择多种工具,这些工具之中,有些是锤子,可以解决不同类型的问题,而另一些可能是钉子。例如,NGINX微服务参考架构包括几种不同的模型,这些模型提供了使用微服务来解决问题的一系列方法。 服务网格架构中的组成部分 - 例如:NGINX,容器,Kubernetes,以及微服务(作为架构方法),可以在非服务网格架构实现中高效地使用。例如,Istio是作为一个完整的服务网格架构开发的,但其模块化的设计意味着开发人员可以自由选择他们需要的部分组件技术。考虑到这一点,即使您不确定是否以及何时会完全实现服务网格应用程序,也值得深入了解一下服务网格概念。 

注释: 

【1】断路器模式: 一种设计模式。用以侦测错误,并避免不断地触发相同的错误(如维护时服务不可用、暂时性的系统问题或是未知的系统错误)。https://zh.wikipedia.org/wiki/斷路器設計模式 
【2】蓝绿部署(blue‑green deployment):蓝绿部署是保留老版本,同时部署新版本然后进行测试,测试通过后,将流量切换到新版本,然后老版本同时也升级到新版本。 
【3】金丝雀部署(canary deployment):又叫做灰度部署,即选择部分部署新版本,将部分流量引入到新版本,新老版本同时提供服务。等待灰度的版本测试完毕,之后全量覆盖老版本。 

原文链接:What Is a Service Mesh? 

============================================================================== 
译者介绍:Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

Serverless的本质是什么?

grace_shi 发表了文章 • 0 个评论 • 2470 次浏览 • 2018-06-18 19:34 • 来自相关话题

【编者的话】这篇文章来自于The New Stask,是Serverlss系列的第一篇文章,这一系列文章是为了探索Serverless的本质,每周一更新。 Serverless直译为中文是“无服务器”,但是实际上它仍需要服务器,只不过 ...查看全部
【编者的话】这篇文章来自于The New Stask,是Serverlss系列的第一篇文章,这一系列文章是为了探索Serverless的本质,每周一更新。

Serverless直译为中文是“无服务器”,但是实际上它仍需要服务器,只不过服务器的管理以及资源分配部分对用户不可见,为避免误导读者,译文中还是将英文保留。

最开始,一台单用户的物理服务器便能满足我们的日常所需,它快速,可靠并且安全,只对管理员负责。但是在实际中配置和扩展都很麻烦。虚拟机的出现满足了灵活性和可扩展性的需求,之后云服务提供商为我们带来了基础架构即服务(IaaS),云平台自助服务也由此诞生。在这片肥沃的土壤中出现AWS(Amazon Web Services),编排,以及基础设施即代码(IaC),之后开始了集装箱化,带来了平台即服务(PaaS)的架构,一切看起来都很顺利......但程序员仍想要更多的功能,如独立于编程语言(language agnostic)的端点,服务器的水平伸缩能力,以及可以实时支付服务使用量的能力。

为了满足这些需求,Serverless计算应运而生,Serverless计算也被称为功能即服务(FaaS)。运行时只会执行程序但不会存储数据。这意味着像AWS(Amazon Web Service),谷歌云以及微软Azure云这样的云服务提供商会动态的管理资源的分配和分布。

Serverless是付完即走,基于实际的消费而不是基于预测的预付款进行收费的。这本是基础设施应该有的样子,在2018年终于出现在我们面前。
# 这并不是魔法
首先,这个名字非常有误导性。 Serveless(无服务器)计算仍然需要服务器,它并不是什么神秘魔法。

这个术语的出现是因为服务器的管理以及容量规划都被隐藏起来了。Serverless被称作是无服务的是因为用户/程序员无需关心甚至意识到基础架构的存在——服务器被完全抽象出去了。Serveless代码可以和传统方式部署的代码一起使用,例如微服务,甚至一个应用程序可以完全不需要配置服务器,只需要以无服务器的方式编写即可。

Serveless 真正的价值不在于节省了成本,而在于节省了时间。



Bitnami的现任云技术高级总监Sebastien Goasguen说到“我会把Serverles 想像成一个具有微型PaaS的像胶水一样的软件,它最大的优点就是可以从云中发生的事件中调用函数(即胶水)“,Goasguen描述了一个场景,例如,将图像放在AWS(Amazon Web Service)的storage bucket中存储,然后调用函数来调整该图像的大小。Serverless系统会获取这段代码并且自动注入到运行时环境(服务器或者容器),之后将这个函数暴露出来以便调用。
# 那么,讲完了什么是Serverless,然后呢?
传统云计算和Serverless云计算最主要的区别在于客户是否需要为未被使用或者未被充分使用的资源支付费用。以前,无论是内部数据中心还是云上,我们都需要提前预测容量和资源需求,并且提前准备好。在之前的例子中,这意味着我们提前启动AWS服务器以便随时执行这项调整镜像大小的服务。而在Serverless配置中,你只需要调整代码执行的时机,即只在函数被调用时候执行。

Serverless计算服务将您的函数作为输入,执行逻辑,返回输出,之后关闭。你只需要为函数实际执行所消耗的资源付费。

即用即付(Pay-as-you-play),并且只用为你实际使用的资源付费,这显然是件好事,但是Goasguen以及其他Cloud Native的专家强调Serverless真正的价值在于时间效率,而不是成本效率。
# 像时间机器一样?
Serverless就像一扇通往未来的门,它和其他即服务(other as-a-service)的技术一样,为公司提供了很多工具,可以让公司专注于构建使用如AI,机器学习等尖端技术的应用程序。而不是浪费时间精力在不停的构建,重建必需的基础设施。

Serverless其他的时间机器功能在于缩短了从代码开发到投入生产的时间。它真正实现了“这是我的代码,现在立刻运行它”。不会因为基础设施产生延迟。

Oracle公司负责Serverless业务的副总裁Chad Arimura说到“Serverless的基本思想是程序员只需要写代码然后推送到Serverless的服务就足够了,其余的事情都由这个服务来处理”。他还补充道,像数据库和数据存储这类的依赖关系也被当作服务无缝集成到Serverless底下。

Arimura说到“在Serverless背后,专业的团队和自动化工作相结合,大规模的操作这些系统,以便开发人员无需考虑这些问题,这项技术看起来就像是魔法一样,这也是为什么这项技术被炒作的如此厉害,正因为它带给了我们如此美妙的体验”。
# 感受 FaaS(功能即服务)平台的强大
虽然Docker技术简化了分布式应用打包和依赖管理的问题。Kubernetes帮助企业在生产中运行这些应用。但是使用它们并不简单易用。Dcokerfile, 、基础设施细节、Kubernets manifests文件,这些即便对于程序员听众来说,也异常复杂。

Serverless计算的核心就是作为一个功能即服务平台。从本质上讲亚马逊的AWS Lambda以及Google Cloud Function就是Serverless的实现。它们处理了资源管理,负载均衡以及多线程,开发人员就可以只关注他们的代码,而企业只用关心他们的目标。

iguaz.io的创始人兼CTO Yaron Haviv提到,一个持续的数据平台是为提升云上的性能而设计的,将一个新的技术栈按照FaaS(功能即服务)的工作流运行一遍,步骤如下:

  1. Serverless平台提取了功能代码——即FaaS(功能即服务)的功能部分——以及所有依赖项(如必需的库,内存的数量,属性等等),构建成一个集装箱化的应用程序包,通常采用Docker镜像的形式。
  2. 当另一个平台服务,例如对象存储或数据库想要触发这个功能,或者一个外部的http请求想要调用这个功能,Serverless平台会将这个请求转发到一个可用的功能微服务。如果当前没有可用的微服务,那么它将部署“冷启动”(cold start)一个这样的实例。
  3. Serverless平台需要负责在微服务失败的时候恢复它,自动扩展以适应需求,记录和监控功能活动,并且在代码被修改后进行实时滚动升级。专门有人来管理平台服务,这样程序员就可以专注于“功能”方面。

# 那么Severless的缺点是什么呢?
除了以上列出的优点之外,FaaS(功能即服务)也存在一些潜在的缺点。专家提到,云服务提供商通常会降低那些不经常的运行环境的资源,他们也会限制你的可用资源的总量,由此带来延迟以及低性能问题。并且由于任何云计算工作流事实上都会运行在一个公有云环境,而你无法控制或者进入这些云环境,导致监控,调试,以及安全性都无法保障。

亚马逊Lambda已成称为Serverless计算的代名词,这也是大多数人可以完全理解一种Servless的模式。尽管Lambda已经开辟了Serverlss的前路,它也涵盖了所有Serverless的缺点:缓慢的冷启动(cold start),低性能,短时间存在的功能,以及一组封闭的触发器。目前普遍认为,所有的Severless平台都具有这些限制性,但事实上这些限制性可以在平台的实施中避免。值得注意的是有一些更新的Serverless平台比如 Nuclio,它演变出了很多更广泛的用例,这些更新的平台具有更少的限制,更高的性能,并且可以运行在多个云服务上甚至是内部环境。

Haviv说道“极客们喜欢Serverless,但是企业们仍在试水——他们甚至还没有熟悉Docker/Kubernetes,Serverless就开始出现了”,就如任何新技术一样,一开始总是由一些聪敏,愿意冒险的早期受众开始试用,之后慢慢面向大众。而大众往往需要在看到这项技术是值得信赖,并且有可靠证据证明它能解决性能问题,安全问题等等问题之后才会采用这项技术。

鉴于Serverlss这项技术几乎每天都在发展壮大,所以并非所有的方面都可以令人满意。虽然称不上是个缺点,但是这一点的确令整个董事会坐立不安。Haviv 指出“由于数字化转型”正影响着当代企业,创新者们以及Serverless一类的某某即服务(Other As A Service)技术正在威胁着现任者,让企业变的更加敏捷以及更加愿意承担风险。最有趣的是尽管Serverless比Docker/Kubernetes技术更新,但如果将Docker/Kubernetes的复杂性抽象出来,Serverless会更快更容易的被采用。
# 如何知道Serverless是否适合你的公司
这里不是讨论你的公司到底适不适合Serverless,这里只是讨论一下那些最先采用Serverless技术的公司。

Oracle的Arimura说道“表面上来说,任何编写软件的公司和组织都非常适合采用Serverless”,不过,就当前的文化以及离达成全面“原生云”目标的距离而言,采用Serverless将会使这个过程变得更加艰难。换句话说,如果一个公司没有使用过任何的公有云,没有任何Docker/Kubernetes的实施经历。那么他们就不该从Serverless开始。

“这是一种全新的架构,需要完全不同的思维方式,最简单的例子就是如果要把一个单体应用拆分成10个微服务,100个函数,并且每个都具有独立的部署周期以及复杂的依赖图,配合成熟健壮的CI/CD以及自动化的系统。把这些和Serverlss一起使用的时候,将会大幅提升敏捷性和创新性,但是如果仅仅只有其中一个,那么带来的损失远大于收益。”

Arimura继续说道 “这就是为什么Devops(运维人员)不会变成noOps(无运维人员),因为这是一条完全错误的方向。“事实上,Serverless的出现使得DevOps比以往更重要。

事实上,Bitnami的Goasguen指出,他观察到的大部分使用Serverless的公司都是以程序员为中心的组织,尤其是使用AWS Lamba服务的,这些公司原本就使用AWS并且用AWS将服务连接在一起。 Goasguen说道“所以很有可能,如果你不使用AWS,那么你便不需要Serverless,但是你始终需要保持警惕,开始评估,辨别企业中哪些事件源可以被用来建立完整的应用程序管道。
# 企业试水Serverless的最佳途径?
Arimura建议道“如果一个企业仍处在适应DevOps的阶段,那么它不需要一开始就将一个大型的单体应用完全拆分转换成微服务或者功能,或是为了学习一个新架构就在一个重要的新项目中使用这项技术。最好是从小处着手,例如创建一些自动化的任务,或是事件驱动的用例。”

本系列Serverless的文章可以帮助您的公司开始使用这项技术。

原文链接:Serverless 101: How to Get Serverless Started in the Enterprise

==============================================================================
译者介绍
Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

如何开启Kubernetes之旅

justinfu 发表了文章 • 0 个评论 • 5604 次浏览 • 2017-07-19 18:56 • 来自相关话题

【译者的话】这篇文章由浅入深地介绍了如何开始Kubernetes学习,以及如何基于Kubernetes部署应用。作者给出了很多非常好的建议,指导读者掌握围绕Kubernetes的各个概念和相关技能,为学习Kubernetes指明了方向。 ...查看全部
【译者的话】这篇文章由浅入深地介绍了如何开始Kubernetes学习,以及如何基于Kubernetes部署应用。作者给出了很多非常好的建议,指导读者掌握围绕Kubernetes的各个概念和相关技能,为学习Kubernetes指明了方向。

从Hello Minikube到Kubernetes Anywhere,再到微服务示例应用,学习谷歌容器编排工具的途径比比皆是。



每一次的创新都带来一些新的麻烦。容器使得应用的打包和运行更加便捷,但是管理大规模容器依然是一个挑战。

Kubernetes是谷歌公司内部为解决这个问题而开发的产品,它提供了一个单一的框架来管理在整个集群中运行的容器。该产品提供的服务主要集中在“编排”上,但也涵盖了许多方面:容器调度、容器之间的服务发现、跨系统的负载平衡、滚动更新/回滚、高可用性等。

在这个指南中,我们将介绍创建Kubernetes集群并发布容器应用的基本知识。这并不是要介绍Kubernetes的概念,而是通过简单示例来展示这些概念如何在运行Kubernetes的过程中结合在一起的。
# 选择一个Kubernetes主机
Kubernetes是为了管理Linux容器而诞生的。但是,从Kubernetes 1.5起,尽管Kubernetes控制面板必须继续在Linux上运行,但Kubernetes已经开始支持Windows Server Containers。当然,借助虚拟化,您可以在任何平台上开始使用Kubernetes。

如果您选择在自己的硬件或虚拟机上运行Kubernetes,一个常见的方法是获取绑定Kubernetes的Linux发行版。这样就不需要设置Kubernetes,不仅省去了安装和部署过程,甚至配置和管理的过程也不需要了。

CoreOS Tectonic就是这样的一个发行版,专注于容器和Kubernetes,几乎完全排除其他任何东西。RancherOS采取类似的做法,同样自动化执行大部分的设置。两者都可以安装在各种环境中:裸机,Amazon AWS VMs,Google Compute Engine,OpenStack等。

另一种方法是在常规的Linux发行版上运行Kubernetes,尽管通常会带来更多的管理开销和手动调整。例如,红帽企业Linux在其软件库中有Kubernetes,但即使是Red Hat,也建议仅用于测试和实验。建议红帽用户通过OpenShift PaaS使用Kubernetes,而不是自己动手从头搭建,OpenShift现在使用Kubernetes作为自己的容器编排系统。许多传统的Linux发行版提供了设置Kubernetes和其他大型软件堆栈的特殊工具。例如,Ubuntu提供了一种名为conjur-up的工具,可用于在云和裸机实例上部署Kubernetes的上游版本
# 选择一种托管Kubernetes的云
尽管在谷歌云平台(GCP)上,Kubernetes已经全面支持了,但是在很多其他云平台上,Kubernetes是否支持依然是一个焦点问题。GCP提供了运行Kubernetes的两种主要方式。最方便和集成最好的方式是通过Google容器引擎,它允许您运行Kubernetes的命令行工具来管理创建的集群。或者,您可以使用Google Compute Engine来创建计算集群并手动部署Kubernetes。这种方法对用户的技能要求比较高,但是允许用户使用Google Container Engine尚未支持的个性化定义。如果您刚开始接触容器,最好坚持使用容器引擎。经过一段时间之后,您对Container Engine有了一定的了解,就可以尝试一些更高级的内容,比如您自己选择特定版本的Kubernetes进行部署,或者部署运行Kubernetes发行版的虚拟机。

亚马逊EC2有容器的原生支持,但没有原生支持Kubernetes作为容器编排系统。在AWS运行Kubernetes类似于使用谷歌计算引擎:配置一个计算集群,然后手动部署Kubernetes。

许多Kubernetes的发行版都有如何在AWS部署的详细说明。例如,CoreOS Tectonic,有一个图形化的安装程序,同时还支持Terraform基础设施配置工具。此外,Kubernetes kops工具可以被用来配置一组AWS上的虚拟机集群(通常使用Debian Linux,但是其他的Linux版本也部分支持)。

微软Azure通过Azure Container Service来支持Kubernetes。然而,从将Kubernetes作为一个托管在Azure上的服务这个角度来说,这不是很“原生”的支持。相反,Kubernetes是由一个Azure资源管理模板部署的。Azure对于其他的容器编排系统(比如Docker Swarm和Mesosphere DC/OS)的支持也是这种思路实现的。如果您在这里提到的任何其他的云中部署Kubernetes,并且希望完全控制它,在Azure虚拟机上安装一个Kubernetes的核心版永远是简单可行的办法。

在各种环境(云端或其他方式)中快速配置一个基础Kubernetes集群的方式就是使用名为Kubernetes Anywhere的项目。此脚本适用于Google Compute Engine,Microsoft Azure和VMware vSphere(需要vCenter)。在每种情况下,它为启动过程提供了一定程度的自动化。
# 您自己的小部分Kubernetes节点
如果你只是在一个像开发机器这样的本地环境中运行Kubernetes,而且你不需要整个Kubernetes全部能力,那么有几种方法可以设置“刚好足够”的Kubernetes来进行使用。

其中一种方式是使用由Kubernetes开发团队本身提供的MiniKube。运行它,您会得到一个单节点Kubernetes集群部署在您选择的虚拟主机上。minikube有几个前提,如kubectl命令行接口和虚拟化环境如VirtualBox,但那些都有现成的二进制,支持MacOS,Linux和Windows。

对于MacOS上的CoreOS用户,有Kubernetes Solo。它运行在一个CoreOS虚拟机上,提供了一个状态栏应用程序实现快速管理。Solo也包括Kubernetes包管理程序Helm(通常是Helm下一级),因此基于Kubernetes的应用程序包更容易获取和设置。
# 玩转您的容器集群
当您的Kubernetes运行起来之后,您就可以运行和管理容器了。通过部署和管理基于很多容器的应用示例的方式,您可以轻松地熟悉容器的操作。以一个现有的基于容器的应用程序demo为例,自己组装它,看看它是如何组成的,部署它,然后逐步修改它,直到满足您的预期。如果您选择通过minikube找到立足点,您可以使用Hello Minikube教程创建Docker容器,将这个运行简单的Node.js应用的容器托管在单节点Kubernetes,以此来演示集群安装和应用部署。一旦您对这些都熟悉了,您就可以替换成自己的容器,并做一些实践性部署。

下一步是部署一个示例应用程序,这个程序类似您可能在生产环境中使用的应用。通过这个应用您可以进一步熟悉Kubernetes的一些高级概念,比如pods(一个或多个容器,包括一个应用程序),service(一组逻辑的Pod),replica sets(提供应用在机器故障时的修复机制)和deployment(应用程序的版本)。揭开WordPress/MySQL示例应用程序的神秘面纱,例如,你看到的将不仅仅是如何将应用部署到Kubernetes,并让这些应用正常运行。您也将看到Kubernets应用涉及的很多概念的实现细节,而这些应用都是满足生产环境要求的。您将学习如何设置持久卷以保存应用程序的状态,如何将Pod暴露给彼此,以及如何通过services与外部世界连在一起,以及如何将应用程序密码和API密钥存储为secrets等等。

Weaveworks有一个示例应用程序,袜子商店,展示了微服务模式如何用来组合Kubernetes中的应用。袜子商店对于熟悉底层技术(比如Node.js,Go kit和Spring Boot)的人来说是最有利的,但主旨超越了特定的框架,而是说明云原生技术。

如果您看了一眼WordPress/MySQL的应用,并想创建一个运行在Kubernetes上的应用来满足您的需求,这种想法基本上是对的。Kubernetes有一个应用程序定义的系统称为Helm,它提供了一种打包、版本管理和共享Kubernetes应用的机制。一些主流的应用程序(GitLab,WordPress)和构建应用程序的模块(MySQL、NGINX)将Helm作为一站式直通kubeapps门户的最佳实践。
# 深入探索Kubernetes
Kubernetes通过强大的抽象能力简化了容器的管理,比如Pod和Service,同事通过label和namespace机制提供了很大的灵活性,label和namespace都可以用来隔离pod,services和deployments(比如开发环境、过渡环境和生产环境负载)。

如果您选择上面的示例的一个,并在多个命名空间中创建不同的实例,那么可以对独立于其他命名空间的组件进行更改。您可以使用deployments,以允许这些更新在给定的命名空间中的多个pod之间滚动进行

比这种练习更进一步的是学习Kubernetes本身如何能够被管理基础设施的工具所驱动。以Puppet为例,有一个用于创建和操纵Kubernetes资源的模块,但是HashiCorp’s Terraform很早就有支持,但是支持方式演变成将Kubernetes作为一种资源进行管理。如果您打算使用这样的资源管理器,请注意不同的工具可能会给表带来不同的预期结果。以Puppet and Terraform为例,默认分别使用可变的和不可变的基础设施。这些哲学层次和行为的差异,如何或轻松,或困难地创建您所需要的Kubernetes。

这个故事,“如何开启Kubernetes之旅”最初发表在InfoWorld

原文链接:How to get started with Kubernetes (翻译:付辉)

Netflix Conductor:一个微服务编排工具

justinfu 发表了文章 • 0 个评论 • 15253 次浏览 • 2017-04-29 08:09 • 来自相关话题

【译者的话】这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发。 【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述 ...查看全部
【译者的话】这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发。

【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述、架构、日志和监控,部署、自动驾驶、服务发现、网络方案等核心机制分析,进阶篇——Kubernetes调度工作原理、资源管理及源码分析等。

Netflix内容平台工程团队运行许多业务流程,这些业务流程是通过在微服务上执行异步编排任务来驱动的。其中一些流程运行时长多达数天。这些流程在让一切准备好,以呈现给全球用户的过程中,起到了至关重要的作用。

这些流程的几个例子:

+ 整合工作室合作伙伴的内容摄取
+ 从我们的合作伙伴摄入基于IMF的内容
+ 在Netflix中设置新的标题的过程
+ 内容摄取,编码和部署到CDN

按照传统做法,这其中一些进程已经使用发布/订阅模式,直接进行REST调用以及使用数据库来管理状态的组合进行了自组织的编排。然而,随着微服务数量的增长和流程的复杂性不断增加,如果没有中央协调人员,这些分布式工作流程的可见性将变得困难。

我们构建了“作为业务流程引擎”的Conductor,以满足以下要求,消除在应用程序中对模板的需求,并提供流程相关的执行动作:

+ 以蓝图为主,基于JSON DSL的蓝图定义了执行流程;
+ 跟踪和管理工作流;
+ 能够暂停,恢复和重新启动流程;
+ 用户界面可视化流程;
+ 能够在需要时同步处理所有任务;
+ 能够扩展到数百万个同时运行的流程;
+ 由客户抽象的排队服务提供后端支持;
+ 能够通过HTTP或其他传输操作,例如gRPC;

Conductor是为满足上述需求而建立的,目前已在Netflix上使用。到目前为止,它已经帮助协调了260多万个流程流程,从简单的线性工作流程到跨越多天运行的非常复杂的动态工作流程。

今天,我们是开放Conductor给更广泛的社区,希望从具有相似需求的其他人那里学习,增强其能力。您可以在这里找到Conductor的开发人员文档。
# 为什么不对等编排?
通过对等任务编排,我们发现随着业务需求和复杂性的增长难以扩展。发布/订阅模式为最简单的流程工作,但很快突出了与该方法相关的一些问题:

+ 流程“嵌入”在多个应用程序的代码中;
+ 通常,关于输入/输出,SLA等的紧耦合和不确定性,使其难以适应不断变化的需求;
+ 不清楚当前执行的任务属于整个流程的哪个阶段;

# 为什么是微服务?
在微服务世界中,许多业务流程自动化是通过协调服务来驱动的。Conductor可以在服务之间进行协调,同时提供对它们的相互作用的控制和可见性。有能力在微服务之间进行协调,也帮助我们利用现有服务来构建新流程或更新现有流程,以便使用Conductor非常快速,有效地提供了更容易采用的方法。
# 架构概览
Netflix_Architect.png

在发动机的核心是一个状态机服务又名的决策服务。随着工作流事件的发生(例如任务完成,故障等),决策者将工作流程蓝图与工作流程的当前状态相结合,识别下一个状态,并安排适当的任务和/或更新工作流的状态。

决策者使用分布式队列来管理计划任务。我们一直在Dynomite之上使用dyno-queue来管理分布式延迟队列。队列“食谱”今年早些时候开放,这里是博客文章。
## 任务执行者的实现
由Worker实现的Tasks通过API层进行通信。Worker通过实现可由业务流程引擎调用的REST端点或实现定期检查待处理任务的轮询机制来实现此目的。Worker是幂等无状态的功能。轮询模型允许我们处理worker背后的压力,并在可能的情况下根据队列深度提供自动可扩展性。Conductor提供API来检查可用于自动调整工作实例的每个工作人员的工作负载大小。
Worker_Communication_With_Engine.png

## API层
API通过HTTP协议公开 - 使用HTTP允许轻松地与不同的客户端集成。然而,添加另一个协议(例如,gRPC)应该也是可能的并且相对简单。
## 存储
我们使用Dynomite“作为存储引擎”以及Elasticsearch来索引执行流程。存储API可插拔,可适用于各种存储系统,包括传统的RDBMS或Apache Cassandra,如no-sql存储。
# 核心概念
## 工作流
工作流程使用基于JSON的DSL进行定义。工作流程蓝图定义了一系列需要执行的任务。每个任务都是控制任务(例如,分支,连接,决策,子工作流程等)或工作任务。工作流定义被版本化,提供管理升级和迁移的灵活性。一个工作流定义:
 {
"name": "workflow_name",
"description": "Description of workflow",
"version": 1,
"tasks": [
{
"name": "name_of_task",
"taskReferenceName": "ref_name_unique_within_blueprint",
"inputParameters": {
"movieId": "${workflow.input.movieId}",
"url": "${workflow.input.fileLocation}"
},
"type": "SIMPLE",
... (any other task specific parameters)
},
{}
...
],
"outputParameters": {
"encoded_url": "${encode.output.location}"
}
}

## 任务定义
每个任务的行为由其称为任务定义的模板控制。任务定义为每个任务提供控制参数,例如超时,重试策略等。任务可以是由应用程序实现的工作任务或由业务流程服务器执行的系统任务。Conductor提供开箱即用的系统任务,如决策,叉,连接,子工作流程以及允许插入自定义系统任务的SPI。我们增加了对HTTP任务的支持,有助于调用REST服务。一个任务的定义如下:
 {
"name": "encode_task",
"retryCount": 3,
"timeoutSeconds": 1200,
"inputKeys": [
"sourceRequestId",
"qcElementType"
],
"outputKeys": [
"state",
"skipped",
"result"
],
"timeoutPolicy": "TIME_OUT_WF",
"retryLogic": "FIXED",
"retryDelaySeconds": 600,
"responseTimeoutSeconds": 3600
}

## 输入/输出
任务的输入是一种的映射,即工作流实例化或其他任务的输出的一部分。这种配置允许将来自工作流或其他任务的输入/输出作为可以随后作用于其的任务的输入。例如,可以将编码任务的输出提供给发布任务作为部署到CDN的输入。一个输入的定义如下:
 {
"name": "name_of_task",
"taskReferenceName": "ref_name_unique_within_blueprint",
"inputParameters": {
"movieId": "${workflow.input.movieId}",
"url": "${workflow.input.fileLocation}"
},
"type": "SIMPLE"
}

# 一个案例
下面是一个非常简单的编码和发布流程:
encode-deploy-flow.png

共有3个工作任务和一个控制任务(错误)涉及:

  1. 内容检查:检查输入位置的文件是否正确/完整
  2. 编码:生成视频编码
  3. 发布:发布到CDN

这三个任务由不同的worker实现,这些worker使用任务API轮询待处理的任务。这些是理想的幂等任务,对任务的输入进行操作,执行工作并更新状态。

每个任务完成后,决策者根据蓝图(对应于工作流实例的版本)评估工作流实例的状态,并标识要排定的下一组任务,如果完成所有任务,则完成工作流。
# UI
UI是监控和排除工作流执行的主要机制。 UI通过允许基于包括输入/​​输出参数在内的各种参数的搜索来提供对流程的非常需要的可见性,并提供蓝图的可视化呈现以及所采用的路径,以更好地了解流程执行。对于每个工作流实例,UI提供每个任务执行的详细信息,具体如下:

+ 任务安排的时间戳,由worker获取并完成。
+ 如果任务失败,失败的原因。
+ 重试次数
+ 执行任务的主机。
+ 在任务完成后提供给任务和输出的输入。

下图是UI的一个样例:
Task-UI.png


原文链接:Netflix Conductor : A microservices orchestrator(翻译:付辉)

业务逻辑的演进——从单体应用到微服务再到函数

justinfu 发表了文章 • 0 个评论 • 3251 次浏览 • 2017-03-31 08:45 • 来自相关话题

【译者的话】这篇文章介绍了业务逻辑从单体应用到微服务模式,再到事件驱动函数模型的进化过程。从原理上剖析了每一次进化的动机,为我们揭示了变化背后的深层次原因,非常具有启发性。 【上海站|3天烧脑式Spring Cloud训练营】培训内容 ...查看全部
【译者的话】这篇文章介绍了业务逻辑从单体应用到微服务模式,再到事件驱动函数模型的进化过程。从原理上剖析了每一次进化的动机,为我们揭示了变化背后的深层次原因,非常具有启发性。

【上海站|3天烧脑式Spring Cloud训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

基础技术在不断进步,正在促进事件驱动函数模型的发展,于此同时也在快速提升业务逻辑的`时效`。

更新:感谢读者的阅读和反馈, 关于这篇文章中阐述的观点,我在microxchg录制了一个视频,大家可以点击这里观看。



运行应用软件的目的在于提供某种业务价值。价值通过创建和使用业务逻辑来传递,以便它可以为一些用户提供服务。从开始创建业务逻辑到最终交付,为用户提供服务之间的时间称之为`时效`。提供业务价值的成本等于创建业务逻辑的成本与交付业务逻辑的成本之和。

过去成本高昂、效率是主要考虑因素,高`时效`被认为是常态。今天,随着技术进步和成本的降低,在竞争压力的推动下,组织在评估和优化企业流程的时候,`时效`正在成为主要考察指标。换句话说,为了提升投资回报率,您需要找到增加回报率的方法,提前获得回报或减少投资。

问题的核心在于,当成本占主导地位时,随着成本的降低和软件的影响力的增加,焦点必然转向早日得到回报。

随着技术在过去十年的发展,我们已经看到从单体应用程序到微型服务的发展,现在看到由AWS Lambda领导的无服务器架构、事件驱动函数模式的兴起。是什么因素推动了这种演变?低延迟消息传递使得从单体应用转到微服务,低延迟配置使得能够转移到Lambda。

在十年前,由于时间的限制,单体应用是交付业务逻辑的最佳方式。在五年前,由于限制因素的改变,微服务成为了最好的交付模式。新的应用程序开始建立在微服务架构上,而在过去的几年中,工具和开发实践已经全面支持微服务。时至今日,事件驱动函数模式再次发生了改变,因为潜在的限制已经发生变化,成本降低了,`时效`的根本改善也是可能的。

接下来,我们将详细介绍这种变化的不同维度:交付技术,硬件性能和组织架构实践,并了解它们如何结合起来推动这一变革。

在最开始的时候,交付成本是主要的考虑因素。采购、配置和部署硬件需要花费很长的时间,并且软件安装也是纯手动操作。为了优化交付,每个版本中包含大量业务逻辑,在这些业务逻辑上摊销过高的成本。与此同时,发布周期也不频繁,对于很多组织来说,`时效`通常数月有余。由于基础设施的变更交付周期很长,所以有必要提前预先提供额外的能力,这导致非常低的平均利用率。

降低交付成本的第一步将重点放在流程自动化上。许多组织开发了自定义脚本来部署新硬件、安装和更新应用程序。最终像Puppet和Chef这样常见的框架变得流行起来,“基础设施即代码”加速了更新的交付。DevOps运动开始于运营团队采用敏捷软件开发实践,并与开发人员紧密合作,以此将`时效`从几个月减少到几天。脚本可以改变已有的基础设施及应用,但快速增长的业务或具有不可预测的工作负载,正在努力寻求新的容量(译者注:这里的容量指的是新的计算资源),通过调用Amazon EC2弹性扩容API可以解决这个问题。当开发人员有能力使用Web服务直接自动化许多操作任务时,新一轮全新的DevOps即将到来。按需部署、按时付费的能力可以实现更高的平均利用率,并自动处理突然爆发的工作负载。

当Docker将容器变得“老少皆宜”时,另一波提升交付的浪潮来到了。Docker提供了一种方便的打包格式,这种格式包括一组固定的依赖关系,一个比进程隔离性更强、但弱于虚拟机的运行时环境。容器能够在秒级时间内启动,并且节省大量的内存占用空间。通过将许多容器打包到一个实例上,可以将运行时间从几个小时缩短到数分钟甚至数秒,资源利用率也大幅提升。基于容器的持续交付工具链也提升了开发人员的工作效率,缩短了交付时间。当有大量可预测的工作负载时,容器可以运行在高利用率水平,但是大多数时候工作负载是不可预测的,要么处于峰值要么处于低谷。例如,工作场所使用的应用程序只在一周168小时内的40个小时中使用。为了保持高可用性,通常将应用程序实例扩展到三个可用区域,甚至每个区域需要多个实例。因此一个服务最少需要六个实例。如果我们想缩容到0个实例,那么我们需要找到一种机制,在事件发生时启动应用的一个部分,当事件完成后则关停这部分应用。这是AWS Lambda功能的关键部分,它能在0.1秒的时间内对正在使用的计算资源进行扩容,并根据需要从零扩展到非常高的容量,从而保证峰值和低谷时的工作负载都是有效的100%利用率。从而没有必要考虑如何配置服务器,这就是为什么这通常被称为无服务器模式。

交付技术的进步为改进`时效`提供了垫脚石,但是在过去十年中,还有其他潜在的变化导致了最佳实践的一系列转型。

业务逻辑的大小取决于在满足服务延迟要求的条件下,计算资源(CPU/内存/网络/磁盘)的成本,以及访问相应资源的响应时间。

对于终端用户来说,对于业务逻辑响应时间的要求并没有太大变化。在过去十多年里,基础技术发生了翻天覆地的变化,然而对响应时间的感知和期望确一直基本没变。CPU的计算速度在过去十年中增长缓慢,时钟频率始终在几GHz左右,然而芯片缓存却增长很快,而且CPU核数也在不断增加。内存速度和大小的提升也较为缓慢。

网络现在的传输速度相当快了,常见的从1GBit到10GBit,再到现在的25GBit(正如James Hamilton在他的AWS re:Invent 2016主题演讲中所解释),而且软件协议的效率更高。当通常的做法是通过1GBit网络发送XML有效负载时,通信开销将业务逻辑限制在与大型单体服务共同位置,并直接连接到数据库。十年以后,在25GBit网络上的编码效率将提升一个数量级,这意味着通信成本会降低两个数量级以上。换句话说,十年前服务之间发送和处理一条消息的时间,如今可以达到100至1000条。这是从单体应用架构转移到其他架构模式的关键推动因素。

存储和数据库在过去十年中也经历了一场革命。单体应用将业务逻辑映射到基于复杂关系型数据库模式的事务,这些数据库模式链接了很多的表,并且提供统一的原子更新。十年前,最佳实践是通过存储区域网络建立少数的大型集中式关系数据库,这些数据库后端连接着价格昂贵的磁盘阵列,磁盘与数据库之间建立巨大的缓存池。

今天高速缓存的磁盘已被固态磁盘所取代。不同之处在于读取速度从缓慢、昂贵和不可预测(因为缓存命中率不一致)变得持续快速,且几乎无限制。由于磨损均衡算法和其他影响,写入和更新从缓存磁盘的快速迁移到固态磁盘的具有不可预测性。由于众多原因,新的“NoSQL”数据库架构已经变得流行,但我们关注的只有两点:简单的数据模型和充分利用了固态存储的优势。简单的模式强制将在同一关系数据库中链接在一起的数据表分离成多个独立的NoSQL数据库,从而推动业务逻辑的分散化。Amazon DynamoDB数据存储服务从一开始就设计为只在固态磁盘上运行,为请求提供极其一致的低延迟。Apache Cassandra的存储模型生成大量随机读取,并且很少进行大量写入,无更新,非常适合固态磁盘。与关系数据库相比,NoSQL数据库提供简单但极具成本效益,高可用性和可扩展性的数据库,并且具有非常低的延迟。NoSQL数据库的普及率快速增长是单体应用架构模式转移的另一个关键推动因素。其余关系型的主要模式被剔除,或者变得更容易扩展,并被迁移到诸如Amazon的RDS和Aurora之类的服务中。

当我们看IT的变化时,常常谈论“人,过程和技术”。我们刚刚看到技术如何将利用率和部署速度提高到了AWS Lambda的极限,在几分之一秒内实现了所部署的应用100%利用率。技术也将单体逻辑代码分解成数以百计的微服务/函数,并将单体的RDBMS拆分为许多简单可扩展和高可用性的NoSQL和关系数据存储。

过去十年,“人与过程”也发生了巨大变化。让我们考虑一下由100位开发人员组成的一个团队。为了协调,管理测试并且每隔几个月向这个“巨型逻辑”提交更新,通常有更多的人运行这个过程,而不是编写代码。通常需要两倍多的项目经理,测试人员,DBA,运维人员等。一成不变的组织架构,一切由各种工作任务单所驱动。管理的层次结构要求每个人写每周报告和参加许多汇报工作状态的会议,研发人员需要抽出时间来编码实际的业务逻辑!

DevOps实践,微服务架构和云部署三者与持续交付、紧凑的“两个披萨团队”模式紧密合作,大大减少了任务单,会议和管理成本。小团队的开发人员和产品经理在需要时独立地编写,测试和部署自己的微服务。开发人员的比率发生逆转,从原来的50个经理变为100个开发。每个开发者在会议中花更少的时间和等待任务单,这就获得了两倍的时间,而由此带来的`时效`提升可高达百倍。这个变化的最直观效果就是从做项目转向做产品。大量的项目经理被更少的产品经理所取代。在我所见过的某些案例中,150人输出了原来300多人工作成果的两倍。投资一半,但得到双倍回报,`时效`提升一百倍。许多组织一直在进行这种转型,并有类似改进的实例。

基于Lambda的应用程序由几乎完全是业务逻辑的单个事件驱动功能构成,并且有更少的模版化的内容和平台代码需要管理。这是早期的情况,但这似乎正在推动另一个根本性的变化。开发人员的小团队将在短短几天内从零开始就开始准备应用程序。他们正在使用短小精悍的功能和事件将强大的API驱动的数据存储和服务粘合在一起。已完成的应用程序已经具有高可用性和可扩展性,高利用率,低成本和快速部署。作为一个类比,考虑到一堆模型房子从一块粘土需要多长时间开始,而不是一堆乐高砖。如果有足够的时间,您可以使用这种“粘土”创造任何东西,它具有表现力和创造性,它甚至还可以反其道而行之,创造单体应用(俗称“大泥巴球”)。乐高砖组合在一起,构成了一个功能有限的,块状的模型房屋,在一定的时间内也是很容易扩展和修改的。此外,还有其他的“砖块”有点像乐高砖,但它们并不是主流,任何类型的基于“标准砖”的系统将比“定制粘土”快得多。如果开发人员的生产力能够提高一个数量级,那么我先前提到的100个开发人员的案例中,他们开发的单体应用可以重写,并且在几周之内被10名开发人员组成的团队所取代。如果你怀疑这是否会奏效,大可做一个实验来验证,这个实验的成本还是很低的。事件驱动函数的调用延迟是限制复杂应用程序的关键限制之一,但随着时间的推移,这些延迟正在减少。

我真正的关注点在于已经存在的单体应用是应该整体搬到云环境中,还是应该重写这个应用这个决定性的ROI阀值。应用从数据中心上云的最佳实践是,将扩展性要求高和经常需要修改的单体应用重写成微服务,本身就很小的应用和很少需要修改的应用采取原封不动的策略。我认为AWS Lambda改变了这个决策方式,它会是新的、试验性质的应用的首选方式。这种方式很值得一试,因为可以做多次的重写。

我对您的经验非常感兴趣,请让我了解在您的环境中,您是如何看待`时效`的。

原文链接:Evolution of Business Logic from Monoliths through Microservices, to Functions (翻译:付辉)

微服务化改造系列之四:授权中心

emac 发表了文章 • 2 个评论 • 8456 次浏览 • 2016-12-04 16:48 • 来自相关话题

前情概要: > > - 微服务化改造系列之一:总览 > - 微服务化改造系列之二:服务注册中心 > - 微服务化改造系列之三:配置中心 # 授权中心概述 这篇文章是微服务化 ...查看全部

前情概要:
>
> - 微服务化改造系列之一:总览
> - 微服务化改造系列之二:服务注册中心
> - 微服务化改造系列之三:配置中心



# 授权中心概述
这篇文章是微服务化改造系列的第四篇,主题是授权中心。有了服务注册中心和配置中心,下一步应该就可以发起服务调用了吧?Wait, 还有一个关键问题要解决。不同于单体应用内部的方法调用,服务调用存在一个服务授权的概念。打个比方,原本一家三兄弟住一屋,每次上山打猎喊一声就行,后来三兄弟分了家,再打猎就要挨家挨户敲门了。这一敲一应就是所谓的服务授权。

严格来说,服务授权包含鉴权(Authentication)和授权(Authorization)两部分。鉴权解决的是调用方身份识别的问题,即敲门的是谁。授权解决的是调用是否被允许的问题,即让不让进门。两者一先一后,缺一不可。为避免歧义,如不特殊指明,下文所述授权都是宽泛意义上的授权,即包含了鉴权。

常见的服务授权有三种,简单授权,协议授权和中央授权。

  • 简单授权:服务提供方并不进行真正的授权,而是依赖于外部环境进行自动授权,比如IP地址白名单,内网域名等。这就好比三兄弟互相留了一个后门。
  • 协议授权:服务提供方和服务调用方事先约定一个密钥,服务调用方每次发起服务调用请求时,用约定的密钥对请求内容进行加密生成鉴权头(包含调用方唯一识别ID),服务提供方收到请求后,根据鉴权头找到相应的密钥对请求进行鉴权,鉴权通过后再决定是否授权此次调用。这就好比三兄弟之间约定敲一声是大哥,敲两声是二哥,敲三声是三弟。
  • 中央授权:引入独立的授权中心,服务调用方每次发起服务调用请求时,先从授权中心获取一个授权码,然后附在原始请求上一起发给服务提供方,提供方收到请求后,先通过授权中心将授权码还原成调用方身份信息和相应的权限列表,然后决定是否授权此次调用。这就好比三兄弟每家家门口安装了一个110联网的指纹识别器,通过远程指纹识别敲门人的身份。
一般来说,简单授权在业务规则简单、安全性要求不高的场景下用的比较多。而协议授权,比较适用于点对点或者C/S架构的服务调用场景,比如Amazon S3 API。对于网状结构的微服务而言,中央授权是三种方式中最适合也是最灵活的选择:[list=1]
  • 简化了服务提供方的实现,让提供方专注于权限设计而非实现。
  • 更重要的是提供了一套独立于服务提供方和服务调用方的授权机制,无需重新发布服务,只要在授权中心修改服务授权规则,就可以影响后续的服务调用。
  • ## OAuth说起具体的授权协议,很多人第一反应就是OAuth。事实上也的确如此,很多互联网公司的开放平台都是基于OAuth协议实现的,比如Google APIs, 微信网页授权接口。一次标准的OAuth授权过程如下:
    oauth2.png
    对应到微服务场景,服务提供方相当于上图中的Resource Server,服务调用方相当于Client,而授权中心相当于Authorization Server和Resource Owner的合体。想了解更多关于OAuth的信息,可移步OAuth2或者OAuth2中文版。## Beared Token在标准的OAuth授权过程中,Resource Server收到Client发来的请求后,需要到Authorization Server验证Access Token,并获取Client的进一步信息。通过OAuth 2.0版本引入中的Beared Token,我们可以省去这一次调用,将Client信息存入Access Token,并在Resource Server端完成Access Token的鉴权。主流的Beared Token有SAMLJWT两种格式,SAML基于XML,而JWT基于JSON。由于大多数微服务都使用JSON作为序列化格式,JWT使用的更为广泛。# 框架选型在选型OAuth框架时,我主要调研了CAS,Apache Oltu,Spring Security OAuthOAuth-Apis,对比如下:
    oauth2-frameworks.png
    不考虑实际业务场景,CAS和Spring Security OAuth相对另外两种框架,无论是集成成本还是可扩展性,都有明显优势。前文提到,由于我们选用了Spring Boot作为统一的微服务实现框架,Spring Security OAuth是更自然的选择,并且维护成本相对低一些(服务端)。# 最终方案最终我们基于Spring Security OAuth框架实现了自己的服务授权中心,鉴权部分做的比较简单,目前只支持私网认证。大致的服务授权流程如下:
    oauth2-interaction.png
    oauth2-sequence.png
    值得一提的是,除了服务调用,我们的服务授权中心还增加了SSO的支持,通过微信企业号实现各个服务后台的单点登录/登出,以后有机会再详细介绍。# 冰山一角至此,这个微服务化改造系列就算告一段落,等以后有了更多的积累,我会继续写下去。微服务是一个很大的话题,自Martin Fowler于2014年3月提出以来,愈演愈热,并跟另一个话题容器化一起开创了一个全新的DevOps时代,引领了国内外大大小小各个互联网公司的技术走向,也影响了我们这一代程序员尤其是后端和运维的思维方式。从这个角度说,我写这个微服务化改造系列文章也是偶然中的必然,希望能给读过这些文章的你带来一些新的启发和思考。如果你对微服务也感兴趣或者有一些心得想跟我交流,欢迎在赞赏榜上留下你的微信号。

    少年读书如隙中窥月,中年读书如庭中望月,老年读书如台上玩月,皆以阅历之浅深为所得之浅深耳。-- 张潮 《幽梦影》

    # 参考

    微服务化改造系列之三:配置中心

    emac 发表了文章 • 0 个评论 • 6277 次浏览 • 2016-11-30 17:22 • 来自相关话题

    前情概要: - 微服务化改造系列之一:总览 > - 微服务化改造系列之二:服务注册中心 # 配置中心概述 这篇文章是微服务化改造系列的第三篇,主题是配置中心。上一篇我们谈到服务注册中 ...查看全部

    前情概要:



    - 微服务化改造系列之一:总览
    > - 微服务化改造系列之二:服务注册中心



    # 配置中心概述
    这篇文章是微服务化改造系列的第三篇,主题是配置中心。上一篇我们谈到服务注册中心,即通过提供某种注册和发现的机制,解决服务互通的问题。那么问题来了,一个服务如何知道服务注册中心的地址呢?这就涉及到服务配置了。我们知道,大至一个PaaS平台,小至一个缓存框架,一般都依赖于特定的配置以正常提供服务,微服务也不例外。
    ## 配置分类

    • 按配置的来源划分,主要有源代码(俗称hard-code),文件,数据库和远程调用。
    • 按配置的适用环境划分,可分为开发环境,测试环境,预发布环境,生产环境等。
    • 按配置的集成阶段划分,可分为编译时,打包时和运行时。编译时,最常见的有两种,一是源代码级的配置,二是把配置文件和源代码一起提交到代码仓库中。打包时,即在应用打包阶段通过某种方式将配置(一般是文件形式)打入最终的应用包中。运行时,是指应用启动前并不知道具体的配置,而是在启动时,先从本地或者远程获取配置,然后再正常启动。
    • 按配置的加载方式划分,可分为单次加载型配置和动态加载型配置。
    ## 演变随着业务复杂度的上升和技术架构的演变,对应用的配置方式也提出了越来越高的要求。一个典型的演变过程往往是这样的,起初所有配置跟源代码一起放在代码仓库中;之后出于安全性的考虑,将配置文件从代码仓库中分离出来,或者放在CI服务器上通过打包脚本打入应用包中,或者直接放到运行应用的服务器的特定目录下,剩下的非文件形式的关键配置则存入数据库中。上述这种方式,在单体应用阶段非常常见,也往往可以运行的很好,但到了微服务阶段,面对爆发式增长的应用数量和服务器数量,就显得无能为力了。这时,就轮到配置中心大显身手了。那什么是配置中心?简单来说,就是一种统一管理各种应用配置的基础服务组件。# 可选框架选型一个合格的配置中心,至少需要满足如下4个核心需求:
    • 非开发环境下应用配置的保密性,避免将关键配置写入源代码
    • 不同部署环境下应用配置的隔离性,比如非生产环境的配置不能用于生产环境
    • 同一部署环境下的服务器应用配置的一致性,即所有服务器使用同一份配置
    • 分布式环境下应用配置的可管理性,即提供远程管理配置的能力
    现在开源社区主流的配置中心框架有Spring Cloud Config和disconf,两者都满足了上述4个核心需求,但又有所区别。## Spring Cloud Config
    spring-cloud-config.png
    Spring Cloud Config可以说是一个为Spring量身定做的轻量级配置中心,巧妙的将应用运行环境映射为profile,应用版本映射为label。在服务端,基于特定的外部系统(Git、文件系统或者Vault)存储和管理应用配置;在客户端,利用强大的Spring配置系统,在运行时加载应用配置。## disconf
    disconf.jpg
    disconf是前百度资深研发工程师廖绮绮的开源作品。在服务端,提供了完善的操作界面管理各种运行环境,应用和配置文件;在客户端,深度集成Spring,通过Spring AOP实现应用配置的自动加载和刷新。# 方案选型不管是Spring Cloud Config还是disconf,默认提供的客户端都深度绑定了Spring框架,这对非Spring应用而言无疑增加了集成成本,即便它们都提供了获取应用配置的API。最终我们还是选用了微服务化改造之前自研的Matrix作为配置中心,一方面,可以保持新老系统使用同一套配置服务,降低维护成本,另一方面,在满足4个核心需求的前提下,Matrix还提供了一些独有的能力。
    • 分离配置文件和配置项。对于配置文件,通过各类配套打包插件(sbt, maven, gradle),在打包时将配置文件打入应用包中,同时最小化对CI的侵入性;对于配置项,提供SDK,帮助应用从服务端获取配置项,同时支持简单的缓存机制。
    • 增加应用版本维度,即对于同一应用,可以在服务端针对不同版本或版本区间维护不同的应用配置。
    • 应用配置的版本化支持,类似于Git,可以将任一应用配置回退到任一历史版本。
    进一步信息可参考我之前写的Matrix设计文档
    matrix.png
    Matrix架构图下一篇我将给大家介绍微服务架构的另一个基础组件——授权中心,敬请期待!#参考

    用微服务创建可扩展API

    hokingyang 发表了文章 • 0 个评论 • 2491 次浏览 • 2016-07-11 13:44 • 来自相关话题

    【编者的话】想尝试用微服务创建一个API吗?微服务很适合用于创建API,开发人员可以集中精力于创建小巧,相互无关的组件,组合成一个特定API调用;可以用不同语言开发不同服务点(endpoint),提供不同服务级别(SLAs),甚至独立扩展微服务,可以参考我的某 ...查看全部
    【编者的话】想尝试用微服务创建一个API吗?微服务很适合用于创建API,开发人员可以集中精力于创建小巧,相互无关的组件,组合成一个特定API调用;可以用不同语言开发不同服务点(endpoint),提供不同服务级别(SLAs),甚至独立扩展微服务,可以参考我的某些微服务讲座。

    讲座视频

    我也讲过在一个Kubernetes集群内部署和运行不同服务是非常容易的,如下代码演示了如何简单发起一个前端和后端服务,他们互相通讯并且独立扩展。这个示例唯一没有展示出来的是这个服务是用不同语言开发的,对终端用户无缝透明地工作。最近,我的同事Sara Robinson和我演示了一个基于NGINX如何创建这种服务,我们开源了代码。耐心读完这篇深入报道(报道很长,可以直接跳到自己关心的部分)。这个演示依赖于Kubernetes和Google Container Engine运行这个集群。我们开始之前,确保已经创建了一个Google Cloud project,如果需要从Kubernetes开始,可以查看这篇博客
    #为什么需要Kubernetes
    Sara和我用不同语言进行编程,每种语言都有最佳适用范围。例如,Google内部使用C++、Java、Python和Go组合的开发环境。在有Containers和Kubernetes之前,这意味着为不同开发栈设置四种不同服务器,也就是一种Ops很高的架构。如果想整合服务器,就需要在同一台服务器上安装不同开发栈,但是更新一种栈则需要影响其他栈,扩展系统编程很大挑战,一些看起来简单的操作变的比较复杂。基于这种场景,很多人不得不只选择一种开发栈。有了容器,这种两难境地彻底改变。容器可以在机器和代码之间进行了抽象,开发者在任何机器上不做明显配置就可以运行任何开发栈。Kubernetes自动编排这些作业,开发者可以部署管理所有这些容器而不需要ssh登进这些机器。
    #​创建一个Kubernetes集群
    先创建一个Kubernetes集群运行应用。确保已经安装了Google Cloud SDK,或者使用Cloud Shell(如果对Google Cloud还比较陌生,可以尝试试用版:https://cloud.google.com/free-trial/)。

    我会使用标准三节点集群。
    $ gcloud container clusters create mycluster

    登陆
    $ gcloud container clusters get-credentials mycluster

    集群就简单生成了。
    #微服务代码样例
    我们要部署的代码非常简单。用每种语言,我们都实现了某种字符操作,我们有四种不同服务:

    Ruby - Arrayify
    Hello World → [H,e,l,l,o, ,W,o,r,l,d]

    Python - Reverse
    Hello World → dlroW olleH

    Node.js - To Lower
    Hello World → hello world

    Go - To Upper
    Hello World → HELLO WORLD

    是不是很简单?
    #容器化代码
    下一步是把如上代码放到容器中。容器会帮助将所有依赖包打包为一起并且以可发布方式发行。我们会使用Docker来实现。确保安装了Docker或者使用Cloud Shell。Docker使得创建容器非常简单,并且确保环境一致。如果从未使用过Docker,可以先阅读以下讨论如何在Docker中运行MEAN栈)的博客

    首先是创建叫做Dockerfile的配置文件,如下是我们使用的Dockerfiles。​

    Ruby:
    FROM ruby:2.3.0-onbuild
    CMD ["ruby", "./arrayify.rb"]

    Python:
    FROM python:2.7.11-onbuild
    CMD [ "python", "./app.py" ]

    Node.js:
    FROM node:5.7.0-onbuild

    Go:
    FROM golang:1.6-onbuild

    这些就是所需的所有配置文件了。你的依赖包可能会复杂些,其实Dockerfile的基本概念就是写下需要在Linux中运行的命令,指出哪些文件需要挂载或者copy到容器中。可以从这儿学习更多。

    创建应用,需要在包含Dockerfile的目录下运行docker build命令。开发者可以给这些影响打上标签(tag),以便安全地使用Google Container Registry保存在云端。
    $ docker build -t 
    gcr.io//: .

    用容器名(例如reverser)以及版本(例如0.1)替换Google Cloud Project ID,从西面开始,我会将gcr.io//: 用 开代替。为以上四个微服务都执行以上命令,就创建容器完毕。可以用如下命令测试:
    $ docker run -ti -p 8080:80 

    如果使用Linux,可以访问localhost:8080来使用微服务。如果不使用linux,可以使用docker-machine运行本机Docker引擎(很快Mac和Windows会自带Docker功能)。通过docker-machine,能得到实例名:
    $ docker-machine list

    并且得到机器IP地址:
    $ docker-machine ip 

    此时应当可以看到如下显示:
    图一.png

    #​使用Google Container Engine部署容器
    接下来需要部署他们。首先将容器从本机拷贝到云端。
    $ gcloud docker push 

    这条命令会将本地映像推送到集群访问的私有代码池(repository),记住要推送四次,然后就可以从Container Registry页面看到并且管理所有推送的容器了。下面需要部署容器到集群,最容易的方式是运行一下命令:
    $ kubectl run \

    --image= \
    --port=80

    这条命令将你的容器以Kubernetes部署方式部署为一个实例,如果发生任何事情都将会重启或者重新调度容器。一篇之前的博客讨论过复制控制(部署的老版本名词)以及为什么很重要。

    你可以在这停止了,但是我想还是继续为我的部署生成几个配置文件因为后面会比较容易记住我做了什么修改。

    如下是我用于arraify微服务的YAML文件,给部署一个名字叫arrayify,规定了复制次数(3),一起容器名和开放端口。
    apiVersion: extensions/v1beta1

    kind: Deployment

    metadata:

    name: arrayify

    spec:

    replicas: 3

    template:

    metadata:

    labels:

    name: arrayify-pods

    spec:

    containers:

    - image:

    name: arrayify-container

    imagePullPolicy: Always

    ports:

    - containerPort: 80

    name: http-server

    保存文件叫做“deployment.yaml”,然后部署它。
    $ kubectl apply -f deployment.yaml

    为四个微服务都重复以上步骤,每个微服务都生成yaml文件,改变容器映像和标签(一般就是将arrayify替换为其它对应名字)。此刻,可以看到集群内所有部署和容器。
    $ kubectl get deployments

    图二.png

    $ kubectl get pods

    图三.png

    #发布微服务
    如果你读了我之前一篇博客,那么就会知道下一步就是为每个微服务创建一个Kubernetes服务,这会创建一个稳定的服务点和每个微服务的负载均衡。然而,并不会希望为每个微服务都对外界开放独自的服务。每个微服务都是这个API的一部分,如果你分别开放每个微服务,每个微服务将会有各自的IP地址,这绝对不是我们想看到的。相反,可以使用NGINX来代理微服务实现唯一服务点。我会使用NGINX+,是一个付费软件,但是开源版工作也很不错。

    NGINX可以做很多需要创建可扩展API的事情。可以设置为API网关,可以很好控制API粒度,包括rate limiting、security、access control和其它。我会使用很多基础NGI配置,这样大家可以直接使用它们。
    #创建内部服务
    第一步是可以用NGINX代理。可以参考如下arrayify微服务代码:
    apiVersion: v1


    kind: Service


    metadata:


    name: arrayify


    spec:


    ports:


    - port: 80


    targetPort: 80


    protocol: TCP


    selector:

    name: arrayify-pods

    服务目标是所有带“arrayify-pods”标签pod上的端口80,保存此文件为"service.yaml",然后用如下命令部署:
     $ kubectl create -f service.yaml 

    图四.png

    为所有四个微服务重复以上过程,创建文件,改变标签(一般就是替代arrayify)。此时,可以看见集群内运行的所有服务:
    $ kubectl get svc

    #配置NGINX
    下一步是配置NGINX代理微服务。可以看看如下目录NGINX folder in GitHub。我们会详细讲解如何配置nginx.conf。

    首先看第一行:
    resolver 10.11.240.10 valid=5s;

    这一行定义NGINX用来搜索微服务的DNS服务,对集群来说可能并不是必须的,但是包含这一行却是很安全的。你可能很奇怪IP地址从哪里来,其实是Kubernetes内置的DNS服务,如果你自己有DNS服务,也可以用如下命令获得IP地址:
    $ kubectl get svc kube-dns --namespace=kube-system 

    图五.png

    下一步,需要设置upstreams(实现同一功能的服务器集合,例如一个微服务),因为可以使用DNS,因此很容易搭建,参见如下arrayify微服务的upstream:
    upstream arrayify-backend {

    zone arrayify-backend 64k;

    server arrayify.default.svc.cluster.local resolve;

    }

    Arrayify.default.svc.cluster.local是Kubernetes服务的全名;为四个微服务重复以上过程(一般就是讲arrayify替换为其它名字)。注意server字段,这里会告诉NGINX哪个路径可以重新映射到哪个微服务:
    ​server {

    listen 80;

    status_zone backend-servers;

    location /arrayify/ {

    proxy_pass http://arrayify-backend/;

    }

    }

    这里,告诉NGINX任何一/arrayify/开始的服务请求应该被转发到arrayify微服务。为其它微服务创建一个字段(一般就是替换arrayify为其它微服务名字),可以参考完整nginx.conf。然后跟推送其它微服务一样,推送客制化NGINX映像。也可以从GitHub查看所有内容。
    #公开NGINX
    最后一步就是公开NGINX服务,跟为微服务创建内部服务流程一样,但是需要指出“type:LoadBalancer",会给此服务一个外部IP地址,可以从NGINX目录下svc.yaml文件中看到。

    一旦部署服务,可以用如下命令看到外部IP地址:
    图六.png

    #测试
    下面使用外部IP,测试这个API看看输出情况,非常酷!
    图七.png

    图八.png

    图九.png

    图十.png

    #回顾
    我们创建了如下应用:
    图十一.png

    使用NGINX公开了单一API服务点和代理负载到四个不同微服务,每个都有三个实例。
    #额外阅读
    我们所有的模组都已经运行成功,我们接下来看看如何监控、扩展和更新微服务。
    ##扩展
    用Kubernetes扩展微服务并不容易。例如要扩展Arrayify容器的数量,可以使用如下命令扩展到五个容器:
    $ kubectl scale deployment arrayify --replicas=5

    缩减也是一样的过程。如果想减少到一个容器,运行如下命令:
    $ kubectl scale deployment arrayify --replicas=1

    也可以实现自动扩展,根据CPU负载动态调整集群内容器数量。使用如下命令:
    $ kubectl autoscale deployment arrayify --min=1 --max=5 --cpu-percent=80

    如你所愿,这条命令确保至少一个容器在运行,如果需要最多可以扩展到五个,并且会确保每个容器至少CPU占用80%以上。也可以用此命令扩展NGINX!需要注意的是虚机(节点)自动扩展现在在Kubernetes内并不支持,然而,可以使用Google Cloud Managed Instance Group来实现此需求。
    #更新
    如果能够动态更新微服务而不影响业务就非常理想。应用不同部分依赖不同微服务,因此如果一个微服务下线了,会对其它部分造成负面影响。幸运的是,Kubernetes使得零宕机部署变的更加易于管理。更新一个微服务,首先创建一个运行新代码的容器,打上新标签。例如,如果想更新arrayify微服务,重新运行docker build命令,但是需要更改版本号。
    $ docker build -t gcr.io//arrayify:0.2 .

    然后推送:
    $ gcloud docker push gcr.io//arrayify:0.2

    打开arrayify微服务的deployment.yaml 文件,改变容器版本(从0.1到0.2),然后部署新版本。
    $ kubectl apply -f deployment.yaml

    Kubernetes会自动扩展部署新版本,缩减下电旧版本。如果新版本有bug,可以用单一命令回滚:
    $ kubectl rollout undo deployment/arrayify

    (替换arrayify为其它需要更新或者回滚微服务名字)如果想了解详细信息,可以读其它文档
    #监控
    使用NGINX+,有一个非常酷的面板,可以了解所有微服务状态。
    图十二.png

    可以从中看出流量、错误以及每个不同微服务的健康状态。可以参看详细的nginx.conf

    最后,我强烈推荐使用Google Stackdriver来为微服务配置自动告警和触发。Stackdriver是一个监控应用的一站式商店;默认的,每个容器的stdout和stderr都被发往stackdriver日志。stackdriver监控可以查看Kubernetes集群和监控各自pods,stackdriver监控可以帮助模拟代码debug而不需要真的命中bug。

    感谢读完了这么长的博客,如果有什么需要分享的,可以跟我在 Twitter @SandeepDinesh互动。

    原文链接:Creating a scalable API with microservices(翻译:杨峰)

    什么是服务网格?

    grace_shi 发表了文章 • 0 个评论 • 293 次浏览 • 2019-06-04 22:29 • 来自相关话题

    服务网格 是一个可配置的低延迟的基础设施层,目的是通过API(应用程序编程接口)处理应用程序服务之间的大量基于网络的进程间通信。服务网络确保容器化的短暂存在的应用程序的基础结构服务之间的通信快速,可靠和安全。网格提供关键功能,包括服务发现,负载平衡,加密,可观 ...查看全部
    服务网格 是一个可配置的低延迟的基础设施层,目的是通过API(应用程序编程接口)处理应用程序服务之间的大量基于网络的进程间通信。服务网络确保容器化的短暂存在的应用程序的基础结构服务之间的通信快速,可靠和安全。网格提供关键功能,包括服务发现,负载平衡,加密,可观察性,可追溯性,身份验证和授权,以及对断路器模式【1】的支持。

    服务网格是如何实现的呢?它通常会为每个服务实例提供一个称为边车(sidecar)的代理实例。这些边车会处理服务间的通信,监控和安全相关的问题, 以及任何可以从各个服务中抽象出来的东西。这样,开发人员就可以专注于服务中应用程序代码的开发,支持和维护,而运维团队可以负责维护服务网格以及运行应用程序。

    Istio,由Google,IBM和Lyft支持,是目前最著名的服务网格架构。Kubernetes,最初由Google设计,是目前Istio支持的唯一容器编排框架。供应商正在寻求商业版本的Istio。如果Istio能添加到开源项目中,将会带来更大的价值。

    Istio并不是唯一的选择,其他服务网格实现也在开发中。目前边车代理模式是最受欢迎的,例如Buoyant,HashiCorp,Solo.io等项目都使用了这种模式。与此同时,Netflix的技术套件使用了一种替代架构,他们使用了应用程序库(包含Ribbon,Hysterix,Eureka,Archaius)来提供服务网格功能,而Azure Service Fabric等平台在应用程序框架中嵌入了类似服务网格的功能。 服务网格包含一些专业术语来描述组件服务和功能:

    • 容器编排框架。随着越来越多的容器被添加到应用程序的基础架构中,用于监视和管理容器组的容器编排框架变得至关重要。
    • 服务和实例(Kubernetes Pod)。实例是微服务的单个运行副本。有时实例是一个容器;在Kubernetes中,一个实例由一小组相互依赖的容器(称为Pod)组成。客户端很少直接访问实例或Pod,通常他们会访问服务,服务通常是一组可扩展且具有容错性的实例或Pod(副本)。
    • 边车代理。 边车代理与单个实例或Pod一起运行。 边车代理的目的是路由或者代理从容器发出或者接收的流量。 边车与其他边车代理进行通信,编排框架会管理这些边车。许多服务网格的实现会使用边车代理来拦截和管理实例或Pod的所有进出流量。
    • 服务发现。当实例需要与不同的服务进行交互时,它需要找到 - 发现 - 其他服务的健康的,可用的实例。通常,这个实例会执行DNS查找来寻找其他服务的实例。容器编排框架保留实例列表(这些实例都可以正常接收请求),并且框架会提供DNS查询的接口。
    • 负载均衡。大多数编排框架已经提供了第4层(传输层)的负载均衡。服务网络实现了更复杂的第7层(应用层)负载均衡,具有更丰富的算法以及更强大的流量管理。同时可以通过API修改负载均衡的参数,从而可以编排蓝绿部署【2】或金丝雀部署【3】。
    • 加密。服务网格可以加密和解密请求和响应,因此每个服务不需要额外对请求进行加密,减少了负担。服务网格还可以通过优先重用现有的持久连接来提高性能,这减少新连接的创建(创建新连接十分耗费计算资源)。一般实现加密流量都是用双向TLS(mTLS),其中公钥架构(PKI,public key infrastructure)生成并分发证书和密钥,提供给边车代理使用。
    • 身份验证和授权。服务网格可以授权和验证从应用程序外部和内部发出的请求,仅向实例发送经过验证的请求。
    • 支持断路器模式【1】。服务网格可以支持断路器模式,这可以隔离不健康的实例,然后在安全的情况下逐渐将它们恢复并加入到健康的实例池中。

    服务网格应用中管理实例之间的网络流量的的部分称为数据平面。另外有一个独立的控制平面负责生成和部署数据平面的配置(这个配置可以控制数据平面的行为)。控制平面通常包含(或被设计为连接到)一个API,命令行界面和用于管理App的图形用户界面。

    *服务网格中的控制平面在数据平面中边车代理上分发配置*

    服务网格架构的一个常见用例是在使用容器和微服务时解决非常苛刻的操作问题。微服务领域的先驱包括Lyft,Netflix和Twitter等公司,这些公司任何时间都能为全球数百万用户提供强大的服务。 (请参阅我们对Netflix面临的一些架构挑战的深入描述。)如果应用程序对这方面要求比较低,那么更简单的架构就足够了。

    服务网格架构不可能解决所有应用程序操作和交付问题。架构师和开发人员可以选择多种工具,这些工具之中,有些是锤子,可以解决不同类型的问题,而另一些可能是钉子。例如,NGINX微服务参考架构包括几种不同的模型,这些模型提供了使用微服务来解决问题的一系列方法。 服务网格架构中的组成部分 - 例如:NGINX,容器,Kubernetes,以及微服务(作为架构方法),可以在非服务网格架构实现中高效地使用。例如,Istio是作为一个完整的服务网格架构开发的,但其模块化的设计意味着开发人员可以自由选择他们需要的部分组件技术。考虑到这一点,即使您不确定是否以及何时会完全实现服务网格应用程序,也值得深入了解一下服务网格概念。 

    注释: 

    【1】断路器模式: 一种设计模式。用以侦测错误,并避免不断地触发相同的错误(如维护时服务不可用、暂时性的系统问题或是未知的系统错误)。https://zh.wikipedia.org/wiki/斷路器設計模式 
    【2】蓝绿部署(blue‑green deployment):蓝绿部署是保留老版本,同时部署新版本然后进行测试,测试通过后,将流量切换到新版本,然后老版本同时也升级到新版本。 
    【3】金丝雀部署(canary deployment):又叫做灰度部署,即选择部分部署新版本,将部分流量引入到新版本,新老版本同时提供服务。等待灰度的版本测试完毕,之后全量覆盖老版本。 

    原文链接:What Is a Service Mesh? 

    ============================================================================== 
    译者介绍:Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

    Serverless的本质是什么?

    grace_shi 发表了文章 • 0 个评论 • 2470 次浏览 • 2018-06-18 19:34 • 来自相关话题

    【编者的话】这篇文章来自于The New Stask,是Serverlss系列的第一篇文章,这一系列文章是为了探索Serverless的本质,每周一更新。 Serverless直译为中文是“无服务器”,但是实际上它仍需要服务器,只不过 ...查看全部
    【编者的话】这篇文章来自于The New Stask,是Serverlss系列的第一篇文章,这一系列文章是为了探索Serverless的本质,每周一更新。

    Serverless直译为中文是“无服务器”,但是实际上它仍需要服务器,只不过服务器的管理以及资源分配部分对用户不可见,为避免误导读者,译文中还是将英文保留。

    最开始,一台单用户的物理服务器便能满足我们的日常所需,它快速,可靠并且安全,只对管理员负责。但是在实际中配置和扩展都很麻烦。虚拟机的出现满足了灵活性和可扩展性的需求,之后云服务提供商为我们带来了基础架构即服务(IaaS),云平台自助服务也由此诞生。在这片肥沃的土壤中出现AWS(Amazon Web Services),编排,以及基础设施即代码(IaC),之后开始了集装箱化,带来了平台即服务(PaaS)的架构,一切看起来都很顺利......但程序员仍想要更多的功能,如独立于编程语言(language agnostic)的端点,服务器的水平伸缩能力,以及可以实时支付服务使用量的能力。

    为了满足这些需求,Serverless计算应运而生,Serverless计算也被称为功能即服务(FaaS)。运行时只会执行程序但不会存储数据。这意味着像AWS(Amazon Web Service),谷歌云以及微软Azure云这样的云服务提供商会动态的管理资源的分配和分布。

    Serverless是付完即走,基于实际的消费而不是基于预测的预付款进行收费的。这本是基础设施应该有的样子,在2018年终于出现在我们面前。
    # 这并不是魔法
    首先,这个名字非常有误导性。 Serveless(无服务器)计算仍然需要服务器,它并不是什么神秘魔法。

    这个术语的出现是因为服务器的管理以及容量规划都被隐藏起来了。Serverless被称作是无服务的是因为用户/程序员无需关心甚至意识到基础架构的存在——服务器被完全抽象出去了。Serveless代码可以和传统方式部署的代码一起使用,例如微服务,甚至一个应用程序可以完全不需要配置服务器,只需要以无服务器的方式编写即可。

    Serveless 真正的价值不在于节省了成本,而在于节省了时间。



    Bitnami的现任云技术高级总监Sebastien Goasguen说到“我会把Serverles 想像成一个具有微型PaaS的像胶水一样的软件,它最大的优点就是可以从云中发生的事件中调用函数(即胶水)“,Goasguen描述了一个场景,例如,将图像放在AWS(Amazon Web Service)的storage bucket中存储,然后调用函数来调整该图像的大小。Serverless系统会获取这段代码并且自动注入到运行时环境(服务器或者容器),之后将这个函数暴露出来以便调用。
    # 那么,讲完了什么是Serverless,然后呢?
    传统云计算和Serverless云计算最主要的区别在于客户是否需要为未被使用或者未被充分使用的资源支付费用。以前,无论是内部数据中心还是云上,我们都需要提前预测容量和资源需求,并且提前准备好。在之前的例子中,这意味着我们提前启动AWS服务器以便随时执行这项调整镜像大小的服务。而在Serverless配置中,你只需要调整代码执行的时机,即只在函数被调用时候执行。

    Serverless计算服务将您的函数作为输入,执行逻辑,返回输出,之后关闭。你只需要为函数实际执行所消耗的资源付费。

    即用即付(Pay-as-you-play),并且只用为你实际使用的资源付费,这显然是件好事,但是Goasguen以及其他Cloud Native的专家强调Serverless真正的价值在于时间效率,而不是成本效率。
    # 像时间机器一样?
    Serverless就像一扇通往未来的门,它和其他即服务(other as-a-service)的技术一样,为公司提供了很多工具,可以让公司专注于构建使用如AI,机器学习等尖端技术的应用程序。而不是浪费时间精力在不停的构建,重建必需的基础设施。

    Serverless其他的时间机器功能在于缩短了从代码开发到投入生产的时间。它真正实现了“这是我的代码,现在立刻运行它”。不会因为基础设施产生延迟。

    Oracle公司负责Serverless业务的副总裁Chad Arimura说到“Serverless的基本思想是程序员只需要写代码然后推送到Serverless的服务就足够了,其余的事情都由这个服务来处理”。他还补充道,像数据库和数据存储这类的依赖关系也被当作服务无缝集成到Serverless底下。

    Arimura说到“在Serverless背后,专业的团队和自动化工作相结合,大规模的操作这些系统,以便开发人员无需考虑这些问题,这项技术看起来就像是魔法一样,这也是为什么这项技术被炒作的如此厉害,正因为它带给了我们如此美妙的体验”。
    # 感受 FaaS(功能即服务)平台的强大
    虽然Docker技术简化了分布式应用打包和依赖管理的问题。Kubernetes帮助企业在生产中运行这些应用。但是使用它们并不简单易用。Dcokerfile, 、基础设施细节、Kubernets manifests文件,这些即便对于程序员听众来说,也异常复杂。

    Serverless计算的核心就是作为一个功能即服务平台。从本质上讲亚马逊的AWS Lambda以及Google Cloud Function就是Serverless的实现。它们处理了资源管理,负载均衡以及多线程,开发人员就可以只关注他们的代码,而企业只用关心他们的目标。

    iguaz.io的创始人兼CTO Yaron Haviv提到,一个持续的数据平台是为提升云上的性能而设计的,将一个新的技术栈按照FaaS(功能即服务)的工作流运行一遍,步骤如下:

    1. Serverless平台提取了功能代码——即FaaS(功能即服务)的功能部分——以及所有依赖项(如必需的库,内存的数量,属性等等),构建成一个集装箱化的应用程序包,通常采用Docker镜像的形式。
    2. 当另一个平台服务,例如对象存储或数据库想要触发这个功能,或者一个外部的http请求想要调用这个功能,Serverless平台会将这个请求转发到一个可用的功能微服务。如果当前没有可用的微服务,那么它将部署“冷启动”(cold start)一个这样的实例。
    3. Serverless平台需要负责在微服务失败的时候恢复它,自动扩展以适应需求,记录和监控功能活动,并且在代码被修改后进行实时滚动升级。专门有人来管理平台服务,这样程序员就可以专注于“功能”方面。

    # 那么Severless的缺点是什么呢?
    除了以上列出的优点之外,FaaS(功能即服务)也存在一些潜在的缺点。专家提到,云服务提供商通常会降低那些不经常的运行环境的资源,他们也会限制你的可用资源的总量,由此带来延迟以及低性能问题。并且由于任何云计算工作流事实上都会运行在一个公有云环境,而你无法控制或者进入这些云环境,导致监控,调试,以及安全性都无法保障。

    亚马逊Lambda已成称为Serverless计算的代名词,这也是大多数人可以完全理解一种Servless的模式。尽管Lambda已经开辟了Serverlss的前路,它也涵盖了所有Serverless的缺点:缓慢的冷启动(cold start),低性能,短时间存在的功能,以及一组封闭的触发器。目前普遍认为,所有的Severless平台都具有这些限制性,但事实上这些限制性可以在平台的实施中避免。值得注意的是有一些更新的Serverless平台比如 Nuclio,它演变出了很多更广泛的用例,这些更新的平台具有更少的限制,更高的性能,并且可以运行在多个云服务上甚至是内部环境。

    Haviv说道“极客们喜欢Serverless,但是企业们仍在试水——他们甚至还没有熟悉Docker/Kubernetes,Serverless就开始出现了”,就如任何新技术一样,一开始总是由一些聪敏,愿意冒险的早期受众开始试用,之后慢慢面向大众。而大众往往需要在看到这项技术是值得信赖,并且有可靠证据证明它能解决性能问题,安全问题等等问题之后才会采用这项技术。

    鉴于Serverlss这项技术几乎每天都在发展壮大,所以并非所有的方面都可以令人满意。虽然称不上是个缺点,但是这一点的确令整个董事会坐立不安。Haviv 指出“由于数字化转型”正影响着当代企业,创新者们以及Serverless一类的某某即服务(Other As A Service)技术正在威胁着现任者,让企业变的更加敏捷以及更加愿意承担风险。最有趣的是尽管Serverless比Docker/Kubernetes技术更新,但如果将Docker/Kubernetes的复杂性抽象出来,Serverless会更快更容易的被采用。
    # 如何知道Serverless是否适合你的公司
    这里不是讨论你的公司到底适不适合Serverless,这里只是讨论一下那些最先采用Serverless技术的公司。

    Oracle的Arimura说道“表面上来说,任何编写软件的公司和组织都非常适合采用Serverless”,不过,就当前的文化以及离达成全面“原生云”目标的距离而言,采用Serverless将会使这个过程变得更加艰难。换句话说,如果一个公司没有使用过任何的公有云,没有任何Docker/Kubernetes的实施经历。那么他们就不该从Serverless开始。

    “这是一种全新的架构,需要完全不同的思维方式,最简单的例子就是如果要把一个单体应用拆分成10个微服务,100个函数,并且每个都具有独立的部署周期以及复杂的依赖图,配合成熟健壮的CI/CD以及自动化的系统。把这些和Serverlss一起使用的时候,将会大幅提升敏捷性和创新性,但是如果仅仅只有其中一个,那么带来的损失远大于收益。”

    Arimura继续说道 “这就是为什么Devops(运维人员)不会变成noOps(无运维人员),因为这是一条完全错误的方向。“事实上,Serverless的出现使得DevOps比以往更重要。

    事实上,Bitnami的Goasguen指出,他观察到的大部分使用Serverless的公司都是以程序员为中心的组织,尤其是使用AWS Lamba服务的,这些公司原本就使用AWS并且用AWS将服务连接在一起。 Goasguen说道“所以很有可能,如果你不使用AWS,那么你便不需要Serverless,但是你始终需要保持警惕,开始评估,辨别企业中哪些事件源可以被用来建立完整的应用程序管道。
    # 企业试水Serverless的最佳途径?
    Arimura建议道“如果一个企业仍处在适应DevOps的阶段,那么它不需要一开始就将一个大型的单体应用完全拆分转换成微服务或者功能,或是为了学习一个新架构就在一个重要的新项目中使用这项技术。最好是从小处着手,例如创建一些自动化的任务,或是事件驱动的用例。”

    本系列Serverless的文章可以帮助您的公司开始使用这项技术。

    原文链接:Serverless 101: How to Get Serverless Started in the Enterprise

    ==============================================================================
    译者介绍
    Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

    如何开启Kubernetes之旅

    justinfu 发表了文章 • 0 个评论 • 5604 次浏览 • 2017-07-19 18:56 • 来自相关话题

    【译者的话】这篇文章由浅入深地介绍了如何开始Kubernetes学习,以及如何基于Kubernetes部署应用。作者给出了很多非常好的建议,指导读者掌握围绕Kubernetes的各个概念和相关技能,为学习Kubernetes指明了方向。 ...查看全部
    【译者的话】这篇文章由浅入深地介绍了如何开始Kubernetes学习,以及如何基于Kubernetes部署应用。作者给出了很多非常好的建议,指导读者掌握围绕Kubernetes的各个概念和相关技能,为学习Kubernetes指明了方向。

    从Hello Minikube到Kubernetes Anywhere,再到微服务示例应用,学习谷歌容器编排工具的途径比比皆是。



    每一次的创新都带来一些新的麻烦。容器使得应用的打包和运行更加便捷,但是管理大规模容器依然是一个挑战。

    Kubernetes是谷歌公司内部为解决这个问题而开发的产品,它提供了一个单一的框架来管理在整个集群中运行的容器。该产品提供的服务主要集中在“编排”上,但也涵盖了许多方面:容器调度、容器之间的服务发现、跨系统的负载平衡、滚动更新/回滚、高可用性等。

    在这个指南中,我们将介绍创建Kubernetes集群并发布容器应用的基本知识。这并不是要介绍Kubernetes的概念,而是通过简单示例来展示这些概念如何在运行Kubernetes的过程中结合在一起的。
    # 选择一个Kubernetes主机
    Kubernetes是为了管理Linux容器而诞生的。但是,从Kubernetes 1.5起,尽管Kubernetes控制面板必须继续在Linux上运行,但Kubernetes已经开始支持Windows Server Containers。当然,借助虚拟化,您可以在任何平台上开始使用Kubernetes。

    如果您选择在自己的硬件或虚拟机上运行Kubernetes,一个常见的方法是获取绑定Kubernetes的Linux发行版。这样就不需要设置Kubernetes,不仅省去了安装和部署过程,甚至配置和管理的过程也不需要了。

    CoreOS Tectonic就是这样的一个发行版,专注于容器和Kubernetes,几乎完全排除其他任何东西。RancherOS采取类似的做法,同样自动化执行大部分的设置。两者都可以安装在各种环境中:裸机,Amazon AWS VMs,Google Compute Engine,OpenStack等。

    另一种方法是在常规的Linux发行版上运行Kubernetes,尽管通常会带来更多的管理开销和手动调整。例如,红帽企业Linux在其软件库中有Kubernetes,但即使是Red Hat,也建议仅用于测试和实验。建议红帽用户通过OpenShift PaaS使用Kubernetes,而不是自己动手从头搭建,OpenShift现在使用Kubernetes作为自己的容器编排系统。许多传统的Linux发行版提供了设置Kubernetes和其他大型软件堆栈的特殊工具。例如,Ubuntu提供了一种名为conjur-up的工具,可用于在云和裸机实例上部署Kubernetes的上游版本
    # 选择一种托管Kubernetes的云
    尽管在谷歌云平台(GCP)上,Kubernetes已经全面支持了,但是在很多其他云平台上,Kubernetes是否支持依然是一个焦点问题。GCP提供了运行Kubernetes的两种主要方式。最方便和集成最好的方式是通过Google容器引擎,它允许您运行Kubernetes的命令行工具来管理创建的集群。或者,您可以使用Google Compute Engine来创建计算集群并手动部署Kubernetes。这种方法对用户的技能要求比较高,但是允许用户使用Google Container Engine尚未支持的个性化定义。如果您刚开始接触容器,最好坚持使用容器引擎。经过一段时间之后,您对Container Engine有了一定的了解,就可以尝试一些更高级的内容,比如您自己选择特定版本的Kubernetes进行部署,或者部署运行Kubernetes发行版的虚拟机。

    亚马逊EC2有容器的原生支持,但没有原生支持Kubernetes作为容器编排系统。在AWS运行Kubernetes类似于使用谷歌计算引擎:配置一个计算集群,然后手动部署Kubernetes。

    许多Kubernetes的发行版都有如何在AWS部署的详细说明。例如,CoreOS Tectonic,有一个图形化的安装程序,同时还支持Terraform基础设施配置工具。此外,Kubernetes kops工具可以被用来配置一组AWS上的虚拟机集群(通常使用Debian Linux,但是其他的Linux版本也部分支持)。

    微软Azure通过Azure Container Service来支持Kubernetes。然而,从将Kubernetes作为一个托管在Azure上的服务这个角度来说,这不是很“原生”的支持。相反,Kubernetes是由一个Azure资源管理模板部署的。Azure对于其他的容器编排系统(比如Docker Swarm和Mesosphere DC/OS)的支持也是这种思路实现的。如果您在这里提到的任何其他的云中部署Kubernetes,并且希望完全控制它,在Azure虚拟机上安装一个Kubernetes的核心版永远是简单可行的办法。

    在各种环境(云端或其他方式)中快速配置一个基础Kubernetes集群的方式就是使用名为Kubernetes Anywhere的项目。此脚本适用于Google Compute Engine,Microsoft Azure和VMware vSphere(需要vCenter)。在每种情况下,它为启动过程提供了一定程度的自动化。
    # 您自己的小部分Kubernetes节点
    如果你只是在一个像开发机器这样的本地环境中运行Kubernetes,而且你不需要整个Kubernetes全部能力,那么有几种方法可以设置“刚好足够”的Kubernetes来进行使用。

    其中一种方式是使用由Kubernetes开发团队本身提供的MiniKube。运行它,您会得到一个单节点Kubernetes集群部署在您选择的虚拟主机上。minikube有几个前提,如kubectl命令行接口和虚拟化环境如VirtualBox,但那些都有现成的二进制,支持MacOS,Linux和Windows。

    对于MacOS上的CoreOS用户,有Kubernetes Solo。它运行在一个CoreOS虚拟机上,提供了一个状态栏应用程序实现快速管理。Solo也包括Kubernetes包管理程序Helm(通常是Helm下一级),因此基于Kubernetes的应用程序包更容易获取和设置。
    # 玩转您的容器集群
    当您的Kubernetes运行起来之后,您就可以运行和管理容器了。通过部署和管理基于很多容器的应用示例的方式,您可以轻松地熟悉容器的操作。以一个现有的基于容器的应用程序demo为例,自己组装它,看看它是如何组成的,部署它,然后逐步修改它,直到满足您的预期。如果您选择通过minikube找到立足点,您可以使用Hello Minikube教程创建Docker容器,将这个运行简单的Node.js应用的容器托管在单节点Kubernetes,以此来演示集群安装和应用部署。一旦您对这些都熟悉了,您就可以替换成自己的容器,并做一些实践性部署。

    下一步是部署一个示例应用程序,这个程序类似您可能在生产环境中使用的应用。通过这个应用您可以进一步熟悉Kubernetes的一些高级概念,比如pods(一个或多个容器,包括一个应用程序),service(一组逻辑的Pod),replica sets(提供应用在机器故障时的修复机制)和deployment(应用程序的版本)。揭开WordPress/MySQL示例应用程序的神秘面纱,例如,你看到的将不仅仅是如何将应用部署到Kubernetes,并让这些应用正常运行。您也将看到Kubernets应用涉及的很多概念的实现细节,而这些应用都是满足生产环境要求的。您将学习如何设置持久卷以保存应用程序的状态,如何将Pod暴露给彼此,以及如何通过services与外部世界连在一起,以及如何将应用程序密码和API密钥存储为secrets等等。

    Weaveworks有一个示例应用程序,袜子商店,展示了微服务模式如何用来组合Kubernetes中的应用。袜子商店对于熟悉底层技术(比如Node.js,Go kit和Spring Boot)的人来说是最有利的,但主旨超越了特定的框架,而是说明云原生技术。

    如果您看了一眼WordPress/MySQL的应用,并想创建一个运行在Kubernetes上的应用来满足您的需求,这种想法基本上是对的。Kubernetes有一个应用程序定义的系统称为Helm,它提供了一种打包、版本管理和共享Kubernetes应用的机制。一些主流的应用程序(GitLab,WordPress)和构建应用程序的模块(MySQL、NGINX)将Helm作为一站式直通kubeapps门户的最佳实践。
    # 深入探索Kubernetes
    Kubernetes通过强大的抽象能力简化了容器的管理,比如Pod和Service,同事通过label和namespace机制提供了很大的灵活性,label和namespace都可以用来隔离pod,services和deployments(比如开发环境、过渡环境和生产环境负载)。

    如果您选择上面的示例的一个,并在多个命名空间中创建不同的实例,那么可以对独立于其他命名空间的组件进行更改。您可以使用deployments,以允许这些更新在给定的命名空间中的多个pod之间滚动进行

    比这种练习更进一步的是学习Kubernetes本身如何能够被管理基础设施的工具所驱动。以Puppet为例,有一个用于创建和操纵Kubernetes资源的模块,但是HashiCorp’s Terraform很早就有支持,但是支持方式演变成将Kubernetes作为一种资源进行管理。如果您打算使用这样的资源管理器,请注意不同的工具可能会给表带来不同的预期结果。以Puppet and Terraform为例,默认分别使用可变的和不可变的基础设施。这些哲学层次和行为的差异,如何或轻松,或困难地创建您所需要的Kubernetes。

    这个故事,“如何开启Kubernetes之旅”最初发表在InfoWorld

    原文链接:How to get started with Kubernetes (翻译:付辉)

    Netflix Conductor:一个微服务编排工具

    justinfu 发表了文章 • 0 个评论 • 15253 次浏览 • 2017-04-29 08:09 • 来自相关话题

    【译者的话】这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发。 【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述 ...查看全部
    【译者的话】这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发。

    【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述、架构、日志和监控,部署、自动驾驶、服务发现、网络方案等核心机制分析,进阶篇——Kubernetes调度工作原理、资源管理及源码分析等。

    Netflix内容平台工程团队运行许多业务流程,这些业务流程是通过在微服务上执行异步编排任务来驱动的。其中一些流程运行时长多达数天。这些流程在让一切准备好,以呈现给全球用户的过程中,起到了至关重要的作用。

    这些流程的几个例子:

    + 整合工作室合作伙伴的内容摄取
    + 从我们的合作伙伴摄入基于IMF的内容
    + 在Netflix中设置新的标题的过程
    + 内容摄取,编码和部署到CDN

    按照传统做法,这其中一些进程已经使用发布/订阅模式,直接进行REST调用以及使用数据库来管理状态的组合进行了自组织的编排。然而,随着微服务数量的增长和流程的复杂性不断增加,如果没有中央协调人员,这些分布式工作流程的可见性将变得困难。

    我们构建了“作为业务流程引擎”的Conductor,以满足以下要求,消除在应用程序中对模板的需求,并提供流程相关的执行动作:

    + 以蓝图为主,基于JSON DSL的蓝图定义了执行流程;
    + 跟踪和管理工作流;
    + 能够暂停,恢复和重新启动流程;
    + 用户界面可视化流程;
    + 能够在需要时同步处理所有任务;
    + 能够扩展到数百万个同时运行的流程;
    + 由客户抽象的排队服务提供后端支持;
    + 能够通过HTTP或其他传输操作,例如gRPC;

    Conductor是为满足上述需求而建立的,目前已在Netflix上使用。到目前为止,它已经帮助协调了260多万个流程流程,从简单的线性工作流程到跨越多天运行的非常复杂的动态工作流程。

    今天,我们是开放Conductor给更广泛的社区,希望从具有相似需求的其他人那里学习,增强其能力。您可以在这里找到Conductor的开发人员文档。
    # 为什么不对等编排?
    通过对等任务编排,我们发现随着业务需求和复杂性的增长难以扩展。发布/订阅模式为最简单的流程工作,但很快突出了与该方法相关的一些问题:

    + 流程“嵌入”在多个应用程序的代码中;
    + 通常,关于输入/输出,SLA等的紧耦合和不确定性,使其难以适应不断变化的需求;
    + 不清楚当前执行的任务属于整个流程的哪个阶段;

    # 为什么是微服务?
    在微服务世界中,许多业务流程自动化是通过协调服务来驱动的。Conductor可以在服务之间进行协调,同时提供对它们的相互作用的控制和可见性。有能力在微服务之间进行协调,也帮助我们利用现有服务来构建新流程或更新现有流程,以便使用Conductor非常快速,有效地提供了更容易采用的方法。
    # 架构概览
    Netflix_Architect.png

    在发动机的核心是一个状态机服务又名的决策服务。随着工作流事件的发生(例如任务完成,故障等),决策者将工作流程蓝图与工作流程的当前状态相结合,识别下一个状态,并安排适当的任务和/或更新工作流的状态。

    决策者使用分布式队列来管理计划任务。我们一直在Dynomite之上使用dyno-queue来管理分布式延迟队列。队列“食谱”今年早些时候开放,这里是博客文章。
    ## 任务执行者的实现
    由Worker实现的Tasks通过API层进行通信。Worker通过实现可由业务流程引擎调用的REST端点或实现定期检查待处理任务的轮询机制来实现此目的。Worker是幂等无状态的功能。轮询模型允许我们处理worker背后的压力,并在可能的情况下根据队列深度提供自动可扩展性。Conductor提供API来检查可用于自动调整工作实例的每个工作人员的工作负载大小。
    Worker_Communication_With_Engine.png

    ## API层
    API通过HTTP协议公开 - 使用HTTP允许轻松地与不同的客户端集成。然而,添加另一个协议(例如,gRPC)应该也是可能的并且相对简单。
    ## 存储
    我们使用Dynomite“作为存储引擎”以及Elasticsearch来索引执行流程。存储API可插拔,可适用于各种存储系统,包括传统的RDBMS或Apache Cassandra,如no-sql存储。
    # 核心概念
    ## 工作流
    工作流程使用基于JSON的DSL进行定义。工作流程蓝图定义了一系列需要执行的任务。每个任务都是控制任务(例如,分支,连接,决策,子工作流程等)或工作任务。工作流定义被版本化,提供管理升级和迁移的灵活性。一个工作流定义:
     {
    "name": "workflow_name",
    "description": "Description of workflow",
    "version": 1,
    "tasks": [
    {
    "name": "name_of_task",
    "taskReferenceName": "ref_name_unique_within_blueprint",
    "inputParameters": {
    "movieId": "${workflow.input.movieId}",
    "url": "${workflow.input.fileLocation}"
    },
    "type": "SIMPLE",
    ... (any other task specific parameters)
    },
    {}
    ...
    ],
    "outputParameters": {
    "encoded_url": "${encode.output.location}"
    }
    }

    ## 任务定义
    每个任务的行为由其称为任务定义的模板控制。任务定义为每个任务提供控制参数,例如超时,重试策略等。任务可以是由应用程序实现的工作任务或由业务流程服务器执行的系统任务。Conductor提供开箱即用的系统任务,如决策,叉,连接,子工作流程以及允许插入自定义系统任务的SPI。我们增加了对HTTP任务的支持,有助于调用REST服务。一个任务的定义如下:
     {
    "name": "encode_task",
    "retryCount": 3,
    "timeoutSeconds": 1200,
    "inputKeys": [
    "sourceRequestId",
    "qcElementType"
    ],
    "outputKeys": [
    "state",
    "skipped",
    "result"
    ],
    "timeoutPolicy": "TIME_OUT_WF",
    "retryLogic": "FIXED",
    "retryDelaySeconds": 600,
    "responseTimeoutSeconds": 3600
    }

    ## 输入/输出
    任务的输入是一种的映射,即工作流实例化或其他任务的输出的一部分。这种配置允许将来自工作流或其他任务的输入/输出作为可以随后作用于其的任务的输入。例如,可以将编码任务的输出提供给发布任务作为部署到CDN的输入。一个输入的定义如下:
     {
    "name": "name_of_task",
    "taskReferenceName": "ref_name_unique_within_blueprint",
    "inputParameters": {
    "movieId": "${workflow.input.movieId}",
    "url": "${workflow.input.fileLocation}"
    },
    "type": "SIMPLE"
    }

    # 一个案例
    下面是一个非常简单的编码和发布流程:
    encode-deploy-flow.png

    共有3个工作任务和一个控制任务(错误)涉及:

    1. 内容检查:检查输入位置的文件是否正确/完整
    2. 编码:生成视频编码
    3. 发布:发布到CDN

    这三个任务由不同的worker实现,这些worker使用任务API轮询待处理的任务。这些是理想的幂等任务,对任务的输入进行操作,执行工作并更新状态。

    每个任务完成后,决策者根据蓝图(对应于工作流实例的版本)评估工作流实例的状态,并标识要排定的下一组任务,如果完成所有任务,则完成工作流。
    # UI
    UI是监控和排除工作流执行的主要机制。 UI通过允许基于包括输入/​​输出参数在内的各种参数的搜索来提供对流程的非常需要的可见性,并提供蓝图的可视化呈现以及所采用的路径,以更好地了解流程执行。对于每个工作流实例,UI提供每个任务执行的详细信息,具体如下:

    + 任务安排的时间戳,由worker获取并完成。
    + 如果任务失败,失败的原因。
    + 重试次数
    + 执行任务的主机。
    + 在任务完成后提供给任务和输出的输入。

    下图是UI的一个样例:
    Task-UI.png


    原文链接:Netflix Conductor : A microservices orchestrator(翻译:付辉)

    业务逻辑的演进——从单体应用到微服务再到函数

    justinfu 发表了文章 • 0 个评论 • 3251 次浏览 • 2017-03-31 08:45 • 来自相关话题

    【译者的话】这篇文章介绍了业务逻辑从单体应用到微服务模式,再到事件驱动函数模型的进化过程。从原理上剖析了每一次进化的动机,为我们揭示了变化背后的深层次原因,非常具有启发性。 【上海站|3天烧脑式Spring Cloud训练营】培训内容 ...查看全部
    【译者的话】这篇文章介绍了业务逻辑从单体应用到微服务模式,再到事件驱动函数模型的进化过程。从原理上剖析了每一次进化的动机,为我们揭示了变化背后的深层次原因,非常具有启发性。

    【上海站|3天烧脑式Spring Cloud训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

    基础技术在不断进步,正在促进事件驱动函数模型的发展,于此同时也在快速提升业务逻辑的`时效`。

    更新:感谢读者的阅读和反馈, 关于这篇文章中阐述的观点,我在microxchg录制了一个视频,大家可以点击这里观看。



    运行应用软件的目的在于提供某种业务价值。价值通过创建和使用业务逻辑来传递,以便它可以为一些用户提供服务。从开始创建业务逻辑到最终交付,为用户提供服务之间的时间称之为`时效`。提供业务价值的成本等于创建业务逻辑的成本与交付业务逻辑的成本之和。

    过去成本高昂、效率是主要考虑因素,高`时效`被认为是常态。今天,随着技术进步和成本的降低,在竞争压力的推动下,组织在评估和优化企业流程的时候,`时效`正在成为主要考察指标。换句话说,为了提升投资回报率,您需要找到增加回报率的方法,提前获得回报或减少投资。

    问题的核心在于,当成本占主导地位时,随着成本的降低和软件的影响力的增加,焦点必然转向早日得到回报。

    随着技术在过去十年的发展,我们已经看到从单体应用程序到微型服务的发展,现在看到由AWS Lambda领导的无服务器架构、事件驱动函数模式的兴起。是什么因素推动了这种演变?低延迟消息传递使得从单体应用转到微服务,低延迟配置使得能够转移到Lambda。

    在十年前,由于时间的限制,单体应用是交付业务逻辑的最佳方式。在五年前,由于限制因素的改变,微服务成为了最好的交付模式。新的应用程序开始建立在微服务架构上,而在过去的几年中,工具和开发实践已经全面支持微服务。时至今日,事件驱动函数模式再次发生了改变,因为潜在的限制已经发生变化,成本降低了,`时效`的根本改善也是可能的。

    接下来,我们将详细介绍这种变化的不同维度:交付技术,硬件性能和组织架构实践,并了解它们如何结合起来推动这一变革。

    在最开始的时候,交付成本是主要的考虑因素。采购、配置和部署硬件需要花费很长的时间,并且软件安装也是纯手动操作。为了优化交付,每个版本中包含大量业务逻辑,在这些业务逻辑上摊销过高的成本。与此同时,发布周期也不频繁,对于很多组织来说,`时效`通常数月有余。由于基础设施的变更交付周期很长,所以有必要提前预先提供额外的能力,这导致非常低的平均利用率。

    降低交付成本的第一步将重点放在流程自动化上。许多组织开发了自定义脚本来部署新硬件、安装和更新应用程序。最终像Puppet和Chef这样常见的框架变得流行起来,“基础设施即代码”加速了更新的交付。DevOps运动开始于运营团队采用敏捷软件开发实践,并与开发人员紧密合作,以此将`时效`从几个月减少到几天。脚本可以改变已有的基础设施及应用,但快速增长的业务或具有不可预测的工作负载,正在努力寻求新的容量(译者注:这里的容量指的是新的计算资源),通过调用Amazon EC2弹性扩容API可以解决这个问题。当开发人员有能力使用Web服务直接自动化许多操作任务时,新一轮全新的DevOps即将到来。按需部署、按时付费的能力可以实现更高的平均利用率,并自动处理突然爆发的工作负载。

    当Docker将容器变得“老少皆宜”时,另一波提升交付的浪潮来到了。Docker提供了一种方便的打包格式,这种格式包括一组固定的依赖关系,一个比进程隔离性更强、但弱于虚拟机的运行时环境。容器能够在秒级时间内启动,并且节省大量的内存占用空间。通过将许多容器打包到一个实例上,可以将运行时间从几个小时缩短到数分钟甚至数秒,资源利用率也大幅提升。基于容器的持续交付工具链也提升了开发人员的工作效率,缩短了交付时间。当有大量可预测的工作负载时,容器可以运行在高利用率水平,但是大多数时候工作负载是不可预测的,要么处于峰值要么处于低谷。例如,工作场所使用的应用程序只在一周168小时内的40个小时中使用。为了保持高可用性,通常将应用程序实例扩展到三个可用区域,甚至每个区域需要多个实例。因此一个服务最少需要六个实例。如果我们想缩容到0个实例,那么我们需要找到一种机制,在事件发生时启动应用的一个部分,当事件完成后则关停这部分应用。这是AWS Lambda功能的关键部分,它能在0.1秒的时间内对正在使用的计算资源进行扩容,并根据需要从零扩展到非常高的容量,从而保证峰值和低谷时的工作负载都是有效的100%利用率。从而没有必要考虑如何配置服务器,这就是为什么这通常被称为无服务器模式。

    交付技术的进步为改进`时效`提供了垫脚石,但是在过去十年中,还有其他潜在的变化导致了最佳实践的一系列转型。

    业务逻辑的大小取决于在满足服务延迟要求的条件下,计算资源(CPU/内存/网络/磁盘)的成本,以及访问相应资源的响应时间。

    对于终端用户来说,对于业务逻辑响应时间的要求并没有太大变化。在过去十多年里,基础技术发生了翻天覆地的变化,然而对响应时间的感知和期望确一直基本没变。CPU的计算速度在过去十年中增长缓慢,时钟频率始终在几GHz左右,然而芯片缓存却增长很快,而且CPU核数也在不断增加。内存速度和大小的提升也较为缓慢。

    网络现在的传输速度相当快了,常见的从1GBit到10GBit,再到现在的25GBit(正如James Hamilton在他的AWS re:Invent 2016主题演讲中所解释),而且软件协议的效率更高。当通常的做法是通过1GBit网络发送XML有效负载时,通信开销将业务逻辑限制在与大型单体服务共同位置,并直接连接到数据库。十年以后,在25GBit网络上的编码效率将提升一个数量级,这意味着通信成本会降低两个数量级以上。换句话说,十年前服务之间发送和处理一条消息的时间,如今可以达到100至1000条。这是从单体应用架构转移到其他架构模式的关键推动因素。

    存储和数据库在过去十年中也经历了一场革命。单体应用将业务逻辑映射到基于复杂关系型数据库模式的事务,这些数据库模式链接了很多的表,并且提供统一的原子更新。十年前,最佳实践是通过存储区域网络建立少数的大型集中式关系数据库,这些数据库后端连接着价格昂贵的磁盘阵列,磁盘与数据库之间建立巨大的缓存池。

    今天高速缓存的磁盘已被固态磁盘所取代。不同之处在于读取速度从缓慢、昂贵和不可预测(因为缓存命中率不一致)变得持续快速,且几乎无限制。由于磨损均衡算法和其他影响,写入和更新从缓存磁盘的快速迁移到固态磁盘的具有不可预测性。由于众多原因,新的“NoSQL”数据库架构已经变得流行,但我们关注的只有两点:简单的数据模型和充分利用了固态存储的优势。简单的模式强制将在同一关系数据库中链接在一起的数据表分离成多个独立的NoSQL数据库,从而推动业务逻辑的分散化。Amazon DynamoDB数据存储服务从一开始就设计为只在固态磁盘上运行,为请求提供极其一致的低延迟。Apache Cassandra的存储模型生成大量随机读取,并且很少进行大量写入,无更新,非常适合固态磁盘。与关系数据库相比,NoSQL数据库提供简单但极具成本效益,高可用性和可扩展性的数据库,并且具有非常低的延迟。NoSQL数据库的普及率快速增长是单体应用架构模式转移的另一个关键推动因素。其余关系型的主要模式被剔除,或者变得更容易扩展,并被迁移到诸如Amazon的RDS和Aurora之类的服务中。

    当我们看IT的变化时,常常谈论“人,过程和技术”。我们刚刚看到技术如何将利用率和部署速度提高到了AWS Lambda的极限,在几分之一秒内实现了所部署的应用100%利用率。技术也将单体逻辑代码分解成数以百计的微服务/函数,并将单体的RDBMS拆分为许多简单可扩展和高可用性的NoSQL和关系数据存储。

    过去十年,“人与过程”也发生了巨大变化。让我们考虑一下由100位开发人员组成的一个团队。为了协调,管理测试并且每隔几个月向这个“巨型逻辑”提交更新,通常有更多的人运行这个过程,而不是编写代码。通常需要两倍多的项目经理,测试人员,DBA,运维人员等。一成不变的组织架构,一切由各种工作任务单所驱动。管理的层次结构要求每个人写每周报告和参加许多汇报工作状态的会议,研发人员需要抽出时间来编码实际的业务逻辑!

    DevOps实践,微服务架构和云部署三者与持续交付、紧凑的“两个披萨团队”模式紧密合作,大大减少了任务单,会议和管理成本。小团队的开发人员和产品经理在需要时独立地编写,测试和部署自己的微服务。开发人员的比率发生逆转,从原来的50个经理变为100个开发。每个开发者在会议中花更少的时间和等待任务单,这就获得了两倍的时间,而由此带来的`时效`提升可高达百倍。这个变化的最直观效果就是从做项目转向做产品。大量的项目经理被更少的产品经理所取代。在我所见过的某些案例中,150人输出了原来300多人工作成果的两倍。投资一半,但得到双倍回报,`时效`提升一百倍。许多组织一直在进行这种转型,并有类似改进的实例。

    基于Lambda的应用程序由几乎完全是业务逻辑的单个事件驱动功能构成,并且有更少的模版化的内容和平台代码需要管理。这是早期的情况,但这似乎正在推动另一个根本性的变化。开发人员的小团队将在短短几天内从零开始就开始准备应用程序。他们正在使用短小精悍的功能和事件将强大的API驱动的数据存储和服务粘合在一起。已完成的应用程序已经具有高可用性和可扩展性,高利用率,低成本和快速部署。作为一个类比,考虑到一堆模型房子从一块粘土需要多长时间开始,而不是一堆乐高砖。如果有足够的时间,您可以使用这种“粘土”创造任何东西,它具有表现力和创造性,它甚至还可以反其道而行之,创造单体应用(俗称“大泥巴球”)。乐高砖组合在一起,构成了一个功能有限的,块状的模型房屋,在一定的时间内也是很容易扩展和修改的。此外,还有其他的“砖块”有点像乐高砖,但它们并不是主流,任何类型的基于“标准砖”的系统将比“定制粘土”快得多。如果开发人员的生产力能够提高一个数量级,那么我先前提到的100个开发人员的案例中,他们开发的单体应用可以重写,并且在几周之内被10名开发人员组成的团队所取代。如果你怀疑这是否会奏效,大可做一个实验来验证,这个实验的成本还是很低的。事件驱动函数的调用延迟是限制复杂应用程序的关键限制之一,但随着时间的推移,这些延迟正在减少。

    我真正的关注点在于已经存在的单体应用是应该整体搬到云环境中,还是应该重写这个应用这个决定性的ROI阀值。应用从数据中心上云的最佳实践是,将扩展性要求高和经常需要修改的单体应用重写成微服务,本身就很小的应用和很少需要修改的应用采取原封不动的策略。我认为AWS Lambda改变了这个决策方式,它会是新的、试验性质的应用的首选方式。这种方式很值得一试,因为可以做多次的重写。

    我对您的经验非常感兴趣,请让我了解在您的环境中,您是如何看待`时效`的。

    原文链接:Evolution of Business Logic from Monoliths through Microservices, to Functions (翻译:付辉)

    微服务化改造系列之四:授权中心

    emac 发表了文章 • 2 个评论 • 8456 次浏览 • 2016-12-04 16:48 • 来自相关话题

    前情概要: > > - 微服务化改造系列之一:总览 > - 微服务化改造系列之二:服务注册中心 > - 微服务化改造系列之三:配置中心 # 授权中心概述 这篇文章是微服务化 ...查看全部

    前情概要:
    >
    > - 微服务化改造系列之一:总览
    > - 微服务化改造系列之二:服务注册中心
    > - 微服务化改造系列之三:配置中心



    # 授权中心概述
    这篇文章是微服务化改造系列的第四篇,主题是授权中心。有了服务注册中心和配置中心,下一步应该就可以发起服务调用了吧?Wait, 还有一个关键问题要解决。不同于单体应用内部的方法调用,服务调用存在一个服务授权的概念。打个比方,原本一家三兄弟住一屋,每次上山打猎喊一声就行,后来三兄弟分了家,再打猎就要挨家挨户敲门了。这一敲一应就是所谓的服务授权。

    严格来说,服务授权包含鉴权(Authentication)和授权(Authorization)两部分。鉴权解决的是调用方身份识别的问题,即敲门的是谁。授权解决的是调用是否被允许的问题,即让不让进门。两者一先一后,缺一不可。为避免歧义,如不特殊指明,下文所述授权都是宽泛意义上的授权,即包含了鉴权。

    常见的服务授权有三种,简单授权,协议授权和中央授权。

    • 简单授权:服务提供方并不进行真正的授权,而是依赖于外部环境进行自动授权,比如IP地址白名单,内网域名等。这就好比三兄弟互相留了一个后门。
    • 协议授权:服务提供方和服务调用方事先约定一个密钥,服务调用方每次发起服务调用请求时,用约定的密钥对请求内容进行加密生成鉴权头(包含调用方唯一识别ID),服务提供方收到请求后,根据鉴权头找到相应的密钥对请求进行鉴权,鉴权通过后再决定是否授权此次调用。这就好比三兄弟之间约定敲一声是大哥,敲两声是二哥,敲三声是三弟。
    • 中央授权:引入独立的授权中心,服务调用方每次发起服务调用请求时,先从授权中心获取一个授权码,然后附在原始请求上一起发给服务提供方,提供方收到请求后,先通过授权中心将授权码还原成调用方身份信息和相应的权限列表,然后决定是否授权此次调用。这就好比三兄弟每家家门口安装了一个110联网的指纹识别器,通过远程指纹识别敲门人的身份。
    一般来说,简单授权在业务规则简单、安全性要求不高的场景下用的比较多。而协议授权,比较适用于点对点或者C/S架构的服务调用场景,比如Amazon S3 API。对于网状结构的微服务而言,中央授权是三种方式中最适合也是最灵活的选择:[list=1]
  • 简化了服务提供方的实现,让提供方专注于权限设计而非实现。
  • 更重要的是提供了一套独立于服务提供方和服务调用方的授权机制,无需重新发布服务,只要在授权中心修改服务授权规则,就可以影响后续的服务调用。
  • ## OAuth说起具体的授权协议,很多人第一反应就是OAuth。事实上也的确如此,很多互联网公司的开放平台都是基于OAuth协议实现的,比如Google APIs, 微信网页授权接口。一次标准的OAuth授权过程如下:
    oauth2.png
    对应到微服务场景,服务提供方相当于上图中的Resource Server,服务调用方相当于Client,而授权中心相当于Authorization Server和Resource Owner的合体。想了解更多关于OAuth的信息,可移步OAuth2或者OAuth2中文版。## Beared Token在标准的OAuth授权过程中,Resource Server收到Client发来的请求后,需要到Authorization Server验证Access Token,并获取Client的进一步信息。通过OAuth 2.0版本引入中的Beared Token,我们可以省去这一次调用,将Client信息存入Access Token,并在Resource Server端完成Access Token的鉴权。主流的Beared Token有SAMLJWT两种格式,SAML基于XML,而JWT基于JSON。由于大多数微服务都使用JSON作为序列化格式,JWT使用的更为广泛。# 框架选型在选型OAuth框架时,我主要调研了CAS,Apache Oltu,Spring Security OAuthOAuth-Apis,对比如下:
    oauth2-frameworks.png
    不考虑实际业务场景,CAS和Spring Security OAuth相对另外两种框架,无论是集成成本还是可扩展性,都有明显优势。前文提到,由于我们选用了Spring Boot作为统一的微服务实现框架,Spring Security OAuth是更自然的选择,并且维护成本相对低一些(服务端)。# 最终方案最终我们基于Spring Security OAuth框架实现了自己的服务授权中心,鉴权部分做的比较简单,目前只支持私网认证。大致的服务授权流程如下:
    oauth2-interaction.png
    oauth2-sequence.png
    值得一提的是,除了服务调用,我们的服务授权中心还增加了SSO的支持,通过微信企业号实现各个服务后台的单点登录/登出,以后有机会再详细介绍。# 冰山一角至此,这个微服务化改造系列就算告一段落,等以后有了更多的积累,我会继续写下去。微服务是一个很大的话题,自Martin Fowler于2014年3月提出以来,愈演愈热,并跟另一个话题容器化一起开创了一个全新的DevOps时代,引领了国内外大大小小各个互联网公司的技术走向,也影响了我们这一代程序员尤其是后端和运维的思维方式。从这个角度说,我写这个微服务化改造系列文章也是偶然中的必然,希望能给读过这些文章的你带来一些新的启发和思考。如果你对微服务也感兴趣或者有一些心得想跟我交流,欢迎在赞赏榜上留下你的微信号。

    少年读书如隙中窥月,中年读书如庭中望月,老年读书如台上玩月,皆以阅历之浅深为所得之浅深耳。-- 张潮 《幽梦影》

    # 参考

    微服务化改造系列之三:配置中心

    emac 发表了文章 • 0 个评论 • 6277 次浏览 • 2016-11-30 17:22 • 来自相关话题

    前情概要: - 微服务化改造系列之一:总览 > - 微服务化改造系列之二:服务注册中心 # 配置中心概述 这篇文章是微服务化改造系列的第三篇,主题是配置中心。上一篇我们谈到服务注册中 ...查看全部

    前情概要:



    - 微服务化改造系列之一:总览
    > - 微服务化改造系列之二:服务注册中心



    # 配置中心概述
    这篇文章是微服务化改造系列的第三篇,主题是配置中心。上一篇我们谈到服务注册中心,即通过提供某种注册和发现的机制,解决服务互通的问题。那么问题来了,一个服务如何知道服务注册中心的地址呢?这就涉及到服务配置了。我们知道,大至一个PaaS平台,小至一个缓存框架,一般都依赖于特定的配置以正常提供服务,微服务也不例外。
    ## 配置分类

    • 按配置的来源划分,主要有源代码(俗称hard-code),文件,数据库和远程调用。
    • 按配置的适用环境划分,可分为开发环境,测试环境,预发布环境,生产环境等。
    • 按配置的集成阶段划分,可分为编译时,打包时和运行时。编译时,最常见的有两种,一是源代码级的配置,二是把配置文件和源代码一起提交到代码仓库中。打包时,即在应用打包阶段通过某种方式将配置(一般是文件形式)打入最终的应用包中。运行时,是指应用启动前并不知道具体的配置,而是在启动时,先从本地或者远程获取配置,然后再正常启动。
    • 按配置的加载方式划分,可分为单次加载型配置和动态加载型配置。
    ## 演变随着业务复杂度的上升和技术架构的演变,对应用的配置方式也提出了越来越高的要求。一个典型的演变过程往往是这样的,起初所有配置跟源代码一起放在代码仓库中;之后出于安全性的考虑,将配置文件从代码仓库中分离出来,或者放在CI服务器上通过打包脚本打入应用包中,或者直接放到运行应用的服务器的特定目录下,剩下的非文件形式的关键配置则存入数据库中。上述这种方式,在单体应用阶段非常常见,也往往可以运行的很好,但到了微服务阶段,面对爆发式增长的应用数量和服务器数量,就显得无能为力了。这时,就轮到配置中心大显身手了。那什么是配置中心?简单来说,就是一种统一管理各种应用配置的基础服务组件。# 可选框架选型一个合格的配置中心,至少需要满足如下4个核心需求:
    • 非开发环境下应用配置的保密性,避免将关键配置写入源代码
    • 不同部署环境下应用配置的隔离性,比如非生产环境的配置不能用于生产环境
    • 同一部署环境下的服务器应用配置的一致性,即所有服务器使用同一份配置
    • 分布式环境下应用配置的可管理性,即提供远程管理配置的能力
    现在开源社区主流的配置中心框架有Spring Cloud Config和disconf,两者都满足了上述4个核心需求,但又有所区别。## Spring Cloud Config
    spring-cloud-config.png
    Spring Cloud Config可以说是一个为Spring量身定做的轻量级配置中心,巧妙的将应用运行环境映射为profile,应用版本映射为label。在服务端,基于特定的外部系统(Git、文件系统或者Vault)存储和管理应用配置;在客户端,利用强大的Spring配置系统,在运行时加载应用配置。## disconf
    disconf.jpg
    disconf是前百度资深研发工程师廖绮绮的开源作品。在服务端,提供了完善的操作界面管理各种运行环境,应用和配置文件;在客户端,深度集成Spring,通过Spring AOP实现应用配置的自动加载和刷新。# 方案选型不管是Spring Cloud Config还是disconf,默认提供的客户端都深度绑定了Spring框架,这对非Spring应用而言无疑增加了集成成本,即便它们都提供了获取应用配置的API。最终我们还是选用了微服务化改造之前自研的Matrix作为配置中心,一方面,可以保持新老系统使用同一套配置服务,降低维护成本,另一方面,在满足4个核心需求的前提下,Matrix还提供了一些独有的能力。
    • 分离配置文件和配置项。对于配置文件,通过各类配套打包插件(sbt, maven, gradle),在打包时将配置文件打入应用包中,同时最小化对CI的侵入性;对于配置项,提供SDK,帮助应用从服务端获取配置项,同时支持简单的缓存机制。
    • 增加应用版本维度,即对于同一应用,可以在服务端针对不同版本或版本区间维护不同的应用配置。
    • 应用配置的版本化支持,类似于Git,可以将任一应用配置回退到任一历史版本。
    进一步信息可参考我之前写的Matrix设计文档
    matrix.png
    Matrix架构图下一篇我将给大家介绍微服务架构的另一个基础组件——授权中心,敬请期待!#参考

    什么是服务网格?

    grace_shi 发表了文章 • 0 个评论 • 293 次浏览 • 2019-06-04 22:29 • 来自相关话题

    服务网格 是一个可配置的低延迟的基础设施层,目的是通过API(应用程序编程接口)处理应用程序服务之间的大量基于网络的进程间通信。服务网络确保容器化的短暂存在的应用程序的基础结构服务之间的通信快速,可靠和安全。网格提供关键功能,包括服务发现,负载平衡,加密,可观 ...查看全部
    服务网格 是一个可配置的低延迟的基础设施层,目的是通过API(应用程序编程接口)处理应用程序服务之间的大量基于网络的进程间通信。服务网络确保容器化的短暂存在的应用程序的基础结构服务之间的通信快速,可靠和安全。网格提供关键功能,包括服务发现,负载平衡,加密,可观察性,可追溯性,身份验证和授权,以及对断路器模式【1】的支持。

    服务网格是如何实现的呢?它通常会为每个服务实例提供一个称为边车(sidecar)的代理实例。这些边车会处理服务间的通信,监控和安全相关的问题, 以及任何可以从各个服务中抽象出来的东西。这样,开发人员就可以专注于服务中应用程序代码的开发,支持和维护,而运维团队可以负责维护服务网格以及运行应用程序。

    Istio,由Google,IBM和Lyft支持,是目前最著名的服务网格架构。Kubernetes,最初由Google设计,是目前Istio支持的唯一容器编排框架。供应商正在寻求商业版本的Istio。如果Istio能添加到开源项目中,将会带来更大的价值。

    Istio并不是唯一的选择,其他服务网格实现也在开发中。目前边车代理模式是最受欢迎的,例如Buoyant,HashiCorp,Solo.io等项目都使用了这种模式。与此同时,Netflix的技术套件使用了一种替代架构,他们使用了应用程序库(包含Ribbon,Hysterix,Eureka,Archaius)来提供服务网格功能,而Azure Service Fabric等平台在应用程序框架中嵌入了类似服务网格的功能。 服务网格包含一些专业术语来描述组件服务和功能:

    • 容器编排框架。随着越来越多的容器被添加到应用程序的基础架构中,用于监视和管理容器组的容器编排框架变得至关重要。
    • 服务和实例(Kubernetes Pod)。实例是微服务的单个运行副本。有时实例是一个容器;在Kubernetes中,一个实例由一小组相互依赖的容器(称为Pod)组成。客户端很少直接访问实例或Pod,通常他们会访问服务,服务通常是一组可扩展且具有容错性的实例或Pod(副本)。
    • 边车代理。 边车代理与单个实例或Pod一起运行。 边车代理的目的是路由或者代理从容器发出或者接收的流量。 边车与其他边车代理进行通信,编排框架会管理这些边车。许多服务网格的实现会使用边车代理来拦截和管理实例或Pod的所有进出流量。
    • 服务发现。当实例需要与不同的服务进行交互时,它需要找到 - 发现 - 其他服务的健康的,可用的实例。通常,这个实例会执行DNS查找来寻找其他服务的实例。容器编排框架保留实例列表(这些实例都可以正常接收请求),并且框架会提供DNS查询的接口。
    • 负载均衡。大多数编排框架已经提供了第4层(传输层)的负载均衡。服务网络实现了更复杂的第7层(应用层)负载均衡,具有更丰富的算法以及更强大的流量管理。同时可以通过API修改负载均衡的参数,从而可以编排蓝绿部署【2】或金丝雀部署【3】。
    • 加密。服务网格可以加密和解密请求和响应,因此每个服务不需要额外对请求进行加密,减少了负担。服务网格还可以通过优先重用现有的持久连接来提高性能,这减少新连接的创建(创建新连接十分耗费计算资源)。一般实现加密流量都是用双向TLS(mTLS),其中公钥架构(PKI,public key infrastructure)生成并分发证书和密钥,提供给边车代理使用。
    • 身份验证和授权。服务网格可以授权和验证从应用程序外部和内部发出的请求,仅向实例发送经过验证的请求。
    • 支持断路器模式【1】。服务网格可以支持断路器模式,这可以隔离不健康的实例,然后在安全的情况下逐渐将它们恢复并加入到健康的实例池中。

    服务网格应用中管理实例之间的网络流量的的部分称为数据平面。另外有一个独立的控制平面负责生成和部署数据平面的配置(这个配置可以控制数据平面的行为)。控制平面通常包含(或被设计为连接到)一个API,命令行界面和用于管理App的图形用户界面。

    *服务网格中的控制平面在数据平面中边车代理上分发配置*

    服务网格架构的一个常见用例是在使用容器和微服务时解决非常苛刻的操作问题。微服务领域的先驱包括Lyft,Netflix和Twitter等公司,这些公司任何时间都能为全球数百万用户提供强大的服务。 (请参阅我们对Netflix面临的一些架构挑战的深入描述。)如果应用程序对这方面要求比较低,那么更简单的架构就足够了。

    服务网格架构不可能解决所有应用程序操作和交付问题。架构师和开发人员可以选择多种工具,这些工具之中,有些是锤子,可以解决不同类型的问题,而另一些可能是钉子。例如,NGINX微服务参考架构包括几种不同的模型,这些模型提供了使用微服务来解决问题的一系列方法。 服务网格架构中的组成部分 - 例如:NGINX,容器,Kubernetes,以及微服务(作为架构方法),可以在非服务网格架构实现中高效地使用。例如,Istio是作为一个完整的服务网格架构开发的,但其模块化的设计意味着开发人员可以自由选择他们需要的部分组件技术。考虑到这一点,即使您不确定是否以及何时会完全实现服务网格应用程序,也值得深入了解一下服务网格概念。 

    注释: 

    【1】断路器模式: 一种设计模式。用以侦测错误,并避免不断地触发相同的错误(如维护时服务不可用、暂时性的系统问题或是未知的系统错误)。https://zh.wikipedia.org/wiki/斷路器設計模式 
    【2】蓝绿部署(blue‑green deployment):蓝绿部署是保留老版本,同时部署新版本然后进行测试,测试通过后,将流量切换到新版本,然后老版本同时也升级到新版本。 
    【3】金丝雀部署(canary deployment):又叫做灰度部署,即选择部分部署新版本,将部分流量引入到新版本,新老版本同时提供服务。等待灰度的版本测试完毕,之后全量覆盖老版本。 

    原文链接:What Is a Service Mesh? 

    ============================================================================== 
    译者介绍:Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

    Serverless的本质是什么?

    grace_shi 发表了文章 • 0 个评论 • 2470 次浏览 • 2018-06-18 19:34 • 来自相关话题

    【编者的话】这篇文章来自于The New Stask,是Serverlss系列的第一篇文章,这一系列文章是为了探索Serverless的本质,每周一更新。 Serverless直译为中文是“无服务器”,但是实际上它仍需要服务器,只不过 ...查看全部
    【编者的话】这篇文章来自于The New Stask,是Serverlss系列的第一篇文章,这一系列文章是为了探索Serverless的本质,每周一更新。

    Serverless直译为中文是“无服务器”,但是实际上它仍需要服务器,只不过服务器的管理以及资源分配部分对用户不可见,为避免误导读者,译文中还是将英文保留。

    最开始,一台单用户的物理服务器便能满足我们的日常所需,它快速,可靠并且安全,只对管理员负责。但是在实际中配置和扩展都很麻烦。虚拟机的出现满足了灵活性和可扩展性的需求,之后云服务提供商为我们带来了基础架构即服务(IaaS),云平台自助服务也由此诞生。在这片肥沃的土壤中出现AWS(Amazon Web Services),编排,以及基础设施即代码(IaC),之后开始了集装箱化,带来了平台即服务(PaaS)的架构,一切看起来都很顺利......但程序员仍想要更多的功能,如独立于编程语言(language agnostic)的端点,服务器的水平伸缩能力,以及可以实时支付服务使用量的能力。

    为了满足这些需求,Serverless计算应运而生,Serverless计算也被称为功能即服务(FaaS)。运行时只会执行程序但不会存储数据。这意味着像AWS(Amazon Web Service),谷歌云以及微软Azure云这样的云服务提供商会动态的管理资源的分配和分布。

    Serverless是付完即走,基于实际的消费而不是基于预测的预付款进行收费的。这本是基础设施应该有的样子,在2018年终于出现在我们面前。
    # 这并不是魔法
    首先,这个名字非常有误导性。 Serveless(无服务器)计算仍然需要服务器,它并不是什么神秘魔法。

    这个术语的出现是因为服务器的管理以及容量规划都被隐藏起来了。Serverless被称作是无服务的是因为用户/程序员无需关心甚至意识到基础架构的存在——服务器被完全抽象出去了。Serveless代码可以和传统方式部署的代码一起使用,例如微服务,甚至一个应用程序可以完全不需要配置服务器,只需要以无服务器的方式编写即可。

    Serveless 真正的价值不在于节省了成本,而在于节省了时间。



    Bitnami的现任云技术高级总监Sebastien Goasguen说到“我会把Serverles 想像成一个具有微型PaaS的像胶水一样的软件,它最大的优点就是可以从云中发生的事件中调用函数(即胶水)“,Goasguen描述了一个场景,例如,将图像放在AWS(Amazon Web Service)的storage bucket中存储,然后调用函数来调整该图像的大小。Serverless系统会获取这段代码并且自动注入到运行时环境(服务器或者容器),之后将这个函数暴露出来以便调用。
    # 那么,讲完了什么是Serverless,然后呢?
    传统云计算和Serverless云计算最主要的区别在于客户是否需要为未被使用或者未被充分使用的资源支付费用。以前,无论是内部数据中心还是云上,我们都需要提前预测容量和资源需求,并且提前准备好。在之前的例子中,这意味着我们提前启动AWS服务器以便随时执行这项调整镜像大小的服务。而在Serverless配置中,你只需要调整代码执行的时机,即只在函数被调用时候执行。

    Serverless计算服务将您的函数作为输入,执行逻辑,返回输出,之后关闭。你只需要为函数实际执行所消耗的资源付费。

    即用即付(Pay-as-you-play),并且只用为你实际使用的资源付费,这显然是件好事,但是Goasguen以及其他Cloud Native的专家强调Serverless真正的价值在于时间效率,而不是成本效率。
    # 像时间机器一样?
    Serverless就像一扇通往未来的门,它和其他即服务(other as-a-service)的技术一样,为公司提供了很多工具,可以让公司专注于构建使用如AI,机器学习等尖端技术的应用程序。而不是浪费时间精力在不停的构建,重建必需的基础设施。

    Serverless其他的时间机器功能在于缩短了从代码开发到投入生产的时间。它真正实现了“这是我的代码,现在立刻运行它”。不会因为基础设施产生延迟。

    Oracle公司负责Serverless业务的副总裁Chad Arimura说到“Serverless的基本思想是程序员只需要写代码然后推送到Serverless的服务就足够了,其余的事情都由这个服务来处理”。他还补充道,像数据库和数据存储这类的依赖关系也被当作服务无缝集成到Serverless底下。

    Arimura说到“在Serverless背后,专业的团队和自动化工作相结合,大规模的操作这些系统,以便开发人员无需考虑这些问题,这项技术看起来就像是魔法一样,这也是为什么这项技术被炒作的如此厉害,正因为它带给了我们如此美妙的体验”。
    # 感受 FaaS(功能即服务)平台的强大
    虽然Docker技术简化了分布式应用打包和依赖管理的问题。Kubernetes帮助企业在生产中运行这些应用。但是使用它们并不简单易用。Dcokerfile, 、基础设施细节、Kubernets manifests文件,这些即便对于程序员听众来说,也异常复杂。

    Serverless计算的核心就是作为一个功能即服务平台。从本质上讲亚马逊的AWS Lambda以及Google Cloud Function就是Serverless的实现。它们处理了资源管理,负载均衡以及多线程,开发人员就可以只关注他们的代码,而企业只用关心他们的目标。

    iguaz.io的创始人兼CTO Yaron Haviv提到,一个持续的数据平台是为提升云上的性能而设计的,将一个新的技术栈按照FaaS(功能即服务)的工作流运行一遍,步骤如下:

    1. Serverless平台提取了功能代码——即FaaS(功能即服务)的功能部分——以及所有依赖项(如必需的库,内存的数量,属性等等),构建成一个集装箱化的应用程序包,通常采用Docker镜像的形式。
    2. 当另一个平台服务,例如对象存储或数据库想要触发这个功能,或者一个外部的http请求想要调用这个功能,Serverless平台会将这个请求转发到一个可用的功能微服务。如果当前没有可用的微服务,那么它将部署“冷启动”(cold start)一个这样的实例。
    3. Serverless平台需要负责在微服务失败的时候恢复它,自动扩展以适应需求,记录和监控功能活动,并且在代码被修改后进行实时滚动升级。专门有人来管理平台服务,这样程序员就可以专注于“功能”方面。

    # 那么Severless的缺点是什么呢?
    除了以上列出的优点之外,FaaS(功能即服务)也存在一些潜在的缺点。专家提到,云服务提供商通常会降低那些不经常的运行环境的资源,他们也会限制你的可用资源的总量,由此带来延迟以及低性能问题。并且由于任何云计算工作流事实上都会运行在一个公有云环境,而你无法控制或者进入这些云环境,导致监控,调试,以及安全性都无法保障。

    亚马逊Lambda已成称为Serverless计算的代名词,这也是大多数人可以完全理解一种Servless的模式。尽管Lambda已经开辟了Serverlss的前路,它也涵盖了所有Serverless的缺点:缓慢的冷启动(cold start),低性能,短时间存在的功能,以及一组封闭的触发器。目前普遍认为,所有的Severless平台都具有这些限制性,但事实上这些限制性可以在平台的实施中避免。值得注意的是有一些更新的Serverless平台比如 Nuclio,它演变出了很多更广泛的用例,这些更新的平台具有更少的限制,更高的性能,并且可以运行在多个云服务上甚至是内部环境。

    Haviv说道“极客们喜欢Serverless,但是企业们仍在试水——他们甚至还没有熟悉Docker/Kubernetes,Serverless就开始出现了”,就如任何新技术一样,一开始总是由一些聪敏,愿意冒险的早期受众开始试用,之后慢慢面向大众。而大众往往需要在看到这项技术是值得信赖,并且有可靠证据证明它能解决性能问题,安全问题等等问题之后才会采用这项技术。

    鉴于Serverlss这项技术几乎每天都在发展壮大,所以并非所有的方面都可以令人满意。虽然称不上是个缺点,但是这一点的确令整个董事会坐立不安。Haviv 指出“由于数字化转型”正影响着当代企业,创新者们以及Serverless一类的某某即服务(Other As A Service)技术正在威胁着现任者,让企业变的更加敏捷以及更加愿意承担风险。最有趣的是尽管Serverless比Docker/Kubernetes技术更新,但如果将Docker/Kubernetes的复杂性抽象出来,Serverless会更快更容易的被采用。
    # 如何知道Serverless是否适合你的公司
    这里不是讨论你的公司到底适不适合Serverless,这里只是讨论一下那些最先采用Serverless技术的公司。

    Oracle的Arimura说道“表面上来说,任何编写软件的公司和组织都非常适合采用Serverless”,不过,就当前的文化以及离达成全面“原生云”目标的距离而言,采用Serverless将会使这个过程变得更加艰难。换句话说,如果一个公司没有使用过任何的公有云,没有任何Docker/Kubernetes的实施经历。那么他们就不该从Serverless开始。

    “这是一种全新的架构,需要完全不同的思维方式,最简单的例子就是如果要把一个单体应用拆分成10个微服务,100个函数,并且每个都具有独立的部署周期以及复杂的依赖图,配合成熟健壮的CI/CD以及自动化的系统。把这些和Serverlss一起使用的时候,将会大幅提升敏捷性和创新性,但是如果仅仅只有其中一个,那么带来的损失远大于收益。”

    Arimura继续说道 “这就是为什么Devops(运维人员)不会变成noOps(无运维人员),因为这是一条完全错误的方向。“事实上,Serverless的出现使得DevOps比以往更重要。

    事实上,Bitnami的Goasguen指出,他观察到的大部分使用Serverless的公司都是以程序员为中心的组织,尤其是使用AWS Lamba服务的,这些公司原本就使用AWS并且用AWS将服务连接在一起。 Goasguen说道“所以很有可能,如果你不使用AWS,那么你便不需要Serverless,但是你始终需要保持警惕,开始评估,辨别企业中哪些事件源可以被用来建立完整的应用程序管道。
    # 企业试水Serverless的最佳途径?
    Arimura建议道“如果一个企业仍处在适应DevOps的阶段,那么它不需要一开始就将一个大型的单体应用完全拆分转换成微服务或者功能,或是为了学习一个新架构就在一个重要的新项目中使用这项技术。最好是从小处着手,例如创建一些自动化的任务,或是事件驱动的用例。”

    本系列Serverless的文章可以帮助您的公司开始使用这项技术。

    原文链接:Serverless 101: How to Get Serverless Started in the Enterprise

    ==============================================================================
    译者介绍
    Grace,程序员,研究生毕业于SUNY at Stony Brook,目前供职于Linktime Cloud Company,对大数据技术以及数据可视化技术感兴趣。

    如何开启Kubernetes之旅

    justinfu 发表了文章 • 0 个评论 • 5604 次浏览 • 2017-07-19 18:56 • 来自相关话题

    【译者的话】这篇文章由浅入深地介绍了如何开始Kubernetes学习,以及如何基于Kubernetes部署应用。作者给出了很多非常好的建议,指导读者掌握围绕Kubernetes的各个概念和相关技能,为学习Kubernetes指明了方向。 ...查看全部
    【译者的话】这篇文章由浅入深地介绍了如何开始Kubernetes学习,以及如何基于Kubernetes部署应用。作者给出了很多非常好的建议,指导读者掌握围绕Kubernetes的各个概念和相关技能,为学习Kubernetes指明了方向。

    从Hello Minikube到Kubernetes Anywhere,再到微服务示例应用,学习谷歌容器编排工具的途径比比皆是。



    每一次的创新都带来一些新的麻烦。容器使得应用的打包和运行更加便捷,但是管理大规模容器依然是一个挑战。

    Kubernetes是谷歌公司内部为解决这个问题而开发的产品,它提供了一个单一的框架来管理在整个集群中运行的容器。该产品提供的服务主要集中在“编排”上,但也涵盖了许多方面:容器调度、容器之间的服务发现、跨系统的负载平衡、滚动更新/回滚、高可用性等。

    在这个指南中,我们将介绍创建Kubernetes集群并发布容器应用的基本知识。这并不是要介绍Kubernetes的概念,而是通过简单示例来展示这些概念如何在运行Kubernetes的过程中结合在一起的。
    # 选择一个Kubernetes主机
    Kubernetes是为了管理Linux容器而诞生的。但是,从Kubernetes 1.5起,尽管Kubernetes控制面板必须继续在Linux上运行,但Kubernetes已经开始支持Windows Server Containers。当然,借助虚拟化,您可以在任何平台上开始使用Kubernetes。

    如果您选择在自己的硬件或虚拟机上运行Kubernetes,一个常见的方法是获取绑定Kubernetes的Linux发行版。这样就不需要设置Kubernetes,不仅省去了安装和部署过程,甚至配置和管理的过程也不需要了。

    CoreOS Tectonic就是这样的一个发行版,专注于容器和Kubernetes,几乎完全排除其他任何东西。RancherOS采取类似的做法,同样自动化执行大部分的设置。两者都可以安装在各种环境中:裸机,Amazon AWS VMs,Google Compute Engine,OpenStack等。

    另一种方法是在常规的Linux发行版上运行Kubernetes,尽管通常会带来更多的管理开销和手动调整。例如,红帽企业Linux在其软件库中有Kubernetes,但即使是Red Hat,也建议仅用于测试和实验。建议红帽用户通过OpenShift PaaS使用Kubernetes,而不是自己动手从头搭建,OpenShift现在使用Kubernetes作为自己的容器编排系统。许多传统的Linux发行版提供了设置Kubernetes和其他大型软件堆栈的特殊工具。例如,Ubuntu提供了一种名为conjur-up的工具,可用于在云和裸机实例上部署Kubernetes的上游版本
    # 选择一种托管Kubernetes的云
    尽管在谷歌云平台(GCP)上,Kubernetes已经全面支持了,但是在很多其他云平台上,Kubernetes是否支持依然是一个焦点问题。GCP提供了运行Kubernetes的两种主要方式。最方便和集成最好的方式是通过Google容器引擎,它允许您运行Kubernetes的命令行工具来管理创建的集群。或者,您可以使用Google Compute Engine来创建计算集群并手动部署Kubernetes。这种方法对用户的技能要求比较高,但是允许用户使用Google Container Engine尚未支持的个性化定义。如果您刚开始接触容器,最好坚持使用容器引擎。经过一段时间之后,您对Container Engine有了一定的了解,就可以尝试一些更高级的内容,比如您自己选择特定版本的Kubernetes进行部署,或者部署运行Kubernetes发行版的虚拟机。

    亚马逊EC2有容器的原生支持,但没有原生支持Kubernetes作为容器编排系统。在AWS运行Kubernetes类似于使用谷歌计算引擎:配置一个计算集群,然后手动部署Kubernetes。

    许多Kubernetes的发行版都有如何在AWS部署的详细说明。例如,CoreOS Tectonic,有一个图形化的安装程序,同时还支持Terraform基础设施配置工具。此外,Kubernetes kops工具可以被用来配置一组AWS上的虚拟机集群(通常使用Debian Linux,但是其他的Linux版本也部分支持)。

    微软Azure通过Azure Container Service来支持Kubernetes。然而,从将Kubernetes作为一个托管在Azure上的服务这个角度来说,这不是很“原生”的支持。相反,Kubernetes是由一个Azure资源管理模板部署的。Azure对于其他的容器编排系统(比如Docker Swarm和Mesosphere DC/OS)的支持也是这种思路实现的。如果您在这里提到的任何其他的云中部署Kubernetes,并且希望完全控制它,在Azure虚拟机上安装一个Kubernetes的核心版永远是简单可行的办法。

    在各种环境(云端或其他方式)中快速配置一个基础Kubernetes集群的方式就是使用名为Kubernetes Anywhere的项目。此脚本适用于Google Compute Engine,Microsoft Azure和VMware vSphere(需要vCenter)。在每种情况下,它为启动过程提供了一定程度的自动化。
    # 您自己的小部分Kubernetes节点
    如果你只是在一个像开发机器这样的本地环境中运行Kubernetes,而且你不需要整个Kubernetes全部能力,那么有几种方法可以设置“刚好足够”的Kubernetes来进行使用。

    其中一种方式是使用由Kubernetes开发团队本身提供的MiniKube。运行它,您会得到一个单节点Kubernetes集群部署在您选择的虚拟主机上。minikube有几个前提,如kubectl命令行接口和虚拟化环境如VirtualBox,但那些都有现成的二进制,支持MacOS,Linux和Windows。

    对于MacOS上的CoreOS用户,有Kubernetes Solo。它运行在一个CoreOS虚拟机上,提供了一个状态栏应用程序实现快速管理。Solo也包括Kubernetes包管理程序Helm(通常是Helm下一级),因此基于Kubernetes的应用程序包更容易获取和设置。
    # 玩转您的容器集群
    当您的Kubernetes运行起来之后,您就可以运行和管理容器了。通过部署和管理基于很多容器的应用示例的方式,您可以轻松地熟悉容器的操作。以一个现有的基于容器的应用程序demo为例,自己组装它,看看它是如何组成的,部署它,然后逐步修改它,直到满足您的预期。如果您选择通过minikube找到立足点,您可以使用Hello Minikube教程创建Docker容器,将这个运行简单的Node.js应用的容器托管在单节点Kubernetes,以此来演示集群安装和应用部署。一旦您对这些都熟悉了,您就可以替换成自己的容器,并做一些实践性部署。

    下一步是部署一个示例应用程序,这个程序类似您可能在生产环境中使用的应用。通过这个应用您可以进一步熟悉Kubernetes的一些高级概念,比如pods(一个或多个容器,包括一个应用程序),service(一组逻辑的Pod),replica sets(提供应用在机器故障时的修复机制)和deployment(应用程序的版本)。揭开WordPress/MySQL示例应用程序的神秘面纱,例如,你看到的将不仅仅是如何将应用部署到Kubernetes,并让这些应用正常运行。您也将看到Kubernets应用涉及的很多概念的实现细节,而这些应用都是满足生产环境要求的。您将学习如何设置持久卷以保存应用程序的状态,如何将Pod暴露给彼此,以及如何通过services与外部世界连在一起,以及如何将应用程序密码和API密钥存储为secrets等等。

    Weaveworks有一个示例应用程序,袜子商店,展示了微服务模式如何用来组合Kubernetes中的应用。袜子商店对于熟悉底层技术(比如Node.js,Go kit和Spring Boot)的人来说是最有利的,但主旨超越了特定的框架,而是说明云原生技术。

    如果您看了一眼WordPress/MySQL的应用,并想创建一个运行在Kubernetes上的应用来满足您的需求,这种想法基本上是对的。Kubernetes有一个应用程序定义的系统称为Helm,它提供了一种打包、版本管理和共享Kubernetes应用的机制。一些主流的应用程序(GitLab,WordPress)和构建应用程序的模块(MySQL、NGINX)将Helm作为一站式直通kubeapps门户的最佳实践。
    # 深入探索Kubernetes
    Kubernetes通过强大的抽象能力简化了容器的管理,比如Pod和Service,同事通过label和namespace机制提供了很大的灵活性,label和namespace都可以用来隔离pod,services和deployments(比如开发环境、过渡环境和生产环境负载)。

    如果您选择上面的示例的一个,并在多个命名空间中创建不同的实例,那么可以对独立于其他命名空间的组件进行更改。您可以使用deployments,以允许这些更新在给定的命名空间中的多个pod之间滚动进行

    比这种练习更进一步的是学习Kubernetes本身如何能够被管理基础设施的工具所驱动。以Puppet为例,有一个用于创建和操纵Kubernetes资源的模块,但是HashiCorp’s Terraform很早就有支持,但是支持方式演变成将Kubernetes作为一种资源进行管理。如果您打算使用这样的资源管理器,请注意不同的工具可能会给表带来不同的预期结果。以Puppet and Terraform为例,默认分别使用可变的和不可变的基础设施。这些哲学层次和行为的差异,如何或轻松,或困难地创建您所需要的Kubernetes。

    这个故事,“如何开启Kubernetes之旅”最初发表在InfoWorld

    原文链接:How to get started with Kubernetes (翻译:付辉)

    Netflix Conductor:一个微服务编排工具

    justinfu 发表了文章 • 0 个评论 • 15253 次浏览 • 2017-04-29 08:09 • 来自相关话题

    【译者的话】这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发。 【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述 ...查看全部
    【译者的话】这篇文章介绍了Netflix Conductor,一个微服务编排工具,为微服务执行复杂业务流程提供了一种思路,希望对读者有一定的启发。

    【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述、架构、日志和监控,部署、自动驾驶、服务发现、网络方案等核心机制分析,进阶篇——Kubernetes调度工作原理、资源管理及源码分析等。

    Netflix内容平台工程团队运行许多业务流程,这些业务流程是通过在微服务上执行异步编排任务来驱动的。其中一些流程运行时长多达数天。这些流程在让一切准备好,以呈现给全球用户的过程中,起到了至关重要的作用。

    这些流程的几个例子:

    + 整合工作室合作伙伴的内容摄取
    + 从我们的合作伙伴摄入基于IMF的内容
    + 在Netflix中设置新的标题的过程
    + 内容摄取,编码和部署到CDN

    按照传统做法,这其中一些进程已经使用发布/订阅模式,直接进行REST调用以及使用数据库来管理状态的组合进行了自组织的编排。然而,随着微服务数量的增长和流程的复杂性不断增加,如果没有中央协调人员,这些分布式工作流程的可见性将变得困难。

    我们构建了“作为业务流程引擎”的Conductor,以满足以下要求,消除在应用程序中对模板的需求,并提供流程相关的执行动作:

    + 以蓝图为主,基于JSON DSL的蓝图定义了执行流程;
    + 跟踪和管理工作流;
    + 能够暂停,恢复和重新启动流程;
    + 用户界面可视化流程;
    + 能够在需要时同步处理所有任务;
    + 能够扩展到数百万个同时运行的流程;
    + 由客户抽象的排队服务提供后端支持;
    + 能够通过HTTP或其他传输操作,例如gRPC;

    Conductor是为满足上述需求而建立的,目前已在Netflix上使用。到目前为止,它已经帮助协调了260多万个流程流程,从简单的线性工作流程到跨越多天运行的非常复杂的动态工作流程。

    今天,我们是开放Conductor给更广泛的社区,希望从具有相似需求的其他人那里学习,增强其能力。您可以在这里找到Conductor的开发人员文档。
    # 为什么不对等编排?
    通过对等任务编排,我们发现随着业务需求和复杂性的增长难以扩展。发布/订阅模式为最简单的流程工作,但很快突出了与该方法相关的一些问题:

    + 流程“嵌入”在多个应用程序的代码中;
    + 通常,关于输入/输出,SLA等的紧耦合和不确定性,使其难以适应不断变化的需求;
    + 不清楚当前执行的任务属于整个流程的哪个阶段;

    # 为什么是微服务?
    在微服务世界中,许多业务流程自动化是通过协调服务来驱动的。Conductor可以在服务之间进行协调,同时提供对它们的相互作用的控制和可见性。有能力在微服务之间进行协调,也帮助我们利用现有服务来构建新流程或更新现有流程,以便使用Conductor非常快速,有效地提供了更容易采用的方法。
    # 架构概览
    Netflix_Architect.png

    在发动机的核心是一个状态机服务又名的决策服务。随着工作流事件的发生(例如任务完成,故障等),决策者将工作流程蓝图与工作流程的当前状态相结合,识别下一个状态,并安排适当的任务和/或更新工作流的状态。

    决策者使用分布式队列来管理计划任务。我们一直在Dynomite之上使用dyno-queue来管理分布式延迟队列。队列“食谱”今年早些时候开放,这里是博客文章。
    ## 任务执行者的实现
    由Worker实现的Tasks通过API层进行通信。Worker通过实现可由业务流程引擎调用的REST端点或实现定期检查待处理任务的轮询机制来实现此目的。Worker是幂等无状态的功能。轮询模型允许我们处理worker背后的压力,并在可能的情况下根据队列深度提供自动可扩展性。Conductor提供API来检查可用于自动调整工作实例的每个工作人员的工作负载大小。
    Worker_Communication_With_Engine.png

    ## API层
    API通过HTTP协议公开 - 使用HTTP允许轻松地与不同的客户端集成。然而,添加另一个协议(例如,gRPC)应该也是可能的并且相对简单。
    ## 存储
    我们使用Dynomite“作为存储引擎”以及Elasticsearch来索引执行流程。存储API可插拔,可适用于各种存储系统,包括传统的RDBMS或Apache Cassandra,如no-sql存储。
    # 核心概念
    ## 工作流
    工作流程使用基于JSON的DSL进行定义。工作流程蓝图定义了一系列需要执行的任务。每个任务都是控制任务(例如,分支,连接,决策,子工作流程等)或工作任务。工作流定义被版本化,提供管理升级和迁移的灵活性。一个工作流定义:
     {
    "name": "workflow_name",
    "description": "Description of workflow",
    "version": 1,
    "tasks": [
    {
    "name": "name_of_task",
    "taskReferenceName": "ref_name_unique_within_blueprint",
    "inputParameters": {
    "movieId": "${workflow.input.movieId}",
    "url": "${workflow.input.fileLocation}"
    },
    "type": "SIMPLE",
    ... (any other task specific parameters)
    },
    {}
    ...
    ],
    "outputParameters": {
    "encoded_url": "${encode.output.location}"
    }
    }

    ## 任务定义
    每个任务的行为由其称为任务定义的模板控制。任务定义为每个任务提供控制参数,例如超时,重试策略等。任务可以是由应用程序实现的工作任务或由业务流程服务器执行的系统任务。Conductor提供开箱即用的系统任务,如决策,叉,连接,子工作流程以及允许插入自定义系统任务的SPI。我们增加了对HTTP任务的支持,有助于调用REST服务。一个任务的定义如下:
     {
    "name": "encode_task",
    "retryCount": 3,
    "timeoutSeconds": 1200,
    "inputKeys": [
    "sourceRequestId",
    "qcElementType"
    ],
    "outputKeys": [
    "state",
    "skipped",
    "result"
    ],
    "timeoutPolicy": "TIME_OUT_WF",
    "retryLogic": "FIXED",
    "retryDelaySeconds": 600,
    "responseTimeoutSeconds": 3600
    }

    ## 输入/输出
    任务的输入是一种的映射,即工作流实例化或其他任务的输出的一部分。这种配置允许将来自工作流或其他任务的输入/输出作为可以随后作用于其的任务的输入。例如,可以将编码任务的输出提供给发布任务作为部署到CDN的输入。一个输入的定义如下:
     {
    "name": "name_of_task",
    "taskReferenceName": "ref_name_unique_within_blueprint",
    "inputParameters": {
    "movieId": "${workflow.input.movieId}",
    "url": "${workflow.input.fileLocation}"
    },
    "type": "SIMPLE"
    }

    # 一个案例
    下面是一个非常简单的编码和发布流程:
    encode-deploy-flow.png

    共有3个工作任务和一个控制任务(错误)涉及:

    1. 内容检查:检查输入位置的文件是否正确/完整
    2. 编码:生成视频编码
    3. 发布:发布到CDN

    这三个任务由不同的worker实现,这些worker使用任务API轮询待处理的任务。这些是理想的幂等任务,对任务的输入进行操作,执行工作并更新状态。

    每个任务完成后,决策者根据蓝图(对应于工作流实例的版本)评估工作流实例的状态,并标识要排定的下一组任务,如果完成所有任务,则完成工作流。
    # UI
    UI是监控和排除工作流执行的主要机制。 UI通过允许基于包括输入/​​输出参数在内的各种参数的搜索来提供对流程的非常需要的可见性,并提供蓝图的可视化呈现以及所采用的路径,以更好地了解流程执行。对于每个工作流实例,UI提供每个任务执行的详细信息,具体如下:

    + 任务安排的时间戳,由worker获取并完成。
    + 如果任务失败,失败的原因。
    + 重试次数
    + 执行任务的主机。
    + 在任务完成后提供给任务和输出的输入。

    下图是UI的一个样例:
    Task-UI.png


    原文链接:Netflix Conductor : A microservices orchestrator(翻译:付辉)

    业务逻辑的演进——从单体应用到微服务再到函数

    justinfu 发表了文章 • 0 个评论 • 3251 次浏览 • 2017-03-31 08:45 • 来自相关话题

    【译者的话】这篇文章介绍了业务逻辑从单体应用到微服务模式,再到事件驱动函数模型的进化过程。从原理上剖析了每一次进化的动机,为我们揭示了变化背后的深层次原因,非常具有启发性。 【上海站|3天烧脑式Spring Cloud训练营】培训内容 ...查看全部
    【译者的话】这篇文章介绍了业务逻辑从单体应用到微服务模式,再到事件驱动函数模型的进化过程。从原理上剖析了每一次进化的动机,为我们揭示了变化背后的深层次原因,非常具有启发性。

    【上海站|3天烧脑式Spring Cloud训练营】培训内容包括:DevOps、微服务、Spring Cloud、Eureka、Ribbon、Feign、Hystrix、Zuul、Spring Cloud Config、Spring Cloud Sleuth等。

    基础技术在不断进步,正在促进事件驱动函数模型的发展,于此同时也在快速提升业务逻辑的`时效`。

    更新:感谢读者的阅读和反馈, 关于这篇文章中阐述的观点,我在microxchg录制了一个视频,大家可以点击这里观看。



    运行应用软件的目的在于提供某种业务价值。价值通过创建和使用业务逻辑来传递,以便它可以为一些用户提供服务。从开始创建业务逻辑到最终交付,为用户提供服务之间的时间称之为`时效`。提供业务价值的成本等于创建业务逻辑的成本与交付业务逻辑的成本之和。

    过去成本高昂、效率是主要考虑因素,高`时效`被认为是常态。今天,随着技术进步和成本的降低,在竞争压力的推动下,组织在评估和优化企业流程的时候,`时效`正在成为主要考察指标。换句话说,为了提升投资回报率,您需要找到增加回报率的方法,提前获得回报或减少投资。

    问题的核心在于,当成本占主导地位时,随着成本的降低和软件的影响力的增加,焦点必然转向早日得到回报。

    随着技术在过去十年的发展,我们已经看到从单体应用程序到微型服务的发展,现在看到由AWS Lambda领导的无服务器架构、事件驱动函数模式的兴起。是什么因素推动了这种演变?低延迟消息传递使得从单体应用转到微服务,低延迟配置使得能够转移到Lambda。

    在十年前,由于时间的限制,单体应用是交付业务逻辑的最佳方式。在五年前,由于限制因素的改变,微服务成为了最好的交付模式。新的应用程序开始建立在微服务架构上,而在过去的几年中,工具和开发实践已经全面支持微服务。时至今日,事件驱动函数模式再次发生了改变,因为潜在的限制已经发生变化,成本降低了,`时效`的根本改善也是可能的。

    接下来,我们将详细介绍这种变化的不同维度:交付技术,硬件性能和组织架构实践,并了解它们如何结合起来推动这一变革。

    在最开始的时候,交付成本是主要的考虑因素。采购、配置和部署硬件需要花费很长的时间,并且软件安装也是纯手动操作。为了优化交付,每个版本中包含大量业务逻辑,在这些业务逻辑上摊销过高的成本。与此同时,发布周期也不频繁,对于很多组织来说,`时效`通常数月有余。由于基础设施的变更交付周期很长,所以有必要提前预先提供额外的能力,这导致非常低的平均利用率。

    降低交付成本的第一步将重点放在流程自动化上。许多组织开发了自定义脚本来部署新硬件、安装和更新应用程序。最终像Puppet和Chef这样常见的框架变得流行起来,“基础设施即代码”加速了更新的交付。DevOps运动开始于运营团队采用敏捷软件开发实践,并与开发人员紧密合作,以此将`时效`从几个月减少到几天。脚本可以改变已有的基础设施及应用,但快速增长的业务或具有不可预测的工作负载,正在努力寻求新的容量(译者注:这里的容量指的是新的计算资源),通过调用Amazon EC2弹性扩容API可以解决这个问题。当开发人员有能力使用Web服务直接自动化许多操作任务时,新一轮全新的DevOps即将到来。按需部署、按时付费的能力可以实现更高的平均利用率,并自动处理突然爆发的工作负载。

    当Docker将容器变得“老少皆宜”时,另一波提升交付的浪潮来到了。Docker提供了一种方便的打包格式,这种格式包括一组固定的依赖关系,一个比进程隔离性更强、但弱于虚拟机的运行时环境。容器能够在秒级时间内启动,并且节省大量的内存占用空间。通过将许多容器打包到一个实例上,可以将运行时间从几个小时缩短到数分钟甚至数秒,资源利用率也大幅提升。基于容器的持续交付工具链也提升了开发人员的工作效率,缩短了交付时间。当有大量可预测的工作负载时,容器可以运行在高利用率水平,但是大多数时候工作负载是不可预测的,要么处于峰值要么处于低谷。例如,工作场所使用的应用程序只在一周168小时内的40个小时中使用。为了保持高可用性,通常将应用程序实例扩展到三个可用区域,甚至每个区域需要多个实例。因此一个服务最少需要六个实例。如果我们想缩容到0个实例,那么我们需要找到一种机制,在事件发生时启动应用的一个部分,当事件完成后则关停这部分应用。这是AWS Lambda功能的关键部分,它能在0.1秒的时间内对正在使用的计算资源进行扩容,并根据需要从零扩展到非常高的容量,从而保证峰值和低谷时的工作负载都是有效的100%利用率。从而没有必要考虑如何配置服务器,这就是为什么这通常被称为无服务器模式。

    交付技术的进步为改进`时效`提供了垫脚石,但是在过去十年中,还有其他潜在的变化导致了最佳实践的一系列转型。

    业务逻辑的大小取决于在满足服务延迟要求的条件下,计算资源(CPU/内存/网络/磁盘)的成本,以及访问相应资源的响应时间。

    对于终端用户来说,对于业务逻辑响应时间的要求并没有太大变化。在过去十多年里,基础技术发生了翻天覆地的变化,然而对响应时间的感知和期望确一直基本没变。CPU的计算速度在过去十年中增长缓慢,时钟频率始终在几GHz左右,然而芯片缓存却增长很快,而且CPU核数也在不断增加。内存速度和大小的提升也较为缓慢。

    网络现在的传输速度相当快了,常见的从1GBit到10GBit,再到现在的25GBit(正如James Hamilton在他的AWS re:Invent 2016主题演讲中所解释),而且软件协议的效率更高。当通常的做法是通过1GBit网络发送XML有效负载时,通信开销将业务逻辑限制在与大型单体服务共同位置,并直接连接到数据库。十年以后,在25GBit网络上的编码效率将提升一个数量级,这意味着通信成本会降低两个数量级以上。换句话说,十年前服务之间发送和处理一条消息的时间,如今可以达到100至1000条。这是从单体应用架构转移到其他架构模式的关键推动因素。

    存储和数据库在过去十年中也经历了一场革命。单体应用将业务逻辑映射到基于复杂关系型数据库模式的事务,这些数据库模式链接了很多的表,并且提供统一的原子更新。十年前,最佳实践是通过存储区域网络建立少数的大型集中式关系数据库,这些数据库后端连接着价格昂贵的磁盘阵列,磁盘与数据库之间建立巨大的缓存池。

    今天高速缓存的磁盘已被固态磁盘所取代。不同之处在于读取速度从缓慢、昂贵和不可预测(因为缓存命中率不一致)变得持续快速,且几乎无限制。由于磨损均衡算法和其他影响,写入和更新从缓存磁盘的快速迁移到固态磁盘的具有不可预测性。由于众多原因,新的“NoSQL”数据库架构已经变得流行,但我们关注的只有两点:简单的数据模型和充分利用了固态存储的优势。简单的模式强制将在同一关系数据库中链接在一起的数据表分离成多个独立的NoSQL数据库,从而推动业务逻辑的分散化。Amazon DynamoDB数据存储服务从一开始就设计为只在固态磁盘上运行,为请求提供极其一致的低延迟。Apache Cassandra的存储模型生成大量随机读取,并且很少进行大量写入,无更新,非常适合固态磁盘。与关系数据库相比,NoSQL数据库提供简单但极具成本效益,高可用性和可扩展性的数据库,并且具有非常低的延迟。NoSQL数据库的普及率快速增长是单体应用架构模式转移的另一个关键推动因素。其余关系型的主要模式被剔除,或者变得更容易扩展,并被迁移到诸如Amazon的RDS和Aurora之类的服务中。

    当我们看IT的变化时,常常谈论“人,过程和技术”。我们刚刚看到技术如何将利用率和部署速度提高到了AWS Lambda的极限,在几分之一秒内实现了所部署的应用100%利用率。技术也将单体逻辑代码分解成数以百计的微服务/函数,并将单体的RDBMS拆分为许多简单可扩展和高可用性的NoSQL和关系数据存储。

    过去十年,“人与过程”也发生了巨大变化。让我们考虑一下由100位开发人员组成的一个团队。为了协调,管理测试并且每隔几个月向这个“巨型逻辑”提交更新,通常有更多的人运行这个过程,而不是编写代码。通常需要两倍多的项目经理,测试人员,DBA,运维人员等。一成不变的组织架构,一切由各种工作任务单所驱动。管理的层次结构要求每个人写每周报告和参加许多汇报工作状态的会议,研发人员需要抽出时间来编码实际的业务逻辑!

    DevOps实践,微服务架构和云部署三者与持续交付、紧凑的“两个披萨团队”模式紧密合作,大大减少了任务单,会议和管理成本。小团队的开发人员和产品经理在需要时独立地编写,测试和部署自己的微服务。开发人员的比率发生逆转,从原来的50个经理变为100个开发。每个开发者在会议中花更少的时间和等待任务单,这就获得了两倍的时间,而由此带来的`时效`提升可高达百倍。这个变化的最直观效果就是从做项目转向做产品。大量的项目经理被更少的产品经理所取代。在我所见过的某些案例中,150人输出了原来300多人工作成果的两倍。投资一半,但得到双倍回报,`时效`提升一百倍。许多组织一直在进行这种转型,并有类似改进的实例。

    基于Lambda的应用程序由几乎完全是业务逻辑的单个事件驱动功能构成,并且有更少的模版化的内容和平台代码需要管理。这是早期的情况,但这似乎正在推动另一个根本性的变化。开发人员的小团队将在短短几天内从零开始就开始准备应用程序。他们正在使用短小精悍的功能和事件将强大的API驱动的数据存储和服务粘合在一起。已完成的应用程序已经具有高可用性和可扩展性,高利用率,低成本和快速部署。作为一个类比,考虑到一堆模型房子从一块粘土需要多长时间开始,而不是一堆乐高砖。如果有足够的时间,您可以使用这种“粘土”创造任何东西,它具有表现力和创造性,它甚至还可以反其道而行之,创造单体应用(俗称“大泥巴球”)。乐高砖组合在一起,构成了一个功能有限的,块状的模型房屋,在一定的时间内也是很容易扩展和修改的。此外,还有其他的“砖块”有点像乐高砖,但它们并不是主流,任何类型的基于“标准砖”的系统将比“定制粘土”快得多。如果开发人员的生产力能够提高一个数量级,那么我先前提到的100个开发人员的案例中,他们开发的单体应用可以重写,并且在几周之内被10名开发人员组成的团队所取代。如果你怀疑这是否会奏效,大可做一个实验来验证,这个实验的成本还是很低的。事件驱动函数的调用延迟是限制复杂应用程序的关键限制之一,但随着时间的推移,这些延迟正在减少。

    我真正的关注点在于已经存在的单体应用是应该整体搬到云环境中,还是应该重写这个应用这个决定性的ROI阀值。应用从数据中心上云的最佳实践是,将扩展性要求高和经常需要修改的单体应用重写成微服务,本身就很小的应用和很少需要修改的应用采取原封不动的策略。我认为AWS Lambda改变了这个决策方式,它会是新的、试验性质的应用的首选方式。这种方式很值得一试,因为可以做多次的重写。

    我对您的经验非常感兴趣,请让我了解在您的环境中,您是如何看待`时效`的。

    原文链接:Evolution of Business Logic from Monoliths through Microservices, to Functions (翻译:付辉)

    微服务化改造系列之四:授权中心

    emac 发表了文章 • 2 个评论 • 8456 次浏览 • 2016-12-04 16:48 • 来自相关话题

    前情概要: > > - 微服务化改造系列之一:总览 > - 微服务化改造系列之二:服务注册中心 > - 微服务化改造系列之三:配置中心 # 授权中心概述 这篇文章是微服务化 ...查看全部

    前情概要:
    >
    > - 微服务化改造系列之一:总览
    > - 微服务化改造系列之二:服务注册中心
    > - 微服务化改造系列之三:配置中心



    # 授权中心概述
    这篇文章是微服务化改造系列的第四篇,主题是授权中心。有了服务注册中心和配置中心,下一步应该就可以发起服务调用了吧?Wait, 还有一个关键问题要解决。不同于单体应用内部的方法调用,服务调用存在一个服务授权的概念。打个比方,原本一家三兄弟住一屋,每次上山打猎喊一声就行,后来三兄弟分了家,再打猎就要挨家挨户敲门了。这一敲一应就是所谓的服务授权。

    严格来说,服务授权包含鉴权(Authentication)和授权(Authorization)两部分。鉴权解决的是调用方身份识别的问题,即敲门的是谁。授权解决的是调用是否被允许的问题,即让不让进门。两者一先一后,缺一不可。为避免歧义,如不特殊指明,下文所述授权都是宽泛意义上的授权,即包含了鉴权。

    常见的服务授权有三种,简单授权,协议授权和中央授权。

    • 简单授权:服务提供方并不进行真正的授权,而是依赖于外部环境进行自动授权,比如IP地址白名单,内网域名等。这就好比三兄弟互相留了一个后门。
    • 协议授权:服务提供方和服务调用方事先约定一个密钥,服务调用方每次发起服务调用请求时,用约定的密钥对请求内容进行加密生成鉴权头(包含调用方唯一识别ID),服务提供方收到请求后,根据鉴权头找到相应的密钥对请求进行鉴权,鉴权通过后再决定是否授权此次调用。这就好比三兄弟之间约定敲一声是大哥,敲两声是二哥,敲三声是三弟。
    • 中央授权:引入独立的授权中心,服务调用方每次发起服务调用请求时,先从授权中心获取一个授权码,然后附在原始请求上一起发给服务提供方,提供方收到请求后,先通过授权中心将授权码还原成调用方身份信息和相应的权限列表,然后决定是否授权此次调用。这就好比三兄弟每家家门口安装了一个110联网的指纹识别器,通过远程指纹识别敲门人的身份。
    一般来说,简单授权在业务规则简单、安全性要求不高的场景下用的比较多。而协议授权,比较适用于点对点或者C/S架构的服务调用场景,比如Amazon S3 API。对于网状结构的微服务而言,中央授权是三种方式中最适合也是最灵活的选择:[list=1]
  • 简化了服务提供方的实现,让提供方专注于权限设计而非实现。
  • 更重要的是提供了一套独立于服务提供方和服务调用方的授权机制,无需重新发布服务,只要在授权中心修改服务授权规则,就可以影响后续的服务调用。
  • ## OAuth说起具体的授权协议,很多人第一反应就是OAuth。事实上也的确如此,很多互联网公司的开放平台都是基于OAuth协议实现的,比如Google APIs, 微信网页授权接口。一次标准的OAuth授权过程如下:
    oauth2.png
    对应到微服务场景,服务提供方相当于上图中的Resource Server,服务调用方相当于Client,而授权中心相当于Authorization Server和Resource Owner的合体。想了解更多关于OAuth的信息,可移步OAuth2或者OAuth2中文版。## Beared Token在标准的OAuth授权过程中,Resource Server收到Client发来的请求后,需要到Authorization Server验证Access Token,并获取Client的进一步信息。通过OAuth 2.0版本引入中的Beared Token,我们可以省去这一次调用,将Client信息存入Access Token,并在Resource Server端完成Access Token的鉴权。主流的Beared Token有SAMLJWT两种格式,SAML基于XML,而JWT基于JSON。由于大多数微服务都使用JSON作为序列化格式,JWT使用的更为广泛。# 框架选型在选型OAuth框架时,我主要调研了CAS,Apache Oltu,Spring Security OAuthOAuth-Apis,对比如下:
    oauth2-frameworks.png
    不考虑实际业务场景,CAS和Spring Security OAuth相对另外两种框架,无论是集成成本还是可扩展性,都有明显优势。前文提到,由于我们选用了Spring Boot作为统一的微服务实现框架,Spring Security OAuth是更自然的选择,并且维护成本相对低一些(服务端)。# 最终方案最终我们基于Spring Security OAuth框架实现了自己的服务授权中心,鉴权部分做的比较简单,目前只支持私网认证。大致的服务授权流程如下:
    oauth2-interaction.png
    oauth2-sequence.png
    值得一提的是,除了服务调用,我们的服务授权中心还增加了SSO的支持,通过微信企业号实现各个服务后台的单点登录/登出,以后有机会再详细介绍。# 冰山一角至此,这个微服务化改造系列就算告一段落,等以后有了更多的积累,我会继续写下去。微服务是一个很大的话题,自Martin Fowler于2014年3月提出以来,愈演愈热,并跟另一个话题容器化一起开创了一个全新的DevOps时代,引领了国内外大大小小各个互联网公司的技术走向,也影响了我们这一代程序员尤其是后端和运维的思维方式。从这个角度说,我写这个微服务化改造系列文章也是偶然中的必然,希望能给读过这些文章的你带来一些新的启发和思考。如果你对微服务也感兴趣或者有一些心得想跟我交流,欢迎在赞赏榜上留下你的微信号。

    少年读书如隙中窥月,中年读书如庭中望月,老年读书如台上玩月,皆以阅历之浅深为所得之浅深耳。-- 张潮 《幽梦影》

    # 参考

    微服务化改造系列之三:配置中心

    emac 发表了文章 • 0 个评论 • 6277 次浏览 • 2016-11-30 17:22 • 来自相关话题

    前情概要: - 微服务化改造系列之一:总览 > - 微服务化改造系列之二:服务注册中心 # 配置中心概述 这篇文章是微服务化改造系列的第三篇,主题是配置中心。上一篇我们谈到服务注册中 ...查看全部

    前情概要:



    - 微服务化改造系列之一:总览
    > - 微服务化改造系列之二:服务注册中心



    # 配置中心概述
    这篇文章是微服务化改造系列的第三篇,主题是配置中心。上一篇我们谈到服务注册中心,即通过提供某种注册和发现的机制,解决服务互通的问题。那么问题来了,一个服务如何知道服务注册中心的地址呢?这就涉及到服务配置了。我们知道,大至一个PaaS平台,小至一个缓存框架,一般都依赖于特定的配置以正常提供服务,微服务也不例外。
    ## 配置分类

    • 按配置的来源划分,主要有源代码(俗称hard-code),文件,数据库和远程调用。
    • 按配置的适用环境划分,可分为开发环境,测试环境,预发布环境,生产环境等。
    • 按配置的集成阶段划分,可分为编译时,打包时和运行时。编译时,最常见的有两种,一是源代码级的配置,二是把配置文件和源代码一起提交到代码仓库中。打包时,即在应用打包阶段通过某种方式将配置(一般是文件形式)打入最终的应用包中。运行时,是指应用启动前并不知道具体的配置,而是在启动时,先从本地或者远程获取配置,然后再正常启动。
    • 按配置的加载方式划分,可分为单次加载型配置和动态加载型配置。
    ## 演变随着业务复杂度的上升和技术架构的演变,对应用的配置方式也提出了越来越高的要求。一个典型的演变过程往往是这样的,起初所有配置跟源代码一起放在代码仓库中;之后出于安全性的考虑,将配置文件从代码仓库中分离出来,或者放在CI服务器上通过打包脚本打入应用包中,或者直接放到运行应用的服务器的特定目录下,剩下的非文件形式的关键配置则存入数据库中。上述这种方式,在单体应用阶段非常常见,也往往可以运行的很好,但到了微服务阶段,面对爆发式增长的应用数量和服务器数量,就显得无能为力了。这时,就轮到配置中心大显身手了。那什么是配置中心?简单来说,就是一种统一管理各种应用配置的基础服务组件。# 可选框架选型一个合格的配置中心,至少需要满足如下4个核心需求:
    • 非开发环境下应用配置的保密性,避免将关键配置写入源代码
    • 不同部署环境下应用配置的隔离性,比如非生产环境的配置不能用于生产环境
    • 同一部署环境下的服务器应用配置的一致性,即所有服务器使用同一份配置
    • 分布式环境下应用配置的可管理性,即提供远程管理配置的能力
    现在开源社区主流的配置中心框架有Spring Cloud Config和disconf,两者都满足了上述4个核心需求,但又有所区别。## Spring Cloud Config
    spring-cloud-config.png
    Spring Cloud Config可以说是一个为Spring量身定做的轻量级配置中心,巧妙的将应用运行环境映射为profile,应用版本映射为label。在服务端,基于特定的外部系统(Git、文件系统或者Vault)存储和管理应用配置;在客户端,利用强大的Spring配置系统,在运行时加载应用配置。## disconf
    disconf.jpg
    disconf是前百度资深研发工程师廖绮绮的开源作品。在服务端,提供了完善的操作界面管理各种运行环境,应用和配置文件;在客户端,深度集成Spring,通过Spring AOP实现应用配置的自动加载和刷新。# 方案选型不管是Spring Cloud Config还是disconf,默认提供的客户端都深度绑定了Spring框架,这对非Spring应用而言无疑增加了集成成本,即便它们都提供了获取应用配置的API。最终我们还是选用了微服务化改造之前自研的Matrix作为配置中心,一方面,可以保持新老系统使用同一套配置服务,降低维护成本,另一方面,在满足4个核心需求的前提下,Matrix还提供了一些独有的能力。
    • 分离配置文件和配置项。对于配置文件,通过各类配套打包插件(sbt, maven, gradle),在打包时将配置文件打入应用包中,同时最小化对CI的侵入性;对于配置项,提供SDK,帮助应用从服务端获取配置项,同时支持简单的缓存机制。
    • 增加应用版本维度,即对于同一应用,可以在服务端针对不同版本或版本区间维护不同的应用配置。
    • 应用配置的版本化支持,类似于Git,可以将任一应用配置回退到任一历史版本。
    进一步信息可参考我之前写的Matrix设计文档
    matrix.png
    Matrix架构图下一篇我将给大家介绍微服务架构的另一个基础组件——授权中心,敬请期待!#参考

    用微服务创建可扩展API

    hokingyang 发表了文章 • 0 个评论 • 2491 次浏览 • 2016-07-11 13:44 • 来自相关话题

    【编者的话】想尝试用微服务创建一个API吗?微服务很适合用于创建API,开发人员可以集中精力于创建小巧,相互无关的组件,组合成一个特定API调用;可以用不同语言开发不同服务点(endpoint),提供不同服务级别(SLAs),甚至独立扩展微服务,可以参考我的某 ...查看全部
    【编者的话】想尝试用微服务创建一个API吗?微服务很适合用于创建API,开发人员可以集中精力于创建小巧,相互无关的组件,组合成一个特定API调用;可以用不同语言开发不同服务点(endpoint),提供不同服务级别(SLAs),甚至独立扩展微服务,可以参考我的某些微服务讲座。

    讲座视频

    我也讲过在一个Kubernetes集群内部署和运行不同服务是非常容易的,如下代码演示了如何简单发起一个前端和后端服务,他们互相通讯并且独立扩展。这个示例唯一没有展示出来的是这个服务是用不同语言开发的,对终端用户无缝透明地工作。最近,我的同事Sara Robinson和我演示了一个基于NGINX如何创建这种服务,我们开源了代码。耐心读完这篇深入报道(报道很长,可以直接跳到自己关心的部分)。这个演示依赖于Kubernetes和Google Container Engine运行这个集群。我们开始之前,确保已经创建了一个Google Cloud project,如果需要从Kubernetes开始,可以查看这篇博客
    #为什么需要Kubernetes
    Sara和我用不同语言进行编程,每种语言都有最佳适用范围。例如,Google内部使用C++、Java、Python和Go组合的开发环境。在有Containers和Kubernetes之前,这意味着为不同开发栈设置四种不同服务器,也就是一种Ops很高的架构。如果想整合服务器,就需要在同一台服务器上安装不同开发栈,但是更新一种栈则需要影响其他栈,扩展系统编程很大挑战,一些看起来简单的操作变的比较复杂。基于这种场景,很多人不得不只选择一种开发栈。有了容器,这种两难境地彻底改变。容器可以在机器和代码之间进行了抽象,开发者在任何机器上不做明显配置就可以运行任何开发栈。Kubernetes自动编排这些作业,开发者可以部署管理所有这些容器而不需要ssh登进这些机器。
    #​创建一个Kubernetes集群
    先创建一个Kubernetes集群运行应用。确保已经安装了Google Cloud SDK,或者使用Cloud Shell(如果对Google Cloud还比较陌生,可以尝试试用版:https://cloud.google.com/free-trial/)。

    我会使用标准三节点集群。
    $ gcloud container clusters create mycluster

    登陆
    $ gcloud container clusters get-credentials mycluster

    集群就简单生成了。
    #微服务代码样例
    我们要部署的代码非常简单。用每种语言,我们都实现了某种字符操作,我们有四种不同服务:

    Ruby - Arrayify
    Hello World → [H,e,l,l,o, ,W,o,r,l,d]

    Python - Reverse
    Hello World → dlroW olleH

    Node.js - To Lower
    Hello World → hello world

    Go - To Upper
    Hello World → HELLO WORLD

    是不是很简单?
    #容器化代码
    下一步是把如上代码放到容器中。容器会帮助将所有依赖包打包为一起并且以可发布方式发行。我们会使用Docker来实现。确保安装了Docker或者使用Cloud Shell。Docker使得创建容器非常简单,并且确保环境一致。如果从未使用过Docker,可以先阅读以下讨论如何在Docker中运行MEAN栈)的博客

    首先是创建叫做Dockerfile的配置文件,如下是我们使用的Dockerfiles。​

    Ruby:
    FROM ruby:2.3.0-onbuild
    CMD ["ruby", "./arrayify.rb"]

    Python:
    FROM python:2.7.11-onbuild
    CMD [ "python", "./app.py" ]

    Node.js:
    FROM node:5.7.0-onbuild

    Go:
    FROM golang:1.6-onbuild

    这些就是所需的所有配置文件了。你的依赖包可能会复杂些,其实Dockerfile的基本概念就是写下需要在Linux中运行的命令,指出哪些文件需要挂载或者copy到容器中。可以从这儿学习更多。

    创建应用,需要在包含Dockerfile的目录下运行docker build命令。开发者可以给这些影响打上标签(tag),以便安全地使用Google Container Registry保存在云端。
    $ docker build -t 
    gcr.io//: .

    用容器名(例如reverser)以及版本(例如0.1)替换Google Cloud Project ID,从西面开始,我会将gcr.io//: 用 开代替。为以上四个微服务都执行以上命令,就创建容器完毕。可以用如下命令测试:
    $ docker run -ti -p 8080:80 

    如果使用Linux,可以访问localhost:8080来使用微服务。如果不使用linux,可以使用docker-machine运行本机Docker引擎(很快Mac和Windows会自带Docker功能)。通过docker-machine,能得到实例名:
    $ docker-machine list

    并且得到机器IP地址:
    $ docker-machine ip 

    此时应当可以看到如下显示:
    图一.png

    #​使用Google Container Engine部署容器
    接下来需要部署他们。首先将容器从本机拷贝到云端。
    $ gcloud docker push 

    这条命令会将本地映像推送到集群访问的私有代码池(repository),记住要推送四次,然后就可以从Container Registry页面看到并且管理所有推送的容器了。下面需要部署容器到集群,最容易的方式是运行一下命令:
    $ kubectl run \

    --image= \
    --port=80

    这条命令将你的容器以Kubernetes部署方式部署为一个实例,如果发生任何事情都将会重启或者重新调度容器。一篇之前的博客讨论过复制控制(部署的老版本名词)以及为什么很重要。

    你可以在这停止了,但是我想还是继续为我的部署生成几个配置文件因为后面会比较容易记住我做了什么修改。

    如下是我用于arraify微服务的YAML文件,给部署一个名字叫arrayify,规定了复制次数(3),一起容器名和开放端口。
    apiVersion: extensions/v1beta1

    kind: Deployment

    metadata:

    name: arrayify

    spec:

    replicas: 3

    template:

    metadata:

    labels:

    name: arrayify-pods

    spec:

    containers:

    - image:

    name: arrayify-container

    imagePullPolicy: Always

    ports:

    - containerPort: 80

    name: http-server

    保存文件叫做“deployment.yaml”,然后部署它。
    $ kubectl apply -f deployment.yaml

    为四个微服务都重复以上步骤,每个微服务都生成yaml文件,改变容器映像和标签(一般就是将arrayify替换为其它对应名字)。此刻,可以看到集群内所有部署和容器。
    $ kubectl get deployments

    图二.png

    $ kubectl get pods

    图三.png

    #发布微服务
    如果你读了我之前一篇博客,那么就会知道下一步就是为每个微服务创建一个Kubernetes服务,这会创建一个稳定的服务点和每个微服务的负载均衡。然而,并不会希望为每个微服务都对外界开放独自的服务。每个微服务都是这个API的一部分,如果你分别开放每个微服务,每个微服务将会有各自的IP地址,这绝对不是我们想看到的。相反,可以使用NGINX来代理微服务实现唯一服务点。我会使用NGINX+,是一个付费软件,但是开源版工作也很不错。

    NGINX可以做很多需要创建可扩展API的事情。可以设置为API网关,可以很好控制API粒度,包括rate limiting、security、access control和其它。我会使用很多基础NGI配置,这样大家可以直接使用它们。
    #创建内部服务
    第一步是可以用NGINX代理。可以参考如下arrayify微服务代码:
    apiVersion: v1


    kind: Service


    metadata:


    name: arrayify


    spec:


    ports:


    - port: 80


    targetPort: 80


    protocol: TCP


    selector:

    name: arrayify-pods

    服务目标是所有带“arrayify-pods”标签pod上的端口80,保存此文件为"service.yaml",然后用如下命令部署:
     $ kubectl create -f service.yaml 

    图四.png

    为所有四个微服务重复以上过程,创建文件,改变标签(一般就是替代arrayify)。此时,可以看见集群内运行的所有服务:
    $ kubectl get svc

    #配置NGINX
    下一步是配置NGINX代理微服务。可以看看如下目录NGINX folder in GitHub。我们会详细讲解如何配置nginx.conf。

    首先看第一行:
    resolver 10.11.240.10 valid=5s;

    这一行定义NGINX用来搜索微服务的DNS服务,对集群来说可能并不是必须的,但是包含这一行却是很安全的。你可能很奇怪IP地址从哪里来,其实是Kubernetes内置的DNS服务,如果你自己有DNS服务,也可以用如下命令获得IP地址:
    $ kubectl get svc kube-dns --namespace=kube-system 

    图五.png

    下一步,需要设置upstreams(实现同一功能的服务器集合,例如一个微服务),因为可以使用DNS,因此很容易搭建,参见如下arrayify微服务的upstream:
    upstream arrayify-backend {

    zone arrayify-backend 64k;

    server arrayify.default.svc.cluster.local resolve;

    }

    Arrayify.default.svc.cluster.local是Kubernetes服务的全名;为四个微服务重复以上过程(一般就是讲arrayify替换为其它名字)。注意server字段,这里会告诉NGINX哪个路径可以重新映射到哪个微服务:
    ​server {

    listen 80;

    status_zone backend-servers;

    location /arrayify/ {

    proxy_pass http://arrayify-backend/;

    }

    }

    这里,告诉NGINX任何一/arrayify/开始的服务请求应该被转发到arrayify微服务。为其它微服务创建一个字段(一般就是替换arrayify为其它微服务名字),可以参考完整nginx.conf。然后跟推送其它微服务一样,推送客制化NGINX映像。也可以从GitHub查看所有内容。
    #公开NGINX
    最后一步就是公开NGINX服务,跟为微服务创建内部服务流程一样,但是需要指出“type:LoadBalancer",会给此服务一个外部IP地址,可以从NGINX目录下svc.yaml文件中看到。

    一旦部署服务,可以用如下命令看到外部IP地址:
    图六.png

    #测试
    下面使用外部IP,测试这个API看看输出情况,非常酷!
    图七.png

    图八.png

    图九.png

    图十.png

    #回顾
    我们创建了如下应用:
    图十一.png

    使用NGINX公开了单一API服务点和代理负载到四个不同微服务,每个都有三个实例。
    #额外阅读
    我们所有的模组都已经运行成功,我们接下来看看如何监控、扩展和更新微服务。
    ##扩展
    用Kubernetes扩展微服务并不容易。例如要扩展Arrayify容器的数量,可以使用如下命令扩展到五个容器:
    $ kubectl scale deployment arrayify --replicas=5

    缩减也是一样的过程。如果想减少到一个容器,运行如下命令:
    $ kubectl scale deployment arrayify --replicas=1

    也可以实现自动扩展,根据CPU负载动态调整集群内容器数量。使用如下命令:
    $ kubectl autoscale deployment arrayify --min=1 --max=5 --cpu-percent=80

    如你所愿,这条命令确保至少一个容器在运行,如果需要最多可以扩展到五个,并且会确保每个容器至少CPU占用80%以上。也可以用此命令扩展NGINX!需要注意的是虚机(节点)自动扩展现在在Kubernetes内并不支持,然而,可以使用Google Cloud Managed Instance Group来实现此需求。
    #更新
    如果能够动态更新微服务而不影响业务就非常理想。应用不同部分依赖不同微服务,因此如果一个微服务下线了,会对其它部分造成负面影响。幸运的是,Kubernetes使得零宕机部署变的更加易于管理。更新一个微服务,首先创建一个运行新代码的容器,打上新标签。例如,如果想更新arrayify微服务,重新运行docker build命令,但是需要更改版本号。
    $ docker build -t gcr.io//arrayify:0.2 .

    然后推送:
    $ gcloud docker push gcr.io//arrayify:0.2

    打开arrayify微服务的deployment.yaml 文件,改变容器版本(从0.1到0.2),然后部署新版本。
    $ kubectl apply -f deployment.yaml

    Kubernetes会自动扩展部署新版本,缩减下电旧版本。如果新版本有bug,可以用单一命令回滚:
    $ kubectl rollout undo deployment/arrayify

    (替换arrayify为其它需要更新或者回滚微服务名字)如果想了解详细信息,可以读其它文档
    #监控
    使用NGINX+,有一个非常酷的面板,可以了解所有微服务状态。
    图十二.png

    可以从中看出流量、错误以及每个不同微服务的健康状态。可以参看详细的nginx.conf

    最后,我强烈推荐使用Google Stackdriver来为微服务配置自动告警和触发。Stackdriver是一个监控应用的一站式商店;默认的,每个容器的stdout和stderr都被发往stackdriver日志。stackdriver监控可以查看Kubernetes集群和监控各自pods,stackdriver监控可以帮助模拟代码debug而不需要真的命中bug。

    感谢读完了这么长的博客,如果有什么需要分享的,可以跟我在 Twitter @SandeepDinesh互动。

    原文链接:Creating a scalable API with microservices(翻译:杨峰)