当前位置:网站首页>10个 Istio 流量管理 最常用的例子,你知道几个?

10个 Istio 流量管理 最常用的例子,你知道几个?

2022-08-09 19:31:00 InfoQ

10 个 Istio 流量管理 最常用的例子,强烈建议
收藏
起来,以备不时之需。

为了方便理解,以Istio官方提供的Bookinfo应用示例为例,引出 Istio 流量管理的常用例子。

Bookinfo应用的架构图如下:

null
其中,包含四个单独的微服务:

  • productpage
    :调用 
    details
     和 
    reviews
     两个服务,用来生成页面。
  • details
    :包含了书籍的信息。
  • reviews
    :包含了书籍相关的评论。它还会调用 ratings 微服务。
  • rating
    :包含了由书籍评价组成的评级信息。

其中,
reviews
 服务有 3 个版本:

  • v1 版本不会调用 
    ratings
     服务。
  • v2 版本会调用 
    ratings
     服务,并使用 1 到 5 个
    黑色
    星形图标来显示评分信息。
  • v3 版本会调用 
    ratings
     服务,并使用 1 到 5 个
    红色
    星形图标来显示评分信息。

流量转移

目标1
:把
reviews
 服务的所有流量都路由到v1版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

目标2
:把
reviews
 服务的50%流量转移到v3版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v1
 weight: 50
 - destination:
 host: reviews
 subset: v3
 weight: 50
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

目标3
:把
reviews
 服务的所有流量都路由到v3版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v3
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

基于用户身份的路由

目标
:来自名为 OneMore 的用户的所有流量都路由到v2版本,其他流量都路由到v1版本。

Istio 对用户身份没有任何特殊的内置机制。在应用示例中,
productpage
服务在所有到 
reviews
 服务的 HTTP 请求中都增加了一个自定义的 
end-user
 请求头,其值为用户名。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - match:
 - headers:
 end-user:
 exact: OneMore
 route:
 - destination:
 host: reviews
 subset: v2
 - route:
 - destination:
 host: reviews
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

注入 HTTP 延迟故障

目标
:用户 OneMore 访问时, 
ratings
 服务注入一个 2 秒的延迟,
productpage
页面在大约 2 秒钟加载完成并且没有错误。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - match:
 - headers:
 end-user:
 exact: OneMore
 fault:
 delay:
 percentage:
 value: 100.0
 fixedDelay: 2s
 route:
 - destination:
 host: ratings
 subset: v1
 - route:
 - destination:
 host: ratings
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: ratings
spec:
 host: ratings
 subsets:
 - labels:
 version: v1
 name: v1

注入 HTTP 中止故障

目标
:用户 OneMore 访问时, 
ratings
 服务注入一个503的中止故障,
productpage
 页面能够立即被加载,同时显示 “Ratings service is currently unavailable” 这样的消息。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: ratings
spec:
 hosts:
 - ratings
 http:
 - fault:
 abort:
 httpStatus: 503
 percentage:
 value: 100
 match:
 - headers:
 end-user:
 exact: OneMore
 route:
 - destination:
 host: ratings
 subset: v1
 - route:
 - destination:
 host: ratings
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: ratings
spec:
 host: ratings
 subsets:
 - labels:
 version: v1
 name: v1

设置请求超时

首先,用户 OneMore 访问时, 
ratings
 服务注入一个 2 秒的延迟,
productpage
页面在大约 2 秒钟加载完成并且没有错误。

按照上文
注入 HTTP 延迟故障
进行操作,不再赘述。

目标
:用户 OneMore 访问时, 
reviews
 服务的请求超时设置为 1 秒,同时显示 “Sorry, product reviews are currently unavailable for this book.” 这样的消息。

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - match:
 - headers:
 end-user:
 exact: OneMore
 route:
 - destination:
 host: reviews
 subset: v2
 timeout: 1s
 - route:
 - destination:
 host: reviews
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

在Jaeger可以看到具体的调用链如下:

null

设置请求重试

首先,用户 OneMore 访问时, 
ratings
 服务注入一个 2 秒的延迟,
productpage
页面在大约 2 秒钟加载完成并且没有错误。

按照上文
注入 HTTP 延迟故障
进行操作,不再赘述。

目标
:用户 OneMore 访问时, 
reviews
 服务的请求重试次数为2次,重试超时时间为 0.5 秒,同时显示 “Sorry, product reviews are currently unavailable for this book.” 这样的错误消息。

kind: VirtualService
apiVersion: networking.istio.io/v1alpha3
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - match:
 - headers:
 end-user:
 exact: OneMore
 route:
 - destination:
 host: reviews
 subset: v2
 retries:
 attempts: 2
 perTryTimeout: 0.5s
 - route:
 - destination:
 host: reviews
 subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

拒绝目标IP的请求

目标
:除了IP为
10.201.240.131
的客户端可以访问
/api/v1/products/1
,其他客户端拒绝请求。

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: deny-by-ip
spec:
 selector:
 matchLabels:
 app: productpage
 action: DENY
 rules:
 - to:
 - operation:
 paths: ["/api/v1/products/1"]
 when:
 - key: remote.ip
 notValues: ["10.201.240.131"]

熔断

目标
:设置
details
服务的并发上限为1。

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: details
spec:
 host: details
 trafficPolicy:
 connectionPool:
 tcp:
 maxConnections: 1
 http:
 http1MaxPendingRequests: 1
 maxRequestsPerConnection: 1

可以使用 Fortio 进行负载测试,发送并发数为 2 的连接(
-c 2
),请求 20 次(
-n 2
0):

kubectl exec fortio-deploy-684b6b47f8-tzsg8 -c fortio -- /usr/bin/fortio load -c 3 -qps 0 -n 20 -loglevel Warning http://details:9080/details/0
其中,
fortio-deploy-684b6b47f8-tzsg8
是Fortio的Pod名称,效果如下:

null

流量镜像

目标
:把流量全部路由到reviews服务的 v2 版本,再把流量全部镜像到 v3 版本。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: reviews
spec:
 hosts:
 - reviews
 http:
 - route:
 - destination:
 host: reviews
 subset: v2
 mirror:
 host: reviews
 subset: v3
 mirrorPercentage:
 value: 100.0
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - labels:
 version: v1
 name: v1
 - labels:
 version: v2
 name: v2
 - labels:
 version: v3
 name: v3

执行如下命令查看
reviews
服务 v3 版本的 Envoy 访问日志:

kubectl logs -l app=reviews,version=v3 -c istio-proxy
可以看到
reviews
服务 v3 版本被调用的日志:

{
 "authority": "reviews-shadow:9080",
 "bytes_received": 0,
 "bytes_sent": 375,
 "connection_termination_details": null,
 "downstream_local_address": "10.1.1.64:9080",
 "downstream_remote_address": "10.1.1.59:0",
 "duration": 1914,
 "method": "GET",
 "path": "/reviews/0",
 "protocol": "HTTP/1.1",
 "request_id": "b79cefe6-1277-9c39-b398-f94a704840cc",
 "requested_server_name": "outbound_.9080_.v3_.reviews.default.svc.cluster.local",
 "response_code": 200,
 "response_code_details": "via_upstream",
 "response_flags": "-",
 "route_name": "default",
 "start_time": "2022-06-27T07:34:19.129Z",
 "upstream_cluster": "inbound|9080||",
 "upstream_host": "10.1.1.64:9080",
 "upstream_local_address": "127.0.0.6:59837",
 "upstream_service_time": "1913",
 "upstream_transport_failure_reason": null,
 "user_agent": "curl/7.79.1",
 "x_forwarded_for": "10.1.1.59"
}

Ingress的路由

目标
:请求头
app-id
details
的所有流量都路由到
details
服务中。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
 name: bookinfo
spec:
 hosts:
 - '*'
 gateways:
 - bookinfo-gateway
 http:
 - match:
 - uri:
 exact: /productpage
 - uri:
 prefix: /static
 - uri:
 exact: /login
 - uri:
 exact: /logout
 - uri:
 prefix: /api/v1/products
 route:
 - destination:
 host: productpage
 port:
 number: 9080
 - match:
 - headers:
 app-id:
 exact: details
 route:
 - destination:
 host: details
 port:
 number: 9080

使用curl命令验证一下:

curl -H "app-id: details" -v http://127.0.0.1/details/2
返回结果如下:

* Trying 127.0.0.1:80...
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> GET /details/2 HTTP/1.1
> Host: 127.0.0.1
> User-Agent: curl/7.79.1
> Accept: */*
> app-id: details
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: application/json
< server: istio-envoy
< date: Tue, 28 Jun 2022 07:14:40 GMT
< content-length: 178
< x-envoy-upstream-service-time: 4
<

{&quot;id&quot;:2,&quot;author&quot;:&quot;William Shakespeare&quot;,&quot;year&quot;:1595,&quot;type&quot;:&quot;paperback&quot;,&quot;pages&quot;:200,&quot;publisher&quot;:&quot;PublisherA&quot;,&quot;language&quot;:&quot;English&quot;,&quot;ISBN-10&quot;:&quot;1234567890&quot;,&quot;ISBN-13&quot;:&quot;123-1234567890&quot;}

* Connection #0 to host 127.0.0.1 left intact

返回结果可以看出,访问的是
details
服务。

最后,感谢你这么帅,还给我
点赞
原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/a236906d997ebdec9835d1aa6