https://github.com/istio/istio
https://www.servicemesher.com/blog/back-to-microservices-with-istio-p1/
在微服务架构中,服务可能会用不同的语言实现并部署在多个节点或集群上,具有不同的响应时间或故障率。如果服务成功(并且及时地)响应了请求,那么它的性能就算是令人满意的。但现实情况并非如此,下游客户端应该在上游服务过于缓慢时受到保护。反之,上游服务也必须被保护,以免被积压的请求拖垮。在多客户端下情况会更加复杂,并可能导致整个基础设施出现一系列的连锁故障。这一问题的解决方案是采用经过时间检验的熔断器模式。
一个熔断器可以有三种状态:关闭、打开和半开,默认情况下处于关闭状态。在关闭状态下,无论请求成功或失败,到达预先设定的故障数量阈值前,都不会触发熔断。而当达到阈值时,熔断器就会打开。当调用处于打开状态的服务时,熔断器将断开请求,这意味着它会直接返回一个错误,而不去执行调用。通过在客户端断开下游请求的方式,可以在生产环境中防止级联故障的发生。在经过事先配置的超时时长后,熔断器进入半开状态,这种状态下故障服务有时间从其中断的行为中恢复。如果请求在这种状态下继续失败,则熔断器将再次打开并继续阻断请求。否则熔断器将关闭,服务将被允许再次处理请求。
Istio中的熔断
Istio的 熔断 可以在 流量策略 中配置。Istio的 自定义资源Destination Rule里,TrafficPolicy字段下有两个和熔断相关的配置:ConnectionPoolSettings 和 OutlierDetection。
ConnectionPoolSettings可以为服务配置连接的数量。OutlierDetection用来控制从负载均衡池中剔除不健康的实例。
例如,ConnectionPoolSettings控制请求的最大数量,挂起请求,重试或者超时;OutlierDetection 设置服务被从连接池剔除时发生错误的请求数,可以设置最小逐出时间和最大逐出百分比。有关完整的字段列表,请参考文档.
Istio在底层使用了Envoy的熔断特性。
让我们来看看Destination Rule中有关熔断的配置:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: notifications
spec:
host: notifications
trafficPolicy:
connectionPool:
tcp:
maxConnections: 1
http:
http1MaxPendingRequests: 1
maxRequestsPerConnection: 1
outlierDetection:
consecutiveErrors: 1
interval: 1s
baseEjectionTime: 3m
maxEjectionPercent: 100
使用ConnectionPoolSettings字段中的这些设置,在给定的时间内只能和notifications 服务建立一个连接:每个连接最多只能有一个挂起的请求。如果达到阈值,熔断器将开始阻断请求。
OutlierDetection部分的设置用来检查每秒调用服务是否有错误发生。如果有,则将服务从负载均衡池中逐出至少三分钟(100%最大弹出百分比表示,如果需要,所有的服务实例都可以同时被逐出)。
在手动创建Destination Rule资源时有一件事需要特别注意,那就是是否为该服务启用了mTLS。如果是的话,还需要在Destination Rule中设置如下字段,否则当调用movies服务时,调用方可能会收到503错误:
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
还可以为特定namespace 或特定服务启用全局的mTLS。你应该了解这些设置以便确定是否把trafficPolicy.tls.mode设置为 ISTIO_MUTUAL。更重要的是,当你试图配置一个完全不同的功能(例如熔断)时,很容易忘记设置此字段。
提示:在创建Destination Rule前总是考虑mTLS!
为了触发熔断,让我们同时从两个连接来调用 notifications服务。maxConnections字段被设置为1。这时应该会看到503与200的响应同时到达。
当一个服务从客户端接收到的负载大于它所能处理的负载(如熔断器中配置的那样),它会在调用之前返回503错误。这是防止错误级联的一种方法。
监控
在生产环境中必须要监控你的服务,以便得到通知并能够在系统发生错误时进行检查。因此,如果你已经为你的服务配置了一个熔断器,你就会想知道它什么时候跳闸;熔断器拦截了百分之多少的请求;何时触发,来自哪个下游客户端?如果能够回答这些问题,你就可以确定熔断器是否工作正常,并根据需要微调配置,或者优化服务来处理额外的并发请求。
提示:如果你继续阅读,可以在Backyards UI中看到和配置所有的这些设置。
让我们看看怎样在Istio里确定熔断器跳闸:
熔断器跳闸时的响应码是503,因此你无法仅根据该响应与其他的503错误区分开来。在Envoy中,有一个计数器叫upstream_rq_pending_overflow,它记录了熔断且失败的请求总数。如果为你的服务深入研究Envoy的统计数据就可以获得这些信息,但这并不容易。
除了响应代码,Envoy还返回响应标志 ,并且存在一个专用响应标志来表示熔断器跳闸:UO。如果这个标志只能通过Envoy的日志获得,这将不会特别有用。幸运的是,它在Istio中实现了,因此响应标志在Istio指标中是可用的并且能被Prometheus获取到。
熔断器的跳闸可以像这样查询到:
sum(istio_requests_total{response_code=”503”, response_flags=”UO”}) by (source_workload, destination_workload, response_code)
Backyards的熔断更简单
使用Backyards时,你不需要手动编辑Destination Rules来设置熔断。可以通过一个方便的UI界面或者(如果你愿意的话)是Backyards CLI 命令行工具来达到相同的结果。
不必担心由于忘记把trafficPolicy.tls.mode 设置为 ISTIO_MUTUAL而配错了Destination Rules。Backyards会为你解决这个问题;它会找到启用了mTLS的服务并相应地设置上述字段。
上面只是Backyards验证特性的一个例子,这能避免你设置错误。后面还有更多的特性。
在此之上,你可以看到服务和请求的可视化界面和活动仪表板,因此可以轻松地确定有多少请求被熔断器触发,以及它来自哪个调用者和何时触发。
Istio带给你:
HTTP、gRPC、WebSocket和TCP流量的自动负载均衡。
通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制。
支持访问控制、速率限制和配额的可拔插策略层和配置API。
自动指标、日志和集群内所有流量的跟踪,包括集群入口和出口。
通过集群中的服务之间的强身份断言来实现服务间的身份验证。
通过在整个环境中部署一个特殊的sidecar代理(辅助容器),您可以将Istio支持添加到服务中(这给我留下了深刻的印象,如果您想做到这一点,请参阅后面的内容)。安装了sidecar代理之后,(微)服务之间的所有网络通信都通过这个代理。此外,所有的网络通信都是使用Istio的控制平面功能进行配置和管理的。
Istio是Service Mesh(服务网格)。我认为的service mesh定义就是“它是一个专用的基础设施层,使得服务间的通信安全、高效和可靠”
然而,如果像我一样,你从概念文档开始看的话,上面有这样的内容:“术语service mesh通常用于描述组成这些应用程序的微服务网络以及它们之间的交互。随着服务网格的大小和复杂程度不断增加,可能会变得难以理解和管理。可能出现包括服务发现、负载平衡、故障恢复、度量和监控,以及更复杂的需求,如A/B测试、金丝雀发布、速率限制、访问控制和端到端身份验证。Istio提供了一个完整的解决方案,通过对整个服务网格提供行为分析和操作控制来满足微服务应用程序的各种需求。“
读完之后你可能会像我一样困惑!最后在网上查了一圈关于什么是服务网格之后,我终于搞明白了。我最后使用的可能是一个在所有搜索到的样本里一个非代表性的共识,但这是一个合理的选择。不过有个细节确实了,就是如何将它与k8s等编排工具分开。Istio需要跟k8s一起使用,没有k8s或其他容器编排工具的它就不存在了吗?它没有做编排,实际上它的是为解决管理基于微服务的解决方案中网络和操作复杂性而设计的。它涵盖的范围就像k8s一样!现在我真的需要继续这个帖子了。。。
所以我知道Istio是什么,给我们带来了什么,但它实际上解决了什么挑战呢?
从为什么使用Istio页面中可以看出,它在服务网络中统一提供了许多关键功能:
流量管理
可观察性
强制策略
服务身份标识和安全
对于我来说,要真正理解Istio的价值,所以我使用了codelab。编写code lab的人真是太棒了!
Code lab向我介绍了Istio控制平面的四个主要组件:
Pilot:处理代理sidecar的配置和编程。
Mixer:为您的流量处理决策并收集遥测数据。
Ingress:处理来自群集外部的传入请求。
CA:证书颁发机构。
查看Istio架构概念页面了解这些组件如何协同工作的。
Code lab提供了路由规则——流量管理部分
我还尝试了Istio.io中的一些task,因为我需要了解它如何处理那些领域的工作。
提示:如果您在完成codelab时也决定在四处看看,那么请将您的群集与应用程序一起启动并运行。无论如何,你会再次使用它。
所以我对它如何解决这些问题有了一个基本的了解,但是如果我使用像GKE这样的托管K8s(好吧,你知道我会选那个不是吗?)使用Istio是否合适?
注意:是的,这里有更多的细节,但我主要想弄明白为什么需要使用Istio。
集群最终用户/开发人员访问
GKE结合使用IAM和RBAC,是的,这里面有很多东西需要你了解。
要为您的集群用户授予比Cloud IAM更细粒度的权限,您可以使用namespace和RBAC来限制对特定pod的访问或排除对secret的访问。
Istio RBAC介绍了两个侧重于服务的角色
ServiceRole定义用于访问网格中的服务的角色。
ServiceRoleBinding将角色授予主题(例如用户、组、服务)。
它们是k8s中的CustomResourceDefinition(CRD)对象。但您仍然需要了解IAM。
服务身份标识
GKE可以使用service account来管理GKE上运行的应用程序可以使用哪些GCP服务。这些service accout的密钥使用secret存储。Pod中运行的进程的身份标识是由k8s service account与RBAC一起决定的。Istio使用istio-auth,它使用双向TLS提供强大的服务间和最终用户身份验证,内置身份和凭证管理。Istio-auth使用Kubernetes service account。
Itsio不提供任何使用GCP service account帮助。这还很早,但是它正在制定未来发展计划的路线图。
Istio-auth很好,计划中的增强功能将值得等待。我对安全的复杂性感到厌烦,因为这不可避免地导致配置错误,所以我希望它与service account类型之间进行更加无缝的对齐!
网络控制
GKE(用于k8s版本1.7.6 +)使用k8s网络策略来管理哪些Pod可以和服务通信。这是相对简单的配置。 Istio也有网络策略,但他们不是你知道和喜欢的K8s策略,为什么会有这样的区别呢? 这篇文章很好地解释了这一点,所以我不会在这里重述,但是这个表格总结了不同之处以及为什么会有这样的不同。
项目 Istio策略 网络策略
层 Service(7层) Network(3、4层)
实现 Userspace Kernel
控制点 Pod Node
Istio使用envoy作为sidecar代理。Envoy在OSI模型的应用层运行,所以在第7层。我的这篇博客将为你详细解释。
您需要两种策略类型,这是纵深防御的方法。
多个集群
Istio有个非常酷的功能是mixer适配器。简而言之,它可以从底层后端进行抽象以提供核心功能,例如日志记录、监控、配额、ACL检查等。它公开了一个一致的API,与使用的后端无关。就像GCS公开了一个API,无论您使用什么存储类别!
我认为mixer适配器模型博客文章中的这张图片解释了mixer适配器中的全部要点。
mixer适配器模型
有一个早期demo,我认为它是istio最有用的特性之一,它实际上使用虚拟机来承载codelab中使用的评分dbase MySQL数据库,并将其作为GKE集群所属网格的一部分。使用一个网格来管理它们!
流量管理
如果你使用了codelab,你会看到使用istio来引导使用路由规则的流量是多么容易。使用K8s,您还可以使用金丝雀部署进行流量管理,并以类似于istio的方式将一定比例的流量引导至您的应用的一个版本,但Istio在这种情况下更灵活,方法是允许您设置细粒度流量百分比并控制流量使用code lab中的其他标准。
服务发现
服务注册在k8s中完成。Istio抽象出底层的服务发现机制,并将其转换为envoy sidecar可消费的标准格式。
审计记录和监控
如果是超出GKE提供的标准日志记录的话,可以将GKE与StackDriver日志记录集成来收集,在持久化存储中存储容器日志、系统日志和关于群集中的活动的事件,例如Pod的调度。还可以与StackDriver Monitoring集成以收集系统度量指标(度量群集的基础设施,例如CPU或内存使用情况)和自定义指标(特定于应用程序的指标)。
Istio利用prometheus与grafana一起作为仪表板进行记录和监控。我喜欢service graph配置,它可以为您提供service mesh的图形表示。你也可以用kibana和fluentd来配合Elasticsearch使用。
那么我需要Istio吗?
Istio的流量管理非常棒,mixer适配器模型可以轻松管理覆盖多个群集和虚拟机的网格。我喜欢Istio是因为它可以让你进中精力思考服务,而不是那么多的pod和节点,并不是说你不必担心这些,而是只关注服务就好了!
如果你需要管理一个分布式集群,那么Istio应该在你的选择列表里。如果您需要在流量管理方面有比k8s提供的更多的灵活性的化那么Istio也很值得关注。
如果你有足够的资源来处理处于发展早期的事物,那么尽早理解Istio是值得的。如果你已经在使用k8s的话那么istio的学习曲线将很低。
记住它是一个建立在上层的东西,所以你仍然需要在k8s层做些事情,比如配置k8s网络策略来补充istio网络策略。
Istio还处于发展的早期阶段,所以它不会做你期望的所有事情,但我们希望它会。你将无法避免的在提供商API和Istio之间来回调用才能完成一个完整的工作,所以它不是你希望的那种一站式解决方案。
Dashboard是可视化网格配置的一种很好的方式,因为编写YAML会让人很快疲惫!是的,您可以设置仪表板上的控制面板来可视化度量指标,但我希望看到它与StackDriver集成。