istio系列:第二章-流量路由转发配置详解

VirtualService

VirtualService定义了对特定目标服务的一组流量规则。如其名字所示,VirtualService在形式上表示一个虚拟服务,将满足条件的流量都转发到对应的服务后端,这个服务后端可以是一个服务,也可以是在DestinationRule中定义的服务的子集。

下面是VirtualService.yaml对应的结构体

type VirtualService struct {
   Hosts []string `protobuf:"bytes,1,rep,name=hosts,proto3" json:"hosts,omitempty"`
   Gateways []string `protobuf:"bytes,2,rep,name=gateways,proto3" json:"gateways,omitempty"`
   Http []*HTTPRoute `protobuf:"bytes,3,rep,name=http,proto3" json:"http,omitempty"`
   Tls []*TLSRoute `protobuf:"bytes,5,rep,name=tls,proto3" json:"tls,omitempty"`
   Tcp []*TCPRoute `protobuf:"bytes,4,rep,name=tcp,proto3" json:"tcp,omitempty"`
   ExportTo []string `protobuf:"bytes,6,rep,name=export_to,json=exportTo,proto3" json:"export_to,omitempty"`
}

接下来让我们细细讲解每个属性的作用

Hosts

标明目的地址,可以是IP、DNS也可以是短域名、服务名(仅用于k8s) 例如reviews(短域名)、reviews.default.svc.cluster.local。对于短域名来说,VirtualService会自动添加后面的服务信息,比如添加命名空间。

注意:VirtualService 的 hosts 的短域名填充到的完整域名时,补齐的 Namespace 是VirtualService的Namespace,而不是Service的Namespace。

Gateways

Gateways表示应用这些流量规则的 Gateway。VirtualService 描述的规则可以作用到网格里的Sidecar 和入口处的 Gateway,表示将路由规则应用于网格内的访问还是网格外经过Gateway的访问。其使用方式有点绕,需要注意以下场景。

  • 场景1:服务只是在网格内访问的,这是最主要的场景。gateways字段可以省略,实际上在VirtualService的定义中都不会出现这个字段。一切都很正常,定义的规则作用到网格内的Sidecar。

  • 场景2:服务只是在网格外访问的。配置要关联的Gateway,表示对应Gateway进来的流量执行在这个VirtualService上定义的流量规则。

  • 场景3:在服务网格内和网格外都需要访问。这里要给这个数组字段至少写两个元素,一个是外部访问的Gateway,另一个是保留关键字“mesh”。使用中的常见问题是忘了配置“mesh”这个常量而导致错误。我们很容易认为场景 3是场景 1和场景2的叠加,只需在内部访问的基础上添加一个可用于外部访问的Gateway。

Http

一个与 HTTPRoute 类似的路由集合,用于处理 HTTP 的流量,是 Istio中内容最丰富的一种流量规则。

type HTTPRoute struct {
   Name string `protobuf:"bytes,17,opt,name=name,proto3" json:"name,omitempty"`
   Match []*HTTPMatchRequest `protobuf:"bytes,1,rep,name=match,proto3" json:"match,omitempty"`
   Route []*HTTPRouteDestination `protobuf:"bytes,2,rep,name=route,proto3" json:"route,omitempty"`
   Redirect *HTTPRedirect `protobuf:"bytes,3,opt,name=redirect,proto3" json:"redirect,omitempty"`
   Delegate *Delegate `protobuf:"bytes,20,opt,name=delegate,proto3" json:"delegate,omitempty"`
   Rewrite *HTTPRewrite `protobuf:"bytes,4,opt,name=rewrite,proto3" json:"rewrite,omitempty"`
   Timeout *duration.Duration `protobuf:"bytes,6,opt,name=timeout,proto3" json:"timeout,omitempty"`
   Retries *HTTPRetry `protobuf:"bytes,7,opt,name=retries,proto3" json:"retries,omitempty"`
   Fault *HTTPFaultInjection `protobuf:"bytes,8,opt,name=fault,proto3" json:"fault,omitempty"`
   Mirror *Destination `protobuf:"bytes,9,opt,name=mirror,proto3" json:"mirror,omitempty"`
   MirrorPercent *wrappers.UInt32Value `protobuf:"bytes,18,opt,name=mirror_percent,json=mirrorPercent,proto3" json:"mirror_percent,omitempty"`
   MirrorPercentage *Percent `protobuf:"bytes,19,opt,name=mirror_percentage,json=mirrorPercentage,proto3" json:"mirror_percentage,omitempty"`
   CorsPolicy *CorsPolicy `protobuf:"bytes,10,opt,name=cors_policy,json=corsPolicy,proto3" json:"cors_policy,omitempty"`
   Headers *Headers `protobuf:"bytes,16,opt,name=headers,proto3" json:"headers,omitempty"`
}

下面让我们一一分析

Name

name 提供了当前规则的一个名称

Route

满足 HTTPMatchRequest 条件的流量都被路由到HTTPRouteDestination,执行重定向(HTTPRedirect)、重写(HTTPRewrite)、重试(HTTPRetry)、故障注入(HTTPFaultInjection)、跨站(CorsPolicy)策略等。

type HTTPRouteDestination struct {
   // 目的地
   Destination *Destination `protobuf:"bytes,1,opt,name=destination,proto3" json:"destination,omitempty"`
   // 要转发到目的地的流量的相对比例。 目的地将收到“权重/(所有权重之和)”请求。多个Destination的权重和要求为100
   Weight int32 `protobuf:"varint,2,opt,name=weight,proto3" json:"weight,omitempty"`
   // 修改一次请求或响应header信息
   Headers *Headers `protobuf:"bytes,7,opt,name=headers,proto3" json:"headers,omitempty"`
}

type Destination struct {
    // DestinationRule名称
	Host string `protobuf:"bytes,1,opt,name=host,proto3" json:"host,omitempty"`
 	// 服务中子集的名称。由DestinationRule定义
	Subset string `protobuf:"bytes,2,opt,name=subset,proto3" json:"subset,omitempty"`
    // 指定端口号
	Port *PortSelector `protobuf:"bytes,3,opt,name=port,proto3" json:"port,omitempty"`
}
Match

匹配规则,为一个HTTPMatchRequest类型的数组,表示HTTP请求满足的条件,支持将HTTP属性如uri、scheme、method、authority、port 等作为条件来匹配请求。

type HTTPMatchRequest struct {
  // 请求匹配的名称
   Name string 
  // 下面4个字段都是StringMatch类型,
  //在匹配请求时都支持exact、prefix和regex三种模式的匹配
  //分别表示完全匹配输入的字符串,前缀方式匹配和正则表达式匹配
   Uri *StringMatch 
  // For example, `http` or `https`.
   Scheme *StringMatch 
   Method *StringMatch 
   Authority *StringMatch 
  // 对于header头的每个字段都可以用完全、前缀、正则来判断
   Headers map[string]*StringMatch 
  // 请求的port 当服务都只开启一个port时不用指定
   Port uint32
  // 表示请求来源的负载匹配标签
  // 在很多时候非常有用,可以对一组服务都打一个相同的标签
  // 然后使用sourceLabels字段对这些服务实施相同的流量规则。
   SourceLabels map[string]string 
  // 表示规则应用的Gateway名称
  // 语义同VirtualService上面的gateways定义
  // 是一个更细的Match条件,会覆盖在VirtualService上配置的gateways
   Gateways []string 
  // 根据查询参数进行匹配
  // 比如请求url中有?name=123
  // 那么我们可以配置name为key值,exact = 123为value
   QueryParams map[string]*StringMatch
  // 指定匹配时是否忽略大小写
  // 只有在 `exact` 和 `prefix` 的情况下才会有用
   IgnoreUriCase bool
  // 是上面headers取反的意思,不存在...
   WithoutHeaders map[string]*StringMatch
  // 资源命名空间
   SourceNamespace string
}

注意:在HTTPRoute的匹配条件中,每个HTTPMatchRequest中的诸多属性都是“与”逻辑,几个元素间的关系是“或”逻辑

比如 下面的配置,在匹配时会根据请求的url判断前缀是否为www.lisi.com/aa或www.zhangsan.com/bb而url与header为与的关系。

MatchRequest:
- match:
  - url:
     prefix: "www.lisi.com/aa"
    url:
     prefix: "www.zhangsan.com/bb"
  - header:
  	 source:
  	   exact: north
Redirect

请求req在重定向时对req头进行了改变。

type HTTPRedirect struct {
  // 用该uri替换请求的uri
   Uri string
  // 替换请求的权限
   Authority string
  // 替换请求的端口
   RedirectPort isHTTPRedirect_RedirectPort 
  // 替换请求的传输协议,比如http或https
   Scheme string
  // 替换重定向code,默认是301
   RedirectCode uint32
}
Delegate

委托用于指定特定的VirtualService

只有当Route和Redirect为空时才可以设置并且路由委托 VirtualService 的规则

  1. 仅支持一级委托。
  2. 委托的 HTTPMatchRequest 必须是根的严格子集,否则会发生冲突,HTTPRoute 不会生效。
type Delegate struct {
   Name string 
   Namespace string 
}
Rewrite

重写 HTTP URI 和授权标头。 重写不能与重定向一起使用。 转发前会进行重写。

type HTTPRewrite struct {
   Uri string 
   Authority string 
}

URI会根据原本设置的匹配规则(前缀匹配等)更改前缀字符串,这是与重定向一个区别(重定向是重写整个url)

Timeout

HTTP 请求超时,默认禁用。

Retries

HTTP 请求的重试策略。

type HTTPRetry struct {
   //运行重试的次数
   Attempts int32 
   //每次尝试的超时时间
   PerTryTimeout *duration.Duration 
   //重试发生的条件
   // See the [retry policies](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-on)
   // and [gRPC retry policies](https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/router_filter#x-envoy-retry-grpc-on) for more details.
   RetryOn string 
   //用于指定重试是否应在其他位置重试的标志
  //(https://www.envoyproxy.io/docs/envoy/latest/intro/arch_overview/http/http_connection_management#retry-plugin-configuration) for more details.
   RetryRemoteLocalities *wrappers.BoolValue 
}
CorsPolicy

跨域资源共享策略 (CORS)

Headers

修改一次请求或响应header信息

Tls

tls 是一种 TLSRoute 类型的路由集合,用于处理非终结的 TLS和HTTPS的流量,使用SNI(Server Name Indication,客户端在TLS握手阶段建立连接使用的服务Hostname)做路由选择

type TLSRoute struct {
  // 匹配规则
   Match []*TLSMatchAttributes 
  // 路由配置 前面已经讲解过用法
   Route []*RouteDestination 
}

type TLSMatchAttributes struct {
	// SNI地址
	SniHosts []string 
    // 关于子网配置 例如,a.b.c.d/xx
	DestinationSubnets []string 
	// 端口绑定
	Port uint32
	// 资源标签
	SourceLabels map[string]string 
	// Gateways名称
	Gateways []string 
	// 命名空间
	SourceNamespace string
}

Tcp

不满足以上HTTP和TLS条件的流量都会应用本节要介绍的TCP流量规则

type TCPRoute struct {
  // 匹配规则
   Match []*L4MatchAttributes 
  // 路由配置 前面已经讲解过用法
   Route []*RouteDestination 
}

type L4MatchAttributes struct {
	// 请求ip地址
	DestinationSubnets []string 
	// 请求端口号
	Port uint32 
	// 关于子网配置 例如,a.b.c.d/xx
	SourceSubnet string `protobuf:"bytes,3,opt,name=source_subnet,json=sourceSubnet,proto3" json:"source_subnet,omitempty"`
	// 资源label前面已经讲解过
	SourceLabels map[string]string
	// gatway名称
	Gateways []string
	// 命名空间
	SourceNamespace string
}

ExportTo

如果没有指定,该配置可以供所有命名空间使用,如果是. 则只允许本命名空间使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值