HTTP是当前最通用、内容最丰富的协议,控制也最多,是Istio上支持最完整的一种协议。通过它除了可以根据协议的内容进行路由,还可以进行其他操作。
VirtualService中的http是一个HTTPRoute类型的路由集合,用于处理HTTP的流量。
◎ 服务的端口协议是HTTP、HTTP2、GRPC,即在服务的端口名中包含http-、http2-、grpc-等。
◎ Gateway的端口协议是HTTP、HTTP2、GRPC,或者Gateway是终结TLS,即Gateway外部是HTTPS,但内部还是HTTP。
◎ ServiceEntry的端口协议是HTTP、HTTP2、GRPC。
1.HTTPRoute规则解析
HTTPRoute的规则定义如图3-29所示。
图3-29 HTTPRoute规则定义
HTTPRoute 规则的功能是:满足 HTTPMatchRequest 条件的流量都被路由到HTTPRouteDestination,执行重定向(HTTPRedirect)、重写(HTTPRewrite)、重试到HTTPRouteDestination,执行重定向(HTTPRedirect)、重写(HTTPRewrite)、重试(HTTPRetry)、故障注入(HTTPFaultInjection)、跨站(CorsPolicy)策略等。HTTP 不仅可以做路由匹配,还可以做一些写操作来修改请求本身,如图 3-30 所示,对用户来说非常灵活。
图3-30 HTTPRoute规则
2.HTTP匹配规则(HTTPMatchRequest)
在HTTPRoute中最重要的字段是条件字段match,为一个HTTPMatchRequest类型的数组,表示HTTP请求满足的条件,支持将HTTP属性如uri、scheme、method、authority、port 等作为条示HTTP请求满足的条件,支持将HTTP属性如uri、scheme、method、authority、port 等作为条件来匹配请求。一个 URI 的完整格式是:URI=scheme:[//authority]path [?query][#fragment],如图3-31所示。
图3-31 URI的完整格式
Authority的定义与 Host的定义容易混淆,都是类似于“weather.com”这样的服务主机名,两者有什么差别呢?
实际上,Authority的标准定义是:“authority=[userinfo@]host[:port]”,如图3-32所示。
图3-32 Authority的标准定义
下面讲讲Authority标准定义中的字段。
(1)uri、scheme、method、authority:4个字段都是StringMatch类型,在匹配请求时都支持exact、prefix和regex三种模式的匹配,分别表示完全匹配输入的字符串,前缀方式匹配和正则表达式匹配。
(2)headers:匹配请求中的Header,是一个Map类型。Map的Key是字符串类型,Value 仍然是 StringMatch 类型。即对于每一个 Header 的值,都可以使用精确、前缀和正则三种方式进行匹配。如下所示为自定义headers中source的取值为“north”,并且uri以“/advertisement”开头的请求:
- match:
- headers:
source:
exact: north
uri:
prefix: "/advertisement/"
(3)port:表示请求的服务端口。大部分服务只开放了一个端口,这也是在微服务实践中推荐的做法,在这种场景下可以不用指定port。
(4)sourceLabels:是一个 map 类型的键值对,表示请求来源的负载匹配标签。这在很多时候非常有用,可以对一组服务都打一个相同的标签,然后使用sourceLabels字段对这些服务实施相同的流量规则。在Kubernetes平台上,这里的Label就是Pod上的标签。
http:
- match:
- sourceLables:
app: frontend
version: v2
(5)gateways:表示规则应用的Gateway名称,语义同VirtualService上面的gateways定义,是一个更细的Match条件,会覆盖在VirtualService上配置的gateways。
注意:在HTTPRoute的匹配条件中,每个HTTPMatchRequest中的诸多属性都是“与”逻辑,几个元素间的关系是“或”逻辑。
需要注意的是,在VirtualService中match字段都是数组类型。HTTPMatchRequest中的诸多属性如uri、headers、method等是“与”逻辑,而数组中几个元素间的关系是“或”逻辑。
在下面的示例中,match包含两个HTTPMatchRequest元素,其条件的语义是:headers中的source取值为“north”,并且uri以“/advertisement”开头的请求,或者uri以“/forecast”开头的请求。
- match:
- headers:
source:
exact: north
uri:
prefix: "/advertisement/"
- uri:
prefix: "/forecast/"
3.HTTP路由目标(HTTPRouteDestination)
HTTPRoute上的route字段是一个HTTPRouteDestination类型的数组,表示满足条件的流量目标。在上节forecast服务的VirtualService例子中,在http规则上定义了两个HTTPRoute类型的元素,每个HTTPRoute都有一个route字段表示两个请求路由,差别是第1个路由有个match的匹配条件,第2个路由没有匹配条件,只有路由目标。满足匹配条件的流量走到v2版本的目标,剩下所有的流量走v1版本,这也是在灰度发布实践中根据条件从原有流量中切一部分流量给灰度版本的惯用做法。
本节通过HTTPRouteDestination的定义了解怎样描述这个路由目标:
http:
- match:
- headers:
source:
exact: north
route:
- destination:
host: forecast
subset: v2
- route:
- destination:
host: forecast
subset: v1
在HTTPRouteDestination中主要有三个字段:destination(请求目标)、weight(权重)和headers(HTTP头操作),destination和weight是必选字段。
1)destination
核心字段 destination 表示请求的目标。在 VirtualService 上执行一组规则,最终的流量要被送到这个目标上。这个字段是一个Destination类型的结构,通过host、subset和port三个属性来描述。
host 是 Destination 的必选字段,表示在 Istio 中注册的服务名,不但包括网格内的服务,也包括通过ServiceEntry方式注册的外部服务。在Kubernetes平台上如果用到短域名,Istio 就会根据规则的命名空间解析服务名,而不是根据 Service 的命名空间来解析。所以在使用上建议写全域名,这和VirtualService上的hosts用法类似。
还是以本节的配置示例来说明:
.....
namespace: weather
.....
spec:
hosts:
- forecast
http:
route:
- destination:
host: forecast # 服务全名为 forecast.weather.svc.cluster.local
subset: v2
- route:
- destination:
host: forecast
subset: v1
如果在这个 VirtualService 上没有写 namespace,则后端地址会是 forecast.default.svc.cluster.local。建议通过如下方式写服务的全名,即不管规则在哪个命名空间下,后端地址总是明确的:
http:
route:
- destination:
host: forecast.weather.svc.cluster.local
subset: v2
- route:
- destination:
host: forecast.weather.svc.cluster.local
subset: v1
与host配合来表示流量路由后端的是另一个重要字段subset,它表示在host上定义的一个子集。例如,在灰度发布中将版本定义为subset,配置路由策略会将流量转发到不同版本的subset上。
3)headers
在Istio 1.0中,HTTPRoute和TCPRoute共用一个Destination的定义DestinationWeight,其结构与Istio 1.1中的RouteDestination基本类似,包括destination和weight两个字段。但 HTTPRouteDestination 在普通的 RouteDestination 上多出来一个 HTTP 特有的字段headers。
headers 字段提供了对 HTTP Header 的一种操作机制,可以修改一次 HTTP 请求中Request或者Response的值,包含request和response两个字段。
◎ request:表示在发请求给目标地址时修改Request的Header。
◎ response:表示在返回应答时修改Response的Header。
对应的类型都是HeaderOperations类型,使用set、add、remove字段来定义对Header的操作。
◎ set:使用map上的Key和Value覆盖Request或者Response中对应的Header。
◎ add:追加map上的Key和Value到原有Header。
◎ remove:删除在列表中指定的Header。
以上分别介绍了 HTTP 请求匹配条件的定义和 HTTP 目标路由的定义,这也是HTTPRoute的主要功能。Istio对于HTTP除了可以做流量的路由,还可以做适当的其他操作,很多原来需要在代码里进行的 HTTP 操作,在使用 Istio 后通过这些配置都可以达到同样的效果,下面分别进行讲解。
未完待续0.0.................................