10个 Istio 流量管理 最常用的例子,你知道几个?
Posted 万猫学社
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了10个 Istio 流量管理 最常用的例子,你知道几个?相关的知识,希望对你有一定的参考价值。
10 个 Istio 流量管理 最常用的例子,强烈建议收藏起来,以备不时之需。
为了方便理解,以Istio官方提供的Bookinfo应用示例为例,引出 Istio 流量管理的常用例子。
Bookinfo应用的架构图如下:
其中,包含四个单独的微服务:
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
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
基于用户身份的路由
目标:来自名为 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
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
注入 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
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
注入 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
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
设置请求超时
首先,用户 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可以看到具体的调用链如下:
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
设置请求重试
首先,用户 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
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
拒绝目标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"]
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
熔断
目标:设置
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名称,效果如下:
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
流量镜像
目标:把流量全部路由到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"
文章持续更新,微信搜索「万猫学社」第一时间阅读,关注后回复「电子书」,免费获取12本Java必读技术书籍。
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
<
"id":2,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"
* Connection #0 to host 127.0.0.1 left intact
返回结果可以看出,访问的是details
服务。
最后,感谢你这么帅,还给我点赞。
微信公众号:万猫学社
微信扫描二维码
关注后回复「电子书」
获取12本Java必读技术书籍
出处:http://www.cnblogs.com/heihaozi/
版权声明:本文遵循 CC 4.0 BY-NC-SA 版权协议,转载请附上原文出处链接和本声明。
微信扫描二维码,关注万猫学社,回复「电子书」,免费获取12本Java必读技术书籍。
Istio流量管理实践之: 基于Istio实现流量对比分析
流量镜像
流量镜像,也称为影子流量,流量镜像提供一种尽可能低的风险为生产带来变化的强大功能。镜像会将实时流量的副本发送到镜像服务。镜像流量发生在主服务的关键请求路径之外。
在非生产或者测试环境中,尝试访问一个服务所有可能的测试用例组合是个非常不现实的任务。 在某些情况下,编写这些用例的所有工作也可能与实际生产所需的用例不匹配。在理想情况下,可以使用实时的生产用例和流量来帮助完善在测试环境中错过的功能区域。
一旦我们能够可靠地镜像流量,就可以开始做一些有价值的事情,例如通过请求流量对比工具Diffy,可以将引入测试集群的流量与生产集群中的预期行为进行比较。例如,我们可能想比较请求结果与预期结果间的偏差,或是API协议中的数据损坏情况,以便更好地兼容。
除此之外,需要注意:
当流量镜像到不同的服务时,会发生在请求的关键路径之外;
忽略对任何镜像流量的响应; 流量被视为“即发即忘”;
流量对比
此处,插入一个代理就可以负责此类流量的协调,并对其进行有趣的比较。Diffy就是一款这样的代理工具。Diffy启动一个代理服务(例如监听端口8880),再根据用户设置的primary、secondary两个旧服务地址(primary和secondary代码完全相同,目的是为了减少噪音干扰)、candidate新服务地址。
它还能够检测结果中的噪音,并通过先调用两个实时服务的实例来忽略它们(例如时间戳,单调递增计数器等提示),总结来说就是检测,然后在测试服务中忽略掉这部分。
Diffy还提供了一个不错的页面可以用来查看调用结果、对比情况、和基于某些特征的过滤。它还有一个很好的管理控制台,可以查看有关调用比较结果的功能指标(metrics)和统计数据(statistics)。
创建用于Istio流量镜像的服务
在此任务中,将首先强制所有流量到 v1 版本的服务。然后,将使用规则将一部分流量镜像到 v2版本。
首先部署两个版本的示例服务。
版本1的部署使用了Docker镜像httpbin,提供常见的http请求访问:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mirrorservice-sample-v1
spec:
replicas: 1
template:
metadata:
labels:
app: mirrorservice-sample
version: v1
spec:
containers:
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: mirrorservice-sample
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:44134", "httpbin:app"]
ports:- containerPort: 44134
版本2的部署使用了自定义的Docker镜像,对应的Dockerfile如下:
- containerPort: 44134
FROM nginx:latest
COPY default.conf /etc/nginx/conf.d/
EXPOSE 80
所需的nginx 配置文件:
server {
listen 44134;
server_name localhost;
location / {
proxy_pass http://httpbin-diffy.diffy:8880/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
版本2的部署作为Istio的流量镜像目标,在接收到流量之后会转发到Diffy的代理中。当前没有直接将Diffy代理作为Isito流量镜像目标,原因是Diffy代理与Envoy代理目前本身有冲突,无法正常流量转发,因此需要此部署中转一下。
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: mirrorservice-sample-v2
spec:
replicas: 1
template:
metadata:
labels:
app: mirrorservice-sample
version: v2
spec:
containers:
- name: mirrorservice-sample
image: registry.cn-beijing.aliyuncs.com/wangxining/mirrorservice:0.1
imagePullPolicy: Always
ports:- containerPort: 44134
对应的Kubernetes service:
- containerPort: 44134
apiVersion: v1
kind: Service
metadata:
name: mirrorservice-sample
spec:
type: ClusterIP
ports:
- name: http
port: 44134
selector:
app: mirrorservice-sample
创建流量镜像的Istio策略
默认情况下,Kubernetes 在服务的两个版本之间进行负载均衡。创建如下流量镜像规则将 100% 的流量发送到 v1, 同时指定流量镜像到v2。当流量被镜像时,请求将通过其主机/授权报头发送到镜像服务附上 -shadow 。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mirrorservice-sample
spec:
host: mirrorservice-sample
subsets:
- name: v1
labels:
version: v1 - name: v2
labels:
version: v2
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: mirrorservice-sample
spec:
hosts:- mirrorservice-sample
http:
- mirrorservice-sample
- route:
- destination:
host: mirrorservice-sample
subset: v1
weight: 100
#- destination:host: mirrorservice-sample
subset: v2
weight: 0
mirror:
host: mirrorservice-sample
subset: v2
搭建Diffy用于请求流量对比
Diffy可以作为代理,截取请求并发送至所有运行的服务实例,通过对比响应结果来发现每次迭代代码中可能存在的问题。其中,Diffy上运行了三类代码实例:
- destination:
线上稳定版本:一个运行线上稳定版本代码的节点
线上稳定版本备份:同样运行了线上的稳定版本,用于消除噪音
测试版本:待上线的测试版本,用于和线上环境代码进行对比
在实际Diffy测试中,会发现大部分的接口都会有一定差异,原因是这些响应中存在了噪音,噪音可能包括:
server响应中生成的时间戳
随机生成的数字
系统服务间的有条件竞争
Diffy能够通过一定的方式,清除这类噪音,保证分析结果不被影响。
创建Diffy及示例服务
通过以下YAML创建Diffy服务:
apiVersion: v1
kind: Service
metadata:
name: httpbin-diffy
labels:
app: httpbin-diffy
spec:
ports:
- name: http-proxy
port: 8880 - name: http-admin
port: 8881 -
name: http-console
port: 8888
selector:
app: httpbin-diffyapiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: httpbin-diffy
version: v2
name: httpbin-diffy-v2
spec:
replicas: 1
selector:
matchLabels:
app: httpbin-diffy
version: v2
template:
metadata:
labels:
app: httpbin-diffy
version: v2
spec:
containers:- image: lordofthejars/diffy:1.0
imagePullPolicy: IfNotPresent
livenessProbe:
exec:
command:- curl
- localhost:8888
initialDelaySeconds: 10
periodSeconds: 60
timeoutSeconds: 1
name: httpbin-diffy
args: ["-candidate=httpbin-candidate:8080", "-master.primary=httpbin-master:8080", "-master.secondary=httpbin-master:8080", "-service.protocol=http", "-serviceName=httpbin", "-proxy.port=:8880", "-admin.port=:8881", "-http.port=:8888", "-rootUrl=‘localhost:8888‘"]
ports:- containerPort: 8888
name: http-console
protocol: TCP - containerPort: 8880
name: http-proxy
protocol: TCP - containerPort: 8881
name: http-admin
protocol: TCP
readinessProbe:
exec:
command:
- containerPort: 8888
- curl
- localhost:8888
initialDelaySeconds: 10
periodSeconds: 60
timeoutSeconds: 1
securityContext:
privileged: false
通过以下YAML创建示例所用的primary、secondary(当前示例中与primary相同)与candidate服务:
- image: lordofthejars/diffy:1.0
apiVersion: v1
kind: Service
metadata:
name: httpbin-master
labels:
app: httpbin-master
spec:
ports:
-
name: http
port: 8080
selector:
app: httpbin
version: v1apiVersion: v1
kind: Service
metadata:
name: httpbin-candidate
labels:
app: httpbin-candidate
spec:
ports: -
name: http
port: 8080
selector:
app: httpbin
version: v2apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin-v1
spec:
replicas: 1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
containers:- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:8080", "httpbin:app"]
ports:-
containerPort: 8080
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: httpbin-v2
spec:
replicas: 1
template:
metadata:
labels:
app: httpbin
version: v2
spec:
containers:
-
- image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
command: ["gunicorn", "--access-logfile", "-", "-b", "0.0.0.0:8080", "httpbin:app"]
ports:- containerPort: 8080
发送流量进行镜像验证
启动 sleep 服务,这样就可以使用 curl 来提供负载:
- containerPort: 8080
- image: docker.io/kennethreitz/httpbin
cat <<EOF | istioctl kube-inject -f - | kubectl create -f -
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: sleep
spec:
replicas: 1
template:
metadata:
labels:
app: sleep
spec:
containers:
- name: sleep
image: tutum/curl
command: ["/bin/sleep","infinity"]
imagePullPolicy: IfNotPresent
EOF
进入到SLEEP_POD, 具体POD名称根据实际赋值。
kubectl exec -it $SLEEP_POD -c sleep sh
发送流量:
curl -v http://mirrorservice-sample:44134/headers
可以查看 v1的访问日志记录,如下所示创建的请求100%指向了v1。
与此同时,查看Diffy的Web界面,可以看到创建的请求也被镜像到Diffy Proxy:
Diffy能够通过一定的方式,清除这类噪音,保证分析结果不被影响。
结论
流量镜像提供一种尽可能低的风险为生产带来变化的强大功能。镜像会将实时流量的副本发送到镜像服务,镜像流量发生在主服务的关键请求路径之外。一旦我们能够可靠地镜像流量,就可以开始做一些有价值的事情,例如通过请求流量对比工具Diffy,可以将引入测试集群的流量与生产集群中的预期行为进行比较。
支持流量镜像只是 Istio 的众多功能之一,它将使基于大型微服务的应用程序的生产部署与管理变得更加简单。欢迎大家使用阿里云上的容器服务,快速搭建微服务的开放治理平台Istio,比较简单地集成到自己项目的微服务开发中。
以上是关于10个 Istio 流量管理 最常用的例子,你知道几个?的主要内容,如果未能解决你的问题,请参考以下文章