Istio系列学习----Istio的路由规则配置:VirtualService

Posted 归来少年Plus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Istio系列学习----Istio的路由规则配置:VirtualService相关的知识,希望对你有一定的参考价值。

VirtualService是istio流量治理的核心配置.

一、路由规则配置示例


含义:对于forecast服务的访问,如果在请求的Header中location取值是north,则将该请求转发到服务的v2版本上,其他请求转发到服务的v1版本上。

二、路由规则定义

virtualService:用于定义对特定目标服务的一组流量规则。描述一个具体的服务对象,包含了对流量的各种处理。

virtualService中的术语:
service:服务
service version:服务版本
source: 发起调用的服务
host: 服务调用方连接和调用目标服务时使用的地址

VirtualService的1级定义,包括通用字段hosts、gateways,复合字段HttpRoute、TCPRoute、TLSRoute,表示istio支持的http\\TCP\\TLS协议的流量规则。

hosts和gateways是每种协议都要用到的公共字段。
1、hosts
必选,表示流量发送的目标。用于匹配访问地址,可以是一个DNS名称或IP地址。
DNS可以使用通配符前缀,也可以使用短域名。但是建议在规则中明确写完整的域名。

对k8s平台来说,hosts中一般是Service的短域名。如forecast对应的完整域名是:forecast.weather.svc.cluster.local,其中weather是forecast服务部署的命名空间。
isito中,hosts的全域名是 forecats.default.svc.cluster.local。其中命名空间default是virtualService的命名空间,不是Service的命名空间。

2、gateways
标识应用这些流量规则的gateway。VirtualService描述的规则可以作用到网格里的Sidecar和入口处的Gateway。具体场景如下:
1)服务仅在网格内访问,规则也仅作用于网格内的sideCar。此时gateways字段可以省略。

2)服务仅在网格外访问,需要配置关联的Gateway,对应gateway进来的流量执行在这个VirtualService上定义的规则。

3)服务在网格内核网格外都要访问,那对gateways数组字段至少配置两个元素,一个是是外部访问的gateway,另一个是保留关键字”mesh“。

3、http
用于处理http的流量,是一个与HTTPRoute类似的路由集合

4、tls
用于处理非终结的TLS和HTTPS的流量,是一个TLSRoute类型的路由集合。

5、tcp
用于处理TCP的流量,所有其他非HTTP和TLS端口的流量,是一个TCPRoute类型的路由集合
注意:http tls tcp3各字段在定义上都是数组,可以定义多个元素;使用上都是一个有序列表,应用时匹配的第一个规则生效。不会检查后面的规则

6、exportTo
新增字段,控制VirtualService跨命名空间的可见性,即VirtualService是否可以被其他命名空间下的sidecar和Gateway使用。
默认全局可见。 .表示仅应用到当前命名空间, *表示应用到所有的命名空间。

三、HTTP路由(HttpRoute)

1、HTTPRoute
http是当前最通用、内容最丰富的协议。除了可以路由,还可以进行如:重定向、重写、重试、流量镜像、故障注入、跨资源共享等操作。
实际的协议包括:http http2 grpc

2、http的配置规则
支持将uri schema method authority port等作为条件来匹配。
URI 的完整格式是:URI=scheme:[//authority]path [?query][#fragment]
Authority的标准定义是:“authority=[userinfo@]host[:port]

具体匹配规则:
1)uri schema method authority都是StringMatch类型,在匹配时支持extract-全部匹配、prefix-前缀匹配、regex-正则匹配
2)headers map类型,也可以采用全部、前缀、正则三种方式匹配。


匹配headers中source取值为north,并且uri以/advertisement开头的请求
3)port 请求的服务端口
4)sourcelabels map类型的键值对,标识请求来源的负载匹配标签。可以对一组服务都打一个相同的标签,然后使用sourceLabels字段对这些服务试试相同的流量规则。
k8s平台中,label就是pod上的标签。

标识请求来源是frontend服务的v2版本负载。
5)gateways:规则应用的gateway名称

匹配逻辑:HTTPMatchRequest中多个match是或的关系,
某个match中的诸多属性如uri、 headers、method等是“与”逻辑,而属性数组中几个元素间的关系是“或”逻辑。

match有两个,其条件的语义是:headers中的source取值 为“north”,并且uri以“/advertisement”开头的请求,或者uri以“/forecast”开头的请求。

在生产环境运行Istio

Istio是什么?Istio是服务网格技术,在网络上添加一层抽象层。它截获Kubernetes集群里的所有或者部分流量,并在之上执行一系列操作。支持哪些操作呢?比如,搭建智能路由或实现断路器方案,进行“金丝雀部署”等。另外,Istio还可以限制外部交互并且控制集群和外部网络的所有路由。而且,Istio支持配置策略规则来控制不同微服务之间的交互。最终,我们可以生成完整的网络交互图,并且得到对于应用来说完全透明的指标集。

官方文档[1]里有Istio的详细介绍。本文介绍Istio上微服务交互背后的基本原理,展示Istio的确是解决各种问题的相当强大的工具。本文尝试回答Istio初学者经常会问的各种问题,帮助大家更有效率地使用Istio。

在介绍安装之前,先介绍一些核心观点,总体看一下Istio的组件和组件间交互的原理。

工作原理

在生产环境运行Istio


Istio由两大组件组成——控制面板和数据面板。控制面板包含基础组件,确保和其他组件之间的正确交互。在当前的1.0版本里,控制面板有三个组件:Pilot,Mixer和Citadel。这里不讨论Citadel,因为在生成证书来进行服务间的双向TLS通信时才需要它。我们先了解一下Pilot和Mixer的设计和目标。

在生产环境运行Istio

Pilot是主要的控制组件,它负责分发集群内的所有信息——服务,它们的端点以及路由规则(比如,金丝雀发布规则或者断流器规则)。

Mixer是可选的控制面板组件,它负责收集指标、日志以及其他网络交互的信息。它还监控是否符合策略规则以及是否符合速率限制。

数据面板的组件使用sidecar代理容器来实现。默认使用强大的代理服务器Envoy[2]。为了确保Istio对于应用来说是彻底透明的,这里使用了自动注入系统。最新的实现支持Kubernetes 1.9或更新版本(mutational admission webhook)。对于Kubernetes 1.7,1.8版本,可以是用Initializer。

Sidecar容器通过GRPC协议连接Pilot,优化集群内变更的pushdown模型。Envoy从1.6版本就开始使用GRPC;Istio则从0.8版本开始使用,它是pilot-agent——Envoy之上GO的封装,用来配置启动参数。

Pilot和Mixer是纯粹的无状态组件,所有的状态都保存在应用程序的内存里。它们的配置由Kubernetes的Custom Resource定义,存储在etcd里。Istio-agent得到Pilot的地址,并打开GRPC连接。

正如我所说,Istio在对应用完全透明的前提下实现了所有功能。让我们一起看看是怎么实现的。算法原理如下:

  1. 我们部署服务的一个新版本。

  2. 取决于sidecar容器的注入类型,在配置阶段添加istio-init容器和istio-agent容器(Envoy),或者手动插入到Kubernetes实体的Pod描述里。

  3. istio-init容器是一些脚本,为Pod设置iptables规则。有两种方式配置流量重定向到istio-agent容器里:使用直接的iptables规则或者TPROXY[2]。撰写本文时,默认使用的是重定向规则。在istio-init里,可以配置截获哪些流量并发送给istio-agent。比如,为了截获所有入站和出站流量,用户需要将参数 -i和 -b设置为 *。用户也可以指定截获特定端口的流量。为了避免截获特定子网的流量,可以使用 -x参数。

  4. 在init运行后,会启动容器,包括pilot-agent(Envoy)。它通过GRPC连接上已经部署的Pilot,得到集群内所有已有服务以及路由策略的信息。根据接收到的数据,它配置集群,将这些流量直接映射到Kubernetes集群里的应用程序端口。重要的地方是:Envoy动态配置监听器(IP,端口对)开始监听。因此,当请求进入Pod,并且使用iptables规则重定向到sidecar时,Envoy已经准备好处理这些连接,并且知道将这些代理流量转发到哪里去。这一步里,信息发送给Mixer,下文会详细介绍。


最终,我们得到Envoy代理服务器的所有网络,可以从一点(Pilot)完成配置。最终,所有inbound和outbound请求都会通过Envoy。更为重要的是,只截获TCP流量。这意味着仍旧是使用UDP上的kube-dns来解析Kubernetes服务IP,这点没有变化。然后,在resolver之后,outbound请求被envoy截获并处理,它决定请求发送到哪个端点(或者不发送,当访问策略禁止或者触发了断流算法时)。

现在我们已经熟悉了Pilot,接下来研究Mixer是怎么工作的,以及为什么我们需要Mixer。Mixer的官方文档在这里[3]。

Mixer有两个组件:istio-telemetry,isito-policy(0.8版本之前使用单个组件istio-mixer)。它们都是Mixer。Istio telemetry接收sidecar容器的GPRC,并且汇报服务交互和参数信息。Istio-policy接收到检查请求,确保满足Policy规则。这些策略检查在客户端(sidecar里)缓存一段时间。报告检查是批量发送的。这里介绍怎么配置以及需要设置哪些参数。

Mixer应该是高可用组件,提供telemetry数据的不间断收集和处理。整个系统是一个多层缓存器。最初,数据缓存在容器的sidecar里,然后在Mixer,最终发送到Mixer后台。因此,如果任意系统组件发生故障,buffer会增长,之后当系统恢复时,会flush。Mixer后台是发送telemetry数据的端点:statsd,newrelic等等。编写自定义后台很简单,之后我会给大家介绍。


总结一下,使用istio-telemetry的工作流如下:

  1. 服务1发送请求给服务2

  2. 在已有的服务1里,请求重定向到sidecar

  3. Sidecar Envoy监控到给服务2的请求,并准备所需信息

  4. 然后它使用Report请求发送给istio-telemetry。

  5. Istio-telemetry决定是否将Report发送给后台,这里也负责发送请求以及请求内容。


现在看看如何搭建包含两大基础组件Pilot和sidecar envoy的Istio系统。如下是Pilot读取的基础配置(Mesh):

 
   
   
 
  1. apiVersion: v1

  2. kind: ConfigMap

  3. metadata:

  4. name: istio

  5. namespace: istio-system

  6. labels:

  7. app: istio

  8. service: istio

  9. data:

  10. mesh: |-

  11. # disable tracing mechanism for now

  12. enableTracing: false

  13. # do not specify mixer endpoints, so that sidecar containers do not send the information

  14. #mixerCheckServer: istio-policy.istio-system:15004

  15. #mixerReportServer: istio-telemetry.istio-system:15004

  16. # interval for envoy to check Pilot

  17. rdsRefreshDelay: 5s

  18. # default config for envoy sidecar

  19. defaultConfig:

  20. # like rdsRefreshDelay

  21. discoveryRefreshDelay: 5s

  22. # path to envoy executable

  23. configPath: "/etc/istio/proxy"

  24. binaryPath: "/usr/local/bin/envoy"

  25. # default name for sidecar container

  26. serviceCluster: istio-proxy

  27. # time for envoy to wait before it shuts down all existing connections

  28. drainDuration: 45s

  29. parentShutdownDuration: 1m0s

  30. # by default, REDIRECT rule for iptables is used. TPROXY can be used as well.

  31. #interceptionMode: REDIRECT

  32. # port for sidecar container admin panel

  33. proxyAdminPort: 15000

  34. # address for sending traces using zipkin protocol (not used as turned off in enableTracing option)

  35. zipkinAddress: tracing-collector.tracing:9411

  36. # statsd address for envoy containers metrics

  37. # statsdUdpAddress: aggregator:8126

  38. # turn off Mutual TLS

  39. controlPlaneAuthPolicy: NONE

  40. # istio-pilot listen port to report service discovery information to sidecars

  41. discoveryAddress: istio-pilot.istio-system:15007


让我们将所有主要控制组件(控制面板)放到Kubernetes的istio-system命名空间里。

最小的配置仅仅要求Pilot的部署。我们使用如下配置[4]。并且手动配置sidecar容器的注入。

Init容器配置:

 
   
   
 
  1. initContainers:

  2. - name: istio-init

  3. args:

  4. - -p

  5. - "15001"

  6. - -u

  7. - "1337"

  8. - -m

  9. - REDIRECT

  10. - -i

  11. - '*'

  12. - -b

  13. - '*'

  14. - -d

  15. - ""

  16. image: istio/proxy_init:1.0.0

  17. imagePullPolicy: IfNotPresent

  18. resources:

  19. limits:

  20. memory: 128Mi

  21. securityContext:

  22. capabilities:

  23. add:

  24. - NET_ADMIN


Sidecar配置:

 
   
   
 
  1. - name: istio-proxy

  2. command:

  3. - "bash"

  4. - "-c"

  5. - |

  6. exec /usr/local/bin/pilot-agent proxy sidecar

  7. --configPath

  8. /etc/istio/proxy

  9. --binaryPath

  10. /usr/local/bin/envoy

  11. --serviceCluster

  12. service-name

  13. --drainDuration

  14. 45s

  15. --parentShutdownDuration

  16. 1m0s

  17. --discoveryAddress

  18. istio-pilot.istio-system:15007

  19. --discoveryRefreshDelay

  20. 1s

  21. --connectTimeout

  22. 10s

  23. --proxyAdminPort

  24. "15000"

  25. --controlPlaneAuthPolicy

  26. NONE

  27. env:

  28. - name: POD_NAME

  29. valueFrom:

  30. fieldRef:

  31. fieldPath: metadata.name

  32. - name: POD_NAMESPACE

  33. valueFrom:

  34. fieldRef:

  35. fieldPath: metadata.namespace

  36. - name: INSTANCE_IP

  37. valueFrom:

  38. fieldRef:

  39. fieldPath: status.podIP

  40. - name: ISTIO_META_POD_NAME

  41. valueFrom:

  42. fieldRef:

  43. fieldPath: metadata.name

  44. - name: ISTIO_META_INTERCEPTION_MODE

  45. value: REDIRECT

  46. image: istio/proxyv2:1.0.0

  47. imagePullPolicy: IfNotPresent

  48. resources:

  49. requests:

  50. cpu: 100m

  51. memory: 128Mi

  52. limits:

  53. memory: 2048Mi

  54. securityContext:

  55. privileged: false

  56. readOnlyRootFilesystem: true

  57. runAsUser: 1337

  58. volumeMounts:

  59. - mountPath: /etc/istio/proxy

  60. name: istio-envoy


为了成功部署,需要为Pilot创建ServiceAccount,ClusterRole,ClusterRoleBinding,CRD;更多详细信息在这里[6]。之后,带有注入的sidecar和Envoy的服务就启动了,会从Pilot获取所有数据并且处理请求。

最重要的一点是所有控制面板组件都是无状态的应用程序,都可以轻松地水平扩展。所有数据都以Kubernetes资源的自定义描述存储在etcd里。

此外,也可以在集群外运行Istio(实验用途),并且在几个Kubernetes集群之间监控并共享服务发现。更多的相关信息在这里[7]。在多集群安装里,要考虑到如下限制:

  1. CIDR Pod和Service CIDR必须在所有集群里都是唯一的,不能重叠。

  2. 集群间的任意Pod CIDR必须能够访问所有CIDR Pod。

  3. 所有Kubernetes API server都必须能够相互访问。


本文让你开始了解Istio。但是,后续文章会接着讨论现有的问题。我们会讨论外部流量路由的特性,探讨最常见的sidecar debug和Profile的方法。最终,我们会创建跟踪系统并且仔细介绍它和Envoy是如何交互的。

相关链接:

  1. https://istio.io/docs/concepts/

  2. https://www.envoyproxy.io/

  3. https://github.com/kristrev/tproxy-example/blob/master/tproxy_example.c

  4. https://istio.io/docs/concepts/policies-and-telemetry/overview/

  5. https://github.com/istio/istio/blob/release-1.0/install/kubernetes/helm/istio/charts/pilot/templates/deployment.yaml

  6. https://github.com/istio/istio/tree/release-1.0/install/kubernetes/helm/istio/charts/pilot/templates

  7. https://istio.io/docs/setup/kubernetes/multicluster-install/


原文链接:https://medium.com/avitotech/running-istio-on-kubernetes-in-production-part-i-a8bbf7fec18e


基于Kubernetes的DevOps实践培训


基于Kubernetes的DevOps实践培训将于2019年5月10日在上海开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:容器特性、镜像、网络;Kubernetes架构、核心组件、基本功能;Kubernetes设计理念、架构设计、基本功能、常用对象、设计原则;Kubernetes的数据库、运行时、网络、插件已经落地经验;微服务架构、组件、监控方案等,点击下方图片查看详情。

以上是关于Istio系列学习----Istio的路由规则配置:VirtualService的主要内容,如果未能解决你的问题,请参考以下文章

在生产环境运行Istio

Istio DestinationRule 目标规则

Istio实战-路由规则配置:VirtualService

[Istio]流量管理API v1alpha3路由规则

idou老师教你学Istio05: 如何用Isito实现智能路由配置

idou老师教你学Istio05: 如何用Isito实现智能路由配置