Istio 功能与作用
Istio服务管控包括下列的典型应用场景:
分布式调用追踪在微服务架构中,业务的调用链非常复杂,一个来自用户的请求可能涉及到几十个服务的协同处理。因此需要一个跟踪系统来记录和分析同一次请求在整个调用链上的相关事件,从而帮助研发和运维人员分析系统瓶颈,快速定位异常和优化调用链路。Istio通过在Envoy代理上收集调用相关数据,实现了对应用无侵入的分布式调用跟踪分析。
Envoy收集一个端到端调用中的各个分段的数据,并将这些调用追踪信息发送给Mixer,Mixer Adapter将追踪信息发送给相应的服务后端进行处理。整个调用追踪信息的生成流程不需要应用程序介入,因此不需要将分布式跟踪相关代码注入到应用程序中。注意:应用仍需要在进行出口调用时将收到的入口请求中tracing相关的header转发出去,传递给调用链中下一个边车进行处理。
度量收集
Istio 实现度量收集的原理如下图所示:
Envoy收集指标相关的原始数据,如请求的服务、HTTP状态码、调用时延等,这些收集到的指标数据被送到Mixer,通过Mixer Adapters将指标信息转换后发送到后端的监控系统中。由于Mixer使用了插件机制,后端监控系统可以根据需要在运行期进行动态切换。
灰度发布当应用上线以后,运维面临的一大挑战是如何能够在不影响已上线业务的情况下进行升级。
无论进行了多么完善的测试,都无法保证线下测试时发现所有潜在故障。在无法百分百避免版本升级故障的情况下,需要通过一种方式进行可控的版本发布,把故障影响控制在可以接受的范围内,并可以快速回退。可以通过灰度发布(又名金丝雀发布)来实现业务从老版本到新版本的平滑过渡,并避免升级过程中出现的问题对用户造成的影响。Istio通过高度的抽象和良好的设计采用一致的方式实现了灰度发布。在发布新版本后,运维人员可以通过定制路由规则将特定的流量(如具有指定特征的测试用户)导入新版本服务中以进行测试。通过渐进受控地向新版本导入生产流量,可以最小化升级中出现的故障对用户的影响。采用Istio进行灰度发布的流程如下图所示:首先,通过部署新版本的服务,并将通过路由规则将金丝雀用户的流量导入到新版本服务中。
测试稳定后,使用路由规则将生产流量逐渐导入到新版本系统中,如按5%、10%、50%、80%逐渐导入。
如果新版本工作正常,则最后将所有流量导入到新版本服务中,并将老版本服务下线;如中间出现问题,则可以将流量重新导回老版本,在新版本中修复故障后采用该流程重新发布。
断路器在微服务架构中,存在着许许多多的服务单元,若一个服务出现故障,就会因依赖关系形成故障蔓延,最终导致整个系统的瘫痪,这样的架构相较传统架构就更加的不稳定。为了解决这样的问题,因此产生了断路器模式。断路器模式指,在某个服务发生故障时,断路器的故障监控向调用放返回一个及时的错误响应,而不是长时间的等待。这样就不会使得调用线程因调用故障被长时间占用,从而避免了故障在整个系统中的蔓延。Istio实现断路器的原理如下图所示:
管理员通过destination policy设置断路触发条件,断路时间等参数。例如设置服务B发生10次5XX错误后断路15分钟。则当服务B的某一实例满足断路条件后,就会被从LB池中移除15分钟。在这段时间内,Envoy将不再把客户端的请求转发到该服务实例。Istio的断路器还支持配置最大链接数,最大待处理请求数,最大请求数,每链接最大请求数,重试次数等参数。当达到设置的最大请求数后,新发起的请求会被Envoy直接拒绝。
故障注入对于一个大型微服务应用而言,系统的健壮性非常重要。在微服务系统中存在大量的服务实例,当部分服务实例出现问题时,微服务应用需要具有较高的容错性,通过重试、断路、自愈等手段保证系统能够继续对外正常提供服务。因此在应用发布到生产系统强需要对系统进行充分的健壮性测试。对微服务应用进行健壮性测试的一个最大的困难是如何对系统故障进行模拟。在一个部署了成百上千微服务的测试环境中,如果想通过对应用,主机或者交换机进行设置来模拟微服务之间的通信故障是非常困难的。Istio通过服务网格承载了微服务之间的通信流量,因此可以在网格中通过规则进行故障注入,模拟部分微服务出现故障的情况,对整个应用的健壮性进行测试。故障注入的原理如下图所示:
测试人员通过Pilot向Envoy注入了一个规则,为发向服务MS-B的请求加入了指定时间的延迟。当客户端请求发向MSB-B时,Envoy会根据该规则为该请求加入时延,引起客户的请求超时。通过设置规则注入故障的方式,测试人员可以很方便地模拟微服务之间的各种通信故障,对微服务应用的健壮性进行较为完整的模拟测试。总结服务网格为微服务提供了一个对应用程序透明的安全、可靠的通信基础设施层。采用服务网格后,微服务应用开发人员可以专注于解决业务领域问题,将一些通用问题交给服务网格处理。采用服务网格后,避免了代码库带来的依赖,可以充分发挥微服务的异构优势,开发团队可以根据业务需求和开发人员能力自由选择技术栈。Istio具有良好的架构设计,提供了强大的二次开发扩展性和用户定制能力。虽然Istio目前还处于beta阶段,但已经获得众多知名公司和产品的支持,是一个非常具有前景的开源服务网格开源项目。
Istio解决问题
故障排查
1.请求在哪失败的?A有调用B吗
2.为什么用户请求/页面hung住了
3.为什么系统这么慢?哪个组件最慢?
应用容错性
客户端没有设置timeout导致应用卡住
没有重试机制,某个服务偶尔出现的异常导致用户页面错误
某些节点异常(load高),导致应用响应变长
应用升级发布
新版本一次性升级,一旦出错影响范围很大
无法进行A/B测试,根据用户属性访问不通版本
服务版本的依赖关系处理不当导致的服务不可用
系统安全
服务都是http的而非https
没有流量限制,任何人都可以对服务发起攻击
以下是Istio的核心功能概述:
• HTTP、gRPC、WebSocket 和 TCP 流量的自动负载均衡。
• 通过丰富的路由规则、重试、故障转移和故障注入,可以对流量行为进行细粒度控制。
• 可插入的策略层和配置 API,支持访问控制、速率限制和配额。
• 对出入集群入口和出口中所有流量的自动度量指标、日志记录和追踪。
• 通过强大的基于身份的验证和授权,在集群中实现安全的服务间通信。
2.1 Proxy代理
Istio的核心原理,是网络代理,拦截下所有想拦截的流量,然后想干啥就干啥吧。
Envoy之所以有能力拦截下所有的流量,是因为它被设计为部署在每一个需要管理的Pod里,作为一个独立容器存在,支持通过配置iptables或cni网桥两种方式来拦截流量(这里也不展开说了,还不明白的同学可以翻看我之前发的k8s底层网络的说明,看看Flannel的实现原理),请看上图,Business-manager容器的请求发出时,会经过本Pod的Enovy代理,Enovy完成规则校验、数据采集、日志等操作后,再转发出去;值得注意的是,请求方Enovy转发出去的流量会发送给接收方的Enovy,之后才有可能到达真正的接收方data-product容器。当然这些操作是Istio的活,我们要做的仅仅是通过配置的形式告诉Istio我们要对哪些流量做什么动作。
通过对拦截下来的流量的解析和修改(是的,理论上什么都能干,包括修改甚至丢弃流量),Envoy包括但不限于以下功能:
• 动态服务发现
• 负载均衡
• TLS 终止
• HTTP/2 & gRPC 代理
• 熔断器
• 健康检查、基于百分比流量拆分的灰度发布
• 故障注入
• 丰富的度量指标
2.2 Mixer混合器
顾名思义,Mixer混合了各种策略以及后端数据采集或遥测系统的适配器,从而实现了前端Proxy与后端系统的隔离与汇合。Mixer是一个灵活的插件模型(有没有发现无论是k8s还是Istio,实现上都很青睐于插件模型,这是一个很灵活的实现方式),它一端连着Envoy,同时我们可以将日志、监控、遥测等各种系统“插入”到Mixer的另一端中,从而得到我们想要的数据或结果。
Mixer被设计为一个独立运行的模块,它可以“插入”logging日志、quota指标、auth安全认证、Tele遥测等很多模块。每插入一个模块都会在前端生成一个规则过滤器。前端的Enovy在每次流量到来时,都会请求Mixer,匹配每一个过滤器。
这就涉及到性能问题了,所以Istio在这个拓扑下设计了一个二级缓存系统。Envoy端在每个Pod里有一个一级缓存,当然这个缓存不能太大;Mixer端会有一个二级缓存,由于Mixer是独立运行的,所以这个缓存可以设计的比较大。这样Envoy可以预先缓存一部分规则,只有当规则缺失时才需要向Mixer请求,这就减少了每次流量到来的网络请求次数;另一方面,日志等数据上送,也是异步执行的,先经过一级缓存、二级缓存再到达后端存储或处理系统。
2.3 Pilot引导
简单来说,Pilot是为我们提供配置智能路由(如A/B测试、金丝雀发布等)、弹性(超时、重发、熔断等)等功能的管理系统,它提供了一系列rules api,允许运维人员指定一系列高级的流量管理规则。Pilot负责将我们的配置转换并写入到每个sidecar(Envoy)。
2.4 Citadel堡垒
这个名字也很有意思,它管理着集群的密钥和证书,是集群的安全部门。典型的如果我们的服务是跨网络通讯(Istio允许我们建立一个安全的集群的集群网络),开发人员想省事懒得对通讯数据进行加解密和身份认证,这事就可以交给Citadel来处理了。更详细的说,Istio各个模块在安全性上分别扮演以下角色:
• Citadel,用于密钥和证书管理
• Sidecar和周边代理,实现客户端和服务器之间的安全通信
• Pilot,将授权策略和安全命名信息分发给代理
• Mixer,管理授权和审计
这一块应该暂时用不上,也不展开说了。
2.5 Galley
这个不知道咋翻译,目前这个组件的作用是验证用户编写的Istio api配置。从官网的说法来看,后面这个组件会逐步接管获取配置、处理和分配的工作,比如从k8s的数据中心(etcd)获取集群信息的活,理论上应该交给Galley干。从这个信息来看,Galley的定位应该类似于k8s的api server组件,提供集群内统一的配置信息接口,从而将用户配置的细节隔离开来。
以下是从官网各项示例中整理出来的Istio所支持的功能列表:
类别 | 功能 | 说明 |
---|---|---|
流量管理 | 请求路由 | A/B测试、金丝雀发布等,包括对集群出入口、及集群内部的流量的控制。比如某应用新版本发布,可以配置为5%的流量流向新版本,95%的给旧版本 |
流量转移 | 与上一条请求路由类似,可以平滑的将流量从旧版本转移到新版本上 | |
负载均衡 | 目前支持3种方式,轮询、随机和带权重的最少请求 | |
服务发现 | 带心跳的健康检查,失败率超标的Pod移出负载均衡池 | |
故障处理 | 超时、重发、熔断、上游并发请求或下游连接数限制等 | |
微调 | 支持用特殊的请求头参数,覆盖默认的超时、重发值 | |
故障注入 | 由Enovy在正常的集群中人为注入故障,比如TCP包损坏或延迟、HTTP错误码等,支持按百分比注入,比如给10%的流向服务A的请求包增加5秒延迟 | |
多重匹配 | 上述规则的配置,支持按多种条件匹配,且支持and或or的方式匹配多条规则 | |
Gateway | 接管集群入口的流量,替代了Ingress,从而对入口流量执行其他规则 | |
Service Entry | 接管集群内部访问外部服务的流量,从而对出口流量执行一些规则 | |
镜像 | 支持将特定的流量镜像到服务路径之外,而不影响主服务路径的正常执行 | |
安全 | 命名空间访问控制 | 支持配置某命名空间的所有或个别服务可以被其他命名空间访问 |
服务级别访问控制 | 允许或禁止访问某个服务 | |
双向TLS | HTTPS加密传输 | |
其他安全策略 | ||
策略 | 速率限制 | 比如限制每秒的请求次数 |
黑白名单 | 支持基于IP或属性的黑名单、白名单 | |
遥测 | 日志收集 | 支持将Prometheus、Jaeger等系统插入Mixer,从而完成数据的采集 |
指标采集 | ||
分布式追踪 |