2020 年,Bilgin Ibryam 提出了 Multi-Runtime(多运行时)的理念,对基于 Sidecar 模式的各种产品形态进行了实践总结和理论升华。那到底什么是多运行时呢?首先还是得从分布式应用的四大类基本需求讲起。简单来讲任何分布式应用都存在的四大类基本需求:
1、生命周期:包括部署,健康检查,水平扩展,配置管理等,目前这些需求的最佳实践,都陆续在 kubernetes 上有了落地。
2、网络:网络方面的需求 是 service Mesh 的主战场,比如 istio 可以满足这里绝大部分需求,除了 pub/sub。
3、状态:包括数据的读写,状态其实是非常难以管理的,涉及幂等,缓存,数据流等等。
4、绑定:主要是指和系统外部资源的交互。
在传统软件时代,是耦合在应用代码里的,但现如今,有越来越多的分布式能力从应用中剥离,而剥离的方式也在逐渐变化,从最早期,这些能力从业务代码剥离到依赖库中,然后有一些特性剥离到平台层(kubernetes)。而如今会有更多的非业务能力,剥离到 sidecar 中。作者预测:理论上每个微服务可以有多个 runtime: 一个业务运行时,和多个分布式能力运行时,但最理想的情况是,或者最可能出现的情况是:在业务之外的运行时合并为一个,通过高度模块化、标准化和可配置的方式,给业务提供所有分布式能力。而dapr则在很早之前就完成了对istio的集成,理论上我们可以通过运行两个sidecar来提供分布式能力,istio关注网络侧,包括不限于服务注册发现、A/B测、金丝雀部署、流量镜像,监控链路等等。当然dapr这部分有一定重叠,但是没有istio做的那么细致,这两者可以互补。而dapr则可以提供istio并不具备的网络功能比如订阅/发布、状态管理包括状态幂等,一致性,actor等等,也包括绑定,通过绑定和外部系统交互这部分。
目录:
一、通过Dapr实现一个简单的基于.net的微服务电商系统
二、通过Dapr实现一个简单的基于.net的微服务电商系统(二)——通讯框架讲解
三、通过Dapr实现一个简单的基于.net的微服务电商系统(三)——一步一步教你如何撸Dapr
四、通过Dapr实现一个简单的基于.net的微服务电商系统(四)——一步一步教你如何撸Dapr之订阅发布
通过Dapr实现一个简单的基于.net的微服务电商系统(五)——一步一步教你如何撸Dapr之状态管理
通过Dapr实现一个简单的基于.net的微服务电商系统(六)——一步一步教你如何撸Dapr之Actor服务
通过Dapr实现一个简单的基于.net的微服务电商系统(七)——一步一步教你如何撸Dapr之服务限流
通过Dapr实现一个简单的基于.net的微服务电商系统(八)——一步一步教你如何撸Dapr之链路追踪
通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权
通过Dapr实现一个简单的基于.net的微服务电商系统(九)——一步一步教你如何撸Dapr之OAuth2授权-百度版
通过Dapr实现一个简单的基于.net的微服务电商系统(十)——一步一步教你如何撸Dapr之绑定
通过Dapr实现一个简单的基于.net的微服务电商系统(十三)——istio+dapr构建多运行时服务网格之生产环境部署
附录:(如果你觉得对你有用,请给个star)
一、电商Demo地址:https://github.com/sd797994/Oxygen-Dapr.EshopSample
二、通讯框架地址:https://github.com/sd797994/Oxygen-Dapr
istio是什么呢?简单来讲istio是一个service mesh,和dapr的结构类似,都是通过在应用之上插入sidecar来提供分布式能力,同时通过控制平面来对这些sidecar进行具体的调度和管控,只不过istio更倾向于提供网络能力,其官网的一句话描述可以概括:“通过领先的服务网格简化可观测性,流量管理,安全及策略。”其功能包括以下几点:
1、使用 TLS 加密、强身份认证和授权的集群内服务到服务的安全通信
2、自动负载均衡的 HTTP, gRPC, WebSocket,和 TCP 流量
3、通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制
4、一个可插入的策略层和配置 API,支持访问控制、速率限制和配额
5、对集群内的所有流量(包括集群入口和出口)进行自动度量、日志和跟踪
说了那么多,我们还是聊聊如何通过dapr+istio对我们的电商demo进行多运行时集成吧。首先是安装,安装可以参考istio官方中文文档,默认安装profile=demo会帮我们安装istiod+ingressgateway+egressgateway,istiod就是我们的控制平面核心,不同于dapr将控制平面分散在多个容器的做法,istio经历过1.5的版本迭代后将所有的功能又合并到了一个容器中。而ingressgateway则是用于替代ingress-controller的,而egress是出口网关,由于istio默认对入口和出口流量都有管控,这里我们不需要限制出口流量,所以设置为ALLOW_ANY。同时这是不需要每次都拉取sidecar镜像。
istioctl install --set profile=demo --set meshConfig.outboundTrafficPolicy.mode=ALLOW_ANY --set values.global.imagePullPolicy=IfNotPresent
同样的我们需要将ingressgateway作为nodeport指向我们的30882,记住这里需要先把之前安装的ingress-controller的svc的30882修改为其他端口,否则会冲突。
kubectl edit svc istio-ingressgateway -n istio-system
-> 文件内容改动如下:...- name: http2 #只需要修改http2即可nodePort: 30882port: 80protocol: TCP...type: NodePort #改成NodePort,下面的部分删除
status:loadBalancer:ingress:- hostname: localhost
接着我们看看kubectl get po -n istio-system 确保三个pod都已经running即可,接着我们安装一些dashboard需要等下通过这些来观察istio,进入安装的istio根目录,找到\samples\addons,执行kubectl apply -f . 即可将Kiali 和其他插件安装完毕,其中kiali是istio的官方仪表板,安装完成后可以通过istioctl dashboard kiali 将kiali启动起来,当然你也可以通过修改kubectl edit svc kiali -n istio-system 设置nodeport来永久暴露kiali面板,这里不赘述。可以看到我们的dapreshop里所有的pod目前状态都是missing sidecar,说明sidecar尚未注入。
接着我们来注入istio的sidecar到我们的电商demo。很简单,只需要执行 kubectl label ns dapreshop istio-injection=enabled 在我们的dapreshop这个namespace打上自动注入的标签,接着我们kubectl delete po --all -n dapreshop重启所有pod即可将该空间下的pod都自动注入sidecar。如果你不需要某些pod注入sidecar,则禁用它即可:
template:
metadata:labels: app: accountserviceversion: v1annotations:sidecar.istio.io/inject: "false"
如果一切顺利,等待一段时间后,我们可以看到每一个pod都会被正确的注入istio的sidcar,而istio sidecar工作原理和dapr不一样,它是通过修改ip规则转发流量的方式强制拦截,流量模型如下:
接着我们需要编写入口流量,让我们的流量通过istio的网关接管,yaml如下:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:name: dapreshop-gatewaynamespace: dapreshop
spec:selector:istio: ingressgatewayservers:- port:number: 80name: httpprotocol: HTTPhosts:- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: apigatewaynamespace: dapreshop
spec:hosts:- "api.dapreshop.com"gateways:- dapreshop-gatewayhttp:- route:- destination:port:number: 80host: apigateway
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: mobiledapreshopnamespace: dapreshop
spec:hosts:- "m.dapreshop.com"gateways:- dapreshop-gatewayhttp:- match:- uri:prefix: /route:- destination:port:number: 80host: mobilefrontend
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: admindapreshopnamespace: dapreshop
spec:hosts:- "admin.dapreshop.com"gateways:- dapreshop-gatewayhttp:- match:- uri:prefix: /route:- destination:port:number: 80host: adminfrontend
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:name: oauthdapreshopnamespace: dapreshop
spec:hosts:- "oauth.dapreshop.com"gateways:- dapreshop-gatewayhttp:- match:- uri:prefix: /route:- destination:port:number: 80host: oauthservice-dapr
apply以后,我们可以通过kugectl get gw,vs -n dapreshop。可以看到相关资源已经注入成功了,接着就可以访问我们的http://admin.dapreshop.com:30882/,可以看到页面被正确打开了,说明流量已经通过istio正确转发了。接着我们操作一下平台,然后登录kiali即可看到正确的链路调用情况了
今天的分享就到这里,这只是一个简单的demo级别的演示,其他的还需要大家多自行摸索,照例欢迎fork+star~
istio vs dapr 比较点
根据 CNCF[2] 的 最新年度调查 [3],很明显,很多人对在他们的项目中使用服务网格表现出了极大的兴趣,并且许多人已经在他们的生产中使用它们。将近 69% 的人正在评估 Istio,64% 的人正在研究 Linkerd。Linkerd 是市场上第一个服务网格,但是 Istio 的服务网格更受欢迎。这两个项目都是最前沿的,而且竞争非常激烈,因此选择哪一个是一个艰难的选择。在此博客文章中,我们将了解有关 Istio 和 Linkerd 的架构,其及组件的更多信息,并比较其特性以帮你做出明智的决定。
服务网格简介
在过去的几年中,微服务架构已经成为设计软件应用程序的流行风格。在这种架构中,我们将应用程序分解为可独立部署的服务。这些服务通常是轻量级的、多语言的,并且通常由各种职能团队进行管理。直到这些服务的数量变得庞大且难以管理之前,这种架构风格效果很好。突然之间,它们不再简单了。这在管理各个方面(例如安全性、网络流量控制和可观察性)带来了挑战。服务网格可以帮助应对这些挑战。
术语服务网格用于描述组成此类应用程序的微服务网络及其之间的交互。随着服务数量和复杂性的增加,其扩展和管理变得越来越困难。服务通常提供服务发现、负载均衡、故障恢复、指标和监控。服务网格通常还具有更复杂的操作要求,例如 A/B 测试、金丝雀发布、限流、访问控制和端到端身份验证。服务网格为负载均衡、服务到服务的身份验证、监控等提供了一种创建服务网络的简单方法,同时对服务代码的更改很少或没有更改。
让我们看一下 Istio 和 Linkerd 的架构。请注意,这两个项目都在快速演进,并且本文基于 Istio 1.6 版本和 Linkerd 2.7 版本。
Istio
Istio 是一个提供了作为服务网格的整套解决方案的开源平台,提供了安全、连接和监控微服务的统一方法。它得到了 IBM、Google 和 Lyft 等行业领军者的支持。Istio 是最流行、最完善的解决方案之一,其高级特性适用于各种规模的企业。它是 Kubernetes 的一等公民,被设计成模块化、平台无关的系统。有关 Istio 的快速演示,请参考我们以前的文章 [4]。
架构
Istio 架构
Istio 架构来源:istio.io[5]
组件
Envoy[6] 是由 Lyft 用 C++ 编写的高性能代理,它可以协调服务网格中所有服务的所有入站和出站流量。它作为 Sidecar 代理与服务一起部署。
Envoy 提供以下功能:
• 动态服务发现• 负载均衡•TLS 终止•HTTP/2 和 gRPC 代理• 断路器• 健康检查• 按百分比分配流量实现的分阶段发布• 故障注入• 丰富的指标
在较新的 Istio 版本中,Sidecar 代理对 Mixer 的工作承担了额外的责任。在早期版本的 Istio(<1.6)中,使用 Mixer 从网格收集遥测信息。
Pilot 为 Sidecar 代理提供服务发现、流量管理功能和弹性。它将控制流量行为的高级路由规则转换为 Envoy 的特定配置。
Citadel 通过内置的身份和凭证管理实现了强大的服务到服务和最终用户身份验证。它可以在网格中启用授权和零信任安全性。
Galley 是 Istio 配置验证、提取、处理和分发组件。
核心功能
• 流量管理 — 智能流量路由规则、流量控制和服务级别属性(如断路器、超时和重试)的管理。它使我们能够轻松设置 A/B 测试、金丝雀发布和并按比例分配流量的分阶段发布。• 安全性 — 在服务之间提供安全的通信通道,并管理大规模身份验证、授权和加密。• 可观察性 — 强大的链路跟踪、监控和日志功能提供了深度洞察(deep insights)和可见性。它有助于有效地检测和解决问题。
Istio 还具有一个附加组件基础结构服务,该服务支持对微服务的监控。Istio 与 Prometheus、Grafana、Jaeger 和服务网格仪表盘 Kiali 等应用程序集成。
Linkerd
Linkerd 是 Buoyant 为 Kubernetes 设计的开源超轻量级的服务网格。用 Rust 完全重写以使其超轻量级和高性能,它提供运行时调试、可观察性、可靠性和安全性,而无需在分布式应用中更改代码。
架构
Linkerd 具有三个组件 — UI、数据平面和控制平面。它通过在每个服务实例旁边安装轻量级透明代理来工作。
控制平面
Linkerd 的控制平面是一组提供了服务网格的核心功能的服务。它聚合了遥测数据、提供面向用户的 API,并为数据平面代理提供控制数据。以下是控制平面的组件:
• 控制器 — 它包含一个公共 API 容器,该容器为 CLI 和仪表盘提供 API。• 目标 — 数据平面中的每个代理都将访问此组件以查找将请求发送到的位置。它有用于每个路由指标、重试和超时的服务描述信息。• 身份 — 它提供了一个证书颁发机构,该证书颁发机构接受来自代理的 CSR 并返回以正确身份签发的证书。它提供了 mTLS 功能。• 代理注入器 — 它是一个准入控制器,用于查找注解(linkerd.io/inject: enabled
)并更改 pod 规范以添加 initContainer
和包含代理本身的 sidecar。• 服务配置文件验证器 — 这也是一个准入控制器,用于在保存新服务描述 [7] 之前对其进行验证。•Tap — 它从 CLI 或仪表盘接收实时监控请求和响应的指令,以在应用程序中提供可观察性。•Web — 提供 Web 仪表盘。•Grafana — Linkerd 通过 Grafana 提供开箱即用的仪表盘。•Prometheus — 通过 /metrics
在端口 4191 上代理的断点来收集和存储所有 Linkerd 指标。
数据平面
Linkerd 数据平面由轻量级代理组成,这些轻量级代理作为边车容器与服务容器的每个实例一起部署。在具有特定注解的 Pod 的初始化阶段,将代理注入(请参见上面的代理注入器)。自从 2.x 由 Rust 中完全重写以来,该代理一直非常轻量级和高性能。这些代理拦截与每个 Pod 之间的通信,以提供检测和加密(TLS),而无需更改应用程序代码。
代理功能:
•HTTP、HTTP/2 和任意 TCP 协议的透明、零配置代理。• 自动为 HTTP 和 TCP 流量导出 Prometheus 指标。• 透明的零配置 WebSocket 代理。• 自动的、可感知延迟的 7 层负载均衡。• 非 HTTP 流量的自动的 4 层负载均衡。• 按需诊断 tap API。
比较
结论
服务网格正成为云原生解决方案和微服务架构中必不可少的组成部分。它完成了所有繁重的工作,例如流量管理、弹性和可观察性,让开发人员专注于业务逻辑。Istio 和 Linkerd 都已经成熟,并已被多家企业用于生产。对需求的计划和分析对于选择要使用哪个服务网格至关重要。请在分析阶段投入足够的时间,因为在游戏的后期从一个迁移到另一个很复杂。
选择与服务网格一样复杂和关键的技术时,不仅要考虑技术,还要考虑使用技术的背景。缺少背景,很难说 A 是否比 B 好,因为答案确实是 “取决于”。我喜欢 Linkerd 的简单,包括入门和以后管理服务网格。此外,多年来,Linkerd 与来自企业公司的用户一起得到了加强。
一个中可能有一些功能看起来不错,但请确保检查另一个是否计划在不久的将来发布该功能,并基于不仅是理论上的评估,而且还要在概念验证沙箱中对它们进行尝试,做出明智的决定。这种概念验证应集中在易用性、功能匹配以及更重要的是技术的操作方面。引入技术相对容易,最困难的部分是在其生命周期中运行和管理它。