流量管理
通过配置路由调整服务之间的流量,支持AB测试,金丝雀测试和流量百分比分发,支持断路器,超时和重试。
流量管理 的API 资源包括:
- virtual service 虚拟服务
- Destination rules
- gateway
- service entries
- sidecars
1.1 virtual service
virtual service 和 Destination rules 是Istio 流量路由功能的关键构件。它基于istio平台的连接和发现,通过virtual service配置如何将请求路由到 Istio 服务网格中的微服务。
如果没有它,默认使用Envoy的轮循模型在每个服务的负载平衡池中分配流量,即轮流向每个池成员发送请求。这种分发方式,缺少一定灵活性,比如无法实现AB测试的百分比流量分发。
VS,使得请求和工作负载强分离。并处于二者之间的中间地位,实现请求到后端的流量控制。
代码语言:txt复制apiVersion: networking.istio.io/v1alpha3
kind: VirtualService #api的资源类型
metadata:
name: reviews #虚拟服务的名称
spec:
hosts: # 虚拟服务的主机
- reviews
http: # HTTP 流量路由规则的有序列表,支持http1.1 http2,grpc
- match: # 匹配条件
- headers: #匹配指定header字段值的请求量,支持前缀匹配,精确匹配和正则表达式匹配
end-user:
exact: jason
route: # 路由规则
- destination: # 目的地的主机必须是 Istio 服务注册中心中的真实目的地
host: reviews
subset: v2
- uri: # 基于uri的匹配请求
prefix: /reviews #前缀匹配
route: # 匹配的uri请求转发目的地
- destination:
host: reviews
- route: # 默认转发
- destination:
host: reviews
subset: v3
基于百分比的分发
代码语言:txt复制spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 75 # reviews:v1承载75%的流量
- destination:
host: reviews
subset: v2
weight: 25 # reviews:v2承载25%的流量
路由规则按从上到下的顺序进行计算,逐个匹配,第一个匹配则终止。如果没有匹配规则,则转发到默认规则上,否则丢弃。
VS支持http,tls,tcp的流量控制。同时通过exportto配置支持跨命名空间边界的虚拟服务的可见性。如果没有指定名称空间,则默认情况下将虚拟服务导出到所有名称空间。目前只支持当前和所有。可以配置指定应用这些路由的网关和边车的名称。
一个配置示例(只做示例,配置不一定合理):
代码语言:txt复制---
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http: #http/grpc流量
- timeout: 5s # Envoy等待服务的答复的时间,默认15s
- name: reviews-v2-routes
match:
- sourceLabels:
env: prod
- headers:
end-user:
exact: jason
- uri:
prefix: "/wpcatalog"
- uri:
exact: "/consumercatalog"
- ignoreUriCase: false
- gateways:
- test.com
rewrite: # 重写uri
uri: "/newcatalog"
redirect: # 重定向url
uri: "/v1/bookRatings"
authority: newratings.default.svc.cluster.local
route:
- destination:
host: reviews
subset: v2
retries: # Envoy 连接服务的重试, 重试之间的间隔(25ms ),由istio自动调整,防止淹没服务
attempts: 3 # 尝试最大次数
perTryTimeout: 2s #每次重试的超时时间
retryOn: gateway-error,connect-failure,refused-stream
corsPolicy: #跨域策略
allowOrigin:
- example.com
allowMethods:
- POST
- GET
allowCredentials: false
allowHeaders:
- X-Foo-Bar
exposeHeaders:
- Token
maxAge: 24h
fault: # 故障注入
abort: # 中止崩溃失败故障
percentage:
value: 0.1
httpStatus: 400
delay: #延时故障
percentage: # 每1000个对评级服务的请求中的1个引入5秒延迟
value: 0.1
fixedDelay: 5s
- name: reviews-v1-route
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v2
weight: 25
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
weight: 751
tcp: # tcp流量
- match: #端口匹配
- port: 27017
route:
- destination:
host: mongo.backup.svc.cluster.local
port:
number: 5555
tls: #https流量
- match:
- port: 443
sniHosts:
- login.bookinfo.com
route:
- destination:
host: login.prod.svc.cluster.local
- match:
- port: 443
sniHosts:
- reviews.bookinfo.com
route:
- destination:
host: reviews.prod.svc.cluster.local
其中涉及超时,重试,故障注入,http,tcp,tls流量分发配置。
Crd 的资源定义文件:istio/manifests/charts/base/crds/crd-all.gen.yaml,官方有更详细的http流量配置说明,以及VS API资源。
1.2 Destination rules
虚拟服务看作是如何将流量路由到给定目的地,然后使用目的地规则来配置该目的地的流量发生的情况。它定义了在路由发生后应用于服务的流量的策略。这些规则指定了负载平衡的配置、 sidecar 的连接池大小和异常检测设置,以检测并驱逐负载平衡池中不健康的主机。
支持配置负载均衡,基于哈希的一致性负载平衡,连接池,断路器,连接设置,tls证书设置
负载均衡策略包括:随机,加权,最少请求。
一个配置示例(只做示例,配置不一定合理):
代码语言:txt复制apiVersion: networking.istio.io/v1beta1
kind: DestinationRule # k8s API资源
metadata:
name: bookinfo-ratings
spec:
host: ratings.prod.svc.cluster.local
trafficPolicy: # 流量策略,包括:负载平衡策略、连接池大小、异常检测
loadBalancer: # 默认LB策略
simple: LEAST_CONN # ROUND_ROBIN-循环,LEAST_CONN-最小连接,RANDOM-随机,PASSTHROUGH-只连
portLevelSettings: # 指定端口上的LB
- port:
number: 80 # 80端口流量采用最小连接LB
loadBalancer:
simple: LEAST_CONN
- port:
number: 9080 # 9080端口流量采用轮询LB
loadBalancer:
localityLbSetting: #局部LB
distribute:
- from: us-west/zone1/* #流量来源
to:
"us-west/zone1/*": 80 # 分担80%
"us-west/zone2/*": 20 # 分担20%
- from: us-west/zone2/*
to:
"us-west/zone1/*": 20
"us-west/zone2/*": 80
failover: #故障转移或分发
- from: us-east
to: eu-west
- from: us-west
to: us-east
consistentHash: #散列LB,支持header,cookie,ip,urlquery,哈希环
httpCookie:
name: user
ttl: 0s
tls: # 客户端配置
mode: MUTUAL #DISABLE - 不用tls,SIMPLE,MUTUAL-手动设置证书,ISTIO_MUTUAL-istio生成
# mode=ISTIO_MUTUAL时,下面字段必须为空
clientCertificate: /etc/certs/myclientcert.pem
privateKey: /etc/certs/client_private_key.pem
caCertificates: /etc/certs/rootcacerts.pem
# 当设定tls时,有些证书是针对二级域名的,那么此时上面的host字段可以设置成 host: "*.foo.com"
connectionPool: # 配置连接池
tcp: # tcp 连接池
maxConnections: 100 # 最大连接数
connectTimeout: 30ms # 连接超时时间
tcpKeepalive:
time: 7200s
interval: 75s
http: # http 连接池
http2MaxRequests: 1000
maxRequestsPerConnection: 10
outlierDetection: #异常检测
consecutiveErrors: 7
interval: 5m #检测间隔每5分钟
baseEjectionTime: 15m # 它设置了每5分钟扫描一次1000个并发,网关错误超过7次,则驱逐15分钟。
# 网关错误指:HTTP的502、503或504,tcp的连接超时和连接错误/失败
maxEjectionPercent: 20 # 负载平衡池中可以弹出的上游服务的最大主机百分比。默认值为10%
minHealthPercent: 10 # 当负载平衡池中健康主机的百分比低于这个阈值时,异常检测将被禁用,默认0
subsets: # 定义命名子集,设置指定版本特定的策略
- name: testversion
labels:
version: v3
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
更多配置参考这里
1.3 Gateway
网关描述了一个负载均衡器,该负载均衡器在网格的边缘接收传入或传出的 HTTP/TCP 连接。也就是网关管理的是网格进出的流量。它应用于在网格边缘运行的独立的Envoy代理,而不是随着服务部署sidecar的 Envoy代理。后者只是服务的流量代理,而不是整个网格的。Istio 的网关资源只允许您配置第4-6层的负载平衡属性,比如要公开的端口、 TLS 设置等等。通常的使用方式是将一个VS(virtual service)绑定到网关(vs中有一Gateway配置项)。
一个配置示例(只做示例,配置不一定合理):
代码语言:txt复制apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- uk.bookinfo.com
- eu.bookinfo.com
tls:
httpsRedirect: true # sends 301 redirect for http requests
- port:
number: 443
name: https-443
protocol: HTTPS
hosts: #以下host发到443端口
- uk.bookinfo.com
- eu.bookinfo.com
tls:
mode: SIMPLE # enables HTTPS on this port
serverCertificate: /etc/certs/servercert.pem
privateKey: /etc/certs/privatekey.pem
- port:
number: 9443
name: https-9443
protocol: HTTPS
hosts:
- "bookinfo-namespace/*.bookinfo.com"
tls:
mode: SIMPLE # enables HTTPS on this port
credentialName: bookinfo-secret # fetches certs from Kubernetes secret
- port:
number: 9080
name: http-wildcard
protocol: HTTP
hosts:
- "*"
- port:
number: 2379 # to expose internal service via external port 2379
name: mongo
protocol: MONGO # 必须是以下之一:HTTP | HTTPS | GRPC | HTTP2 | MONGO | TCP | TLS
hosts:
- "*"
更多网格细节参考文档
1.4 Service entries
使用一个服务条目向 Istio 内部维护的服务注册中心添加一个条目。添加服务条目后,Envoy代理可以向服务发送流量,就好像它是您网格中的服务一样。通过配置服务条目,您可以管理运行在网格之外的服务的流量.一般不需要为 mesh 服务使用的每个外部服务添加服务条目。默认情况下,Istio 配置使者代理来传送请求到未知服务。如果想以更细粒度的方式控制外部服务的流量,考虑使用Service entries,然后配置虚拟服务和目的地规则,就像为网格中的任何其他服务配置流量一样。
代码语言:txt复制apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-dns
spec:
hosts: #访问的host
- foo.bar.com
location: MESH_EXTERNAL #位置在网格外
ports: #服务的端口和协议
- number: 80
name: http
protocol: HTTP
resolution: DNS #解析的方式DNS,意思在下面endpoints进行LB
endpoints:
- address: us.foo.bar.com
ports:
https: 8080
- address: uk.foo.bar.com
ports:
https: 9080
- address: in.foo.bar.com
ports:
https: 7080
--- #还有一种就是静态IP解析,当然也可以不指定
resolution: STATIC
endpoints:
- address: 2.2.2.2
- address: 3.3.3.3
1.5 Sidecars
Istio 配置每个特使代理来接受其相关工作负载的所有端口上的流量,并在转发流量时达到网格中的每个工作负载。但是通过sidecars可以实现
- 对特使代理接受的一组端口和协议进行微调
- 限制特使代理可以访问的服务集
用于 配置应用于特定命名空间中的所有工作负载,或者使用 workloadSelector 选择特定的工作负载
代码语言:txt复制apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default
namespace: bookinfo
spec:
egress: # bookinfo 名称空间中的所有服务配置为只能到达同一名称空间和 Istio 控制平面中运行的服务
- hosts:
- "./*"
- "istio-system/*"
总结
本文主要涉及istio的流量管理的如何使用,不涉及其具体原理的分析。原理后面再谈。