Service Mesh - Istio流量控制篇(下)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Service Mesh - Istio流量控制篇(下)相关的知识,希望对你有一定的参考价值。

参考技术A

上篇:

Ingress 基本概念:

部署 httpbin 服务,同样,官方demo已经提供了该配置文件,执行如下命令应用即可:

为 httpbin 服务配置 Ingress 网关,定义 Ingress gateway,如下所示:

然后定义 Virtual Service 配置路由规则并关联该 Gateway:

使用如下命令获取 istio-ingressgateway 服务的实际请求地址和端口号(但服务的 EXTERNAL-IP 为 pending 或 none 时采用此方式,详见: 官方文档 ):

接下来使用 curl 命令测试一下 httpbin 的接口能否正常访问:

访问没有被暴露的接口,此时返回404:

有进入网格的流量也就有从网格出去的流量,这种入口流量与出口流量也就是我们常说的南北流量,在Istio中我们可以对网格的入口和出口流量进行管控。

Istio中访问外部服务的方法:

Egress 概念:

在本小节,我们将实践创建一个 Egress 网关,让内部服务(sleep)通过它访问外部服务(httpbin.org),这两个服务在前面的章节示例中都已经演示过了:

查看 istio-egressgateway 组件是否存在:

确认 sleep 服务已处于正常运行状态:

为 httpbin.org 这个外部服务定义 ServiceEntry:

确认创建成功:

定义 Egress gateway:

定义路由,将流量引导到 istio-egressgateway:

测试访问 httpbin.org 服务的接口:

查看日志验证出口流量是否经过了Egress网关,输出了如下日志信息代表Egress网关配置成功,出口流量经过了该Egress网关:

此时 sleep 服务访问外部服务的流程如下图:

对于一个分布式系统来说,出现网络故障是在所难免的,因此如何提升系统弹性,提升系统在面对故障时的处理能力是分布式架构非常重要的一个主题。其中,超时和重试是非常重要且常用的,用于提升系统弹性的机制。

基本概念

接下来我们还是通过Bookinfo这个应用来作为演示,对其中的一些服务添加超时策略和重试策略。我们会将请求指向 reviews 服务的 v2 版本,并在 ratings 服务中添加延迟设置,模拟一个故障出现的情况,以此来验证我们设置的超时和重试策略是否生效:

首先,创建一个Virtual Service将请求路由到 reviews 服务的 v2 版本:

给 ratings 服务注入延迟,模拟故障:

给 reviews 服务添加超时策略:

此时刷新应用页面,可以看到返回了错误信息:

将 reviews 服务的超时策略取消掉,然后给 ratings 服务添加重试策略:

查看 ratings 服务的 Sidecar 日志,然后刷新应用页面,正常情况下从日志输出可以看到重试了两次请求:

配置选项 :

什么是 断路器(Circuit Breaking)?

本小节我们实践一下为 httpbin 服务 添加断路器配置 ,然后通过负载测试工具来触发熔断。断路器相关配置是在服务的 DestinationRule 中里进行配置的,如下所示:

安装fortio,使用该负载测试工具来触发熔断:

先尝试发送单个请求,确认该工具能够正常工作:

没问题后,通过如下命令进行并发压测,并发数是3,执行30次:

如果希望查看具体指标可以使用如下命令:

配置选项 :

了解 故障注入(Fault injection) :

在配置好网络(包括故障恢复策略)后,我们可以使用Istio的故障注入机制来测试应用程序的整体故障恢复能力。故障注入是一种将错误引入系统以确保系统能够承受并从错误条件中恢复的测试方法。

所以故障注入机制特别有用,可以提前暴露一些故障恢复策略不兼容或限制性太强,从而可能导致的关键服务不可用的问题。故障注入在业界的发展和应用例子:

其实我们在之前的小节中早已演示过了Istio的故障注入配置,在超时与重试的小节中,我们就为 ratings 服务注入过一个延迟故障:

使用如下命令将Bookinfo应用各个服务的路由信息设置到各自的 v1 版本:

然后将 reviews 服务的流量指向它的 v2 版本,因为只有 v2 和 v3 版本才会调用 ratings 服务:

给 ratings 服务注入延迟故障:

virtual-service-ratings-test-delay.yaml 文件的内容:

配置选项 :

相信很多开发人员都遇到过这样的问题,就是在开发/测试环境中运行良好的功能,一上线就出问题。即便做足了单元测试、集成测试,测试覆盖率也很高,也依然会有这种问题存在,并且这类问题在开发/测试环境难以复现。

出现这种问题的一个主要原因,是因为线上环境,特别是数据环境,比如说数据量、请求的并发量以及用户使用数据的方式都与开发/测试环境非常的不一样。由于这种不一致性导致我们很难在开发/测试环境中发现线上的问题。

那么一个非常好的解决办法,就是使用流量镜像机制,将线上流量复刻一份到开发/测试环境中进行测试。

了解 流量镜像(Traffic Mirroring) :

流量镜像(Traffic mirroring,也称为Shadowing)是一个强大的概念,它允许开发团队以尽可能小的风险为生产环境带来更改。流量镜像机制可以将实时流量的副本发送到一个镜像服务。对流量的镜像发生在主服务的关键请求路径之外。

接下来我们实践一下如何配置Istio中的流量镜像机制,需求是将发送到 v1 版本的流量镜像到 v2 版本。因此,我们首先部署 httpbin 服务的 v1 和 v2 版本。v1 版本的配置如下:

部署 httpbin 服务的 v2 版本:

为 httpbin 创建一个 Service 资源,让 Pod 能够通过服务的方式暴露出来:

为 httpbin 服务创建默认的虚拟服务与目标规则:

测试一下能否正常访问到 httpbin 服务的接口:

完成以上的准备工作后,我们就可以在虚拟服务中为 httpbin 服务的 v2 版本配置对 v1 版本的流量镜像:

尝试请求 httpbin 服务的接口,由于我们配置了路由规则,该请求一定是被路由到 v1 版本上的:

此时观察 v2 版本的日志,从日志输出中可以发现 v2 版本也接收到了相同的请求,代表我们的流量镜像配置生效了:

配置选项 :

腾讯云 TSF Service Mesh 流量转发原理介绍

1 TSF service mesh

腾讯云TSF service mesh是service mesh理念在TSF的落地实现,最主要的特点是在业务程序本地引入一个网络代理,让用户基本不需要引入额外代码就能方便透明的接入微服务,获得服务注册、服务发现、服务路由、服务鉴权和服务限流等能力,这样不同语言编写的和无法改造的业务也可以方便的接入微服务框架。 

TSF service mesh基于开源项目istio(https://istio.io/), 整体架构如下:

TSF service mesh架构从逻辑上划分为控制面和数据面两大部分:

  • 控制面主要提供配置及控制指令支撑数据面组件的正常运行

  • 数据面主要是提供通信代理来进行透明的服务调用,支撑正常的业务流程

控制面组件:

  • api-server:提供mesh的管理接口,用户可通过调用REST API可以进行mesh的功能配置管理

  • pilot:mesh调度控制中心,提供数据面的动态配置通知下发的能力

  • mixer:mesh策略控制及统计上报中心,提供数据面的访问策略控制、统计信息采集及上报等能力

数据面组件 :

  • pilot-agent:负责环境的初始化及清理,envoy/mesh-dns的生命周期管理

  • envoy:通信代理,提供服务与服务之间通信及治理的能力

  • mesh-dns:提供服务的本地域名解析的能力

其中,透明流量转发是指用户不需要感知本地代理的存在,还可以继续按照域名的方式访问透明的访问其他服务,如通过http访问某个后端服务,原先通过(http://ip:port/api/get) ,只需要变成(http://服务名/api/get) 来访问即可,这就需要在本地将业务程序的流量转发到代理中,即实现本地流量托管。

2 TSF service mesh中的本地流量托管

在TSF mesh中,为了实现服务注册、发现、路由等功能,在本地会有一个proxy进程代理所有的本地服务进出流量。 为了让用户不感知本地代理,即原有的访问方式保持不变,需要将服务的进出流量透明的转发到本地代理。 同时为了不影响本地没有注册在tsf中的业务,我们不能做全量托管,要做细粒度的流量转发。

3 流量转发方案选择

目前在linux下常见的细粒度流量转发方案有几种: 1)iptables iptables是历史悠久的firewall,一直集成在linux内核中。其中,iptables的nat模块(netfilter)就可以用于流量转发。 2)ipvs ipvs集成进linux自带的4层负载均衡组件LVS,可以用于流量转发 3) bpf filter bpf filter,即berkerly pacakge filter,作为tcpdump等流量分析工具的底层实现,特点是性能高和安全,经过发展,开始慢慢作为新一代的流量转发利器

iptables vs ipvsiptables的优势在于起步早,使用范围广泛。iptabels最让人诟病的是当转发规则多时它的性能会下降(瓶颈在5000左右),但是在tsf mesh中随着服务和节点的增加,我们都只会有少量的几条规则(具体原因见后面的示例)iptables vs bpf filter虽然从性能上来看bpf filter会比iptables高,但是目前用bpf filter来做流量转发并不是很成熟

总体来看我们选择了iptables来做细粒度的流量转发。

4 TSF service mesh的流量转发

在TSF mesh中,本地的proxy作为入流量和出流量的double proxy,为了将服务的进出流量转发到本地代理,需要同时有出流量转发规则和入流量转发规则,同时还要将不应该托管的流量return掉

比如现在我们有两个服务consumer和provider,每个服务有一个节点 9.77.7.132节点上有服务:consumer,服务监听端口: 8080,服务协议: http 9.77.7.35节点上有服务:provider,服务监听端口: 8081,服务协议: http 本地代理监听在15001 在9.77.7.132上访问9.77.7.35的provider的/api/get接口: curl http://provider/api/get一次请求的路线如下: 出流量涉及四个组件 1)发起dns请求,查找provider的ip 2)dns query被iptables转发到本地的dns server(监听5353),返回虚拟vip

3)向得到的虚拟vip:80发起请求http://provider/api/get

4)请求被iptables转发到15001端口(proxy)

5)proxy向9.77.7.35:8081发起请求http://provider/api/get 入流量涉及三个组件 6)请求被iptables转发到本地15001端口(proxy) 7)proxy向9.77.7.35:8081发起请求http://provider/api/get

9.77.7.132上的nat规则如下:

 
   
   
 
  1. Chain PREROUTING (policy ACCEPT)

  2. target     prot opt source               destination        

  3. ISTIO_INBOUND  tcp  --  0.0.0.0/0            0.0.0.0/0          


  4. Chain INPUT (policy ACCEPT)

  5. target     prot opt source               destination        


  6. Chain OUTPUT (policy ACCEPT)

  7. target     prot opt source               destination        

  8. ISTIO_OUTPUT  all  --  0.0.0.0/0            0.0.0.0/0          

  9. DNS_OUTPUT  all  --  0.0.0.0/0            0.0.0.0/0          


  10. Chain POSTROUTING (policy ACCEPT)

  11. target     prot opt source               destination        


  12. Chain DNS_OUTPUT (1 references)

  13. target     prot opt source               destination        

  14. RETURN     all  --  0.0.0.0/0            0.0.0.0/0            owner UID match 1000

  15. DNAT       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53 to:127.0.0.1:5353

  16. DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53 to:127.0.0.1:5353


  17. Chain ISTIO_INBOUND (1 references)

  18. target     prot opt source               destination        

  19. RETURN     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

  20. ISTIO_REDIRECT  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8080


  21. Chain ISTIO_OUTPUT (1 references)

  22. target     prot opt source               destination        

  23. RETURN     all  --  0.0.0.0/0            0.0.0.0/0            owner UID match 1000

  24. DNAT       tcp  --  0.0.0.0/0            168.254.48.46        to:9.77.7.132:15001


  25. Chain ISTIO_REDIRECT (2 references)

  26. target     prot opt source               destination        

  27. REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0            redir ports 15001

9.77.7.35上的nat规则如下:

 
   
   
 
  1. Chain PREROUTING (policy ACCEPT)

  2. target     prot opt source               destination        

  3. ISTIO_INBOUND  tcp  --  0.0.0.0/0            0.0.0.0/0          


  4. Chain INPUT (policy ACCEPT)

  5. target     prot opt source               destination        


  6. Chain OUTPUT (policy ACCEPT)

  7. target     prot opt source               destination        

  8. ISTIO_OUTPUT  all  --  0.0.0.0/0            0.0.0.0/0          

  9. DNS_OUTPUT  all  --  0.0.0.0/0            0.0.0.0/0          


  10. Chain POSTROUTING (policy ACCEPT)

  11. target     prot opt source               destination        


  12. Chain DNS_OUTPUT (1 references)

  13. target     prot opt source               destination        

  14. RETURN     all  --  0.0.0.0/0            0.0.0.0/0            owner UID match 1000

  15. DNAT       udp  --  0.0.0.0/0            0.0.0.0/0            udp dpt:53 to:127.0.0.1:5353

  16. DNAT       tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:53 to:127.0.0.1:5353


  17. Chain ISTIO_INBOUND (1 references)

  18. target     prot opt source               destination        

  19. RETURN     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22

  20. ISTIO_REDIRECT  tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8081


  21. Chain ISTIO_OUTPUT (1 references)

  22. target     prot opt source               destination        

  23. RETURN     all  --  0.0.0.0/0            0.0.0.0/0            owner UID match 1000

  24. DNAT       tcp  --  0.0.0.0/0            168.254.48.46        to:9.77.7.35:15001


  25. Chain ISTIO_REDIRECT (2 references)

  26. target     prot opt source               destination        

  27. REDIRECT   tcp  --  0.0.0.0/0            0.0.0.0/0            redir ports 15001

说明: Chain DNSOUTPUT:用于做本地dns劫持(用于收敛转发规则到虚拟ip) ISTIOINBOUND:入流量转发规则,只劫持访问本地8081的流量 ISTIOOUTPUT:出流量转发规则,只劫持访问虚拟ip(虚拟ip,用于规则收敛)的流量 ISTIOREDIRECT:劫持流量到本地的15001端口

6 参考

https://console.cloud.tencent.com/tsf
https://kubernetes.io/blog/2018/07/09/ipvs-based-in-cluster-load-balancing-deep-dive
https://cilium.io/blog/2018/04/17/why-is-the-kernel-community-replacing-iptables/


以上是关于Service Mesh - Istio流量控制篇(下)的主要内容,如果未能解决你的问题,请参考以下文章

Service Mesh实战 手把手带你学会Istio

k8s 安装并试用Istio service mesh

腾讯云 TSF Service Mesh 流量转发原理介绍

谈谈微服务架构中的基础设施:Service Mesh与Istio

Istio 控制面对接 Consul 注册中心

Service Mesh 的实现,Google 的 Istio