更多相关文章
一、DestinationRule CR资源规范
二、DestinationRule配置要点
- DestinationRule用于配置路由完成之后的应用于服务的流量策略,即配置如何将流量调度至上游端点,同时也是为 VirtualService的Destination指定的目标提供具体的定义和实现;主要包括以下配置项:
- 负载均衡配置
- Sidecar连接池
- 异常值检测相关的配置,即异常端点驱逐机制
- DestinationRule的关键字段 :
- host : 必选字段,指定规则适用对象,可以使用短域名;可用值是在服务注册中心注册的服务名,即网格内的服务或者是以 ServiceEntry注册的网格外的服务;
- trafficPolicy : 具体的规则内容,包括负载均衡、连接池策略和异常值检测;
- subsets : 服务的子集定义,通常一个子集用于定义一个服务版本;
- exportTo : 用于控制DestinationRule 扩名称空间的可见性,即控制一个名称空间下定义的 DestinationRule 资源对象是否可被其他名称空间下的Sidecar执行;
- “.” : 表示仅应用于当前名称空间;
- “*” : 表示应用于所有名称空间;
- Subset : 服务子集
- name : 子集名称
- labels : 子集上的标签
- trafficPolicy : 应用于当前子集的流量策略
TrafficPolicy 主要包括如下几项重要配置
- loadBalancer : 定义使用的负载均衡器,即负载均衡算法;
- 简单负载均衡 : ROUND_ROBIN、LEAST_CONN、RANDON和PASSTHROUTH ;
- 一致性哈希 : consistentHash 仅对 HTTP 协议有效,它支持基于 httpHeaderName、httpCookie、useSourelp进行hash计算,并能够通过 minimumRingSize 指定Hash环大小;
- outlierDetection : 异常值检测;
- consecutiveErrors:实例被驱逐前的连续错误次数和,默认值为5;
- interval:驱逐的时间间隔,默认值为10秒,支持以时、分、秒和毫秒为单位;
- baseEjectionTime:基准驱逐时长,具体时长取决于退避算法;
- maxEjectionPercent:可被驱逐的最大实例比例,默认为10%;
- minHealthPercent:启用异常值检测时要满足的最小健康状态实例比例,小于此比例,异常值检测将被禁用;默认为50%;
- connectionPool : 连接池配置;
- TCP 连接池配置 :
- maxConnections : 为上游服务的所有实例建立的最大连接数,默认为 1024;
- connectTimeout : TCP 连接超时时长;对于HTTP协议而言,仅适用于HTTP/1;
- tcpKeepalive : TCP keepalives 机制,通过定期给发送一个 keepalive 探测报文来判断连接是否可用;
- HTTP 连接池配置 :
- httpMaxPendingRequests : 允许挂起的最大HTTP请求数,默认为1024,仅适用于HTTP/1.1;
- http2MaxRequests : 允许的HTTP/2 最大请求数,默认为1024;HTTP/1.1 的由maxConnections设置即能实现;
- maxRequestsPerConnection : 每连接的最大请求数,默认为无限制,而1则表示禁用 Keep-alive;
- maxRetries : 最大重试次数,默认为3;
- idleTimeout : 空闲超时时长;
- TCP 连接池配置 :
- PortTrafficPolicy : 流量策略要应用的目标端口;
三、DestinationRule配置生效示意图
四、DestinationRule配置示例
4.1、CircuitBreaker - TrafficPolicy 负载均衡策略
1、使用以下 DestinationRule 定义对访问demoapp 的负载均衡策略
# cat destinationrule-demoapp.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: demoapp
spec:
# 主机 :对demoapp service 服务的访问
host: demoapp
# 全局负载均衡策略
trafficPolicy:
# 负载均衡策略
loadBalancer:
# 加权最少连接
simple: LEAST_CONN
# 子集
subsets:
# 名为 v10 的子集
- name: v10
labels:
version: v1.0
# v10 子集的负载均衡策略
trafficPolicy:
# 负载均衡策略
loadBalancer:
# 一致性哈希
consistentHash:
# 如果请求标头有 X-User 标头,如果 X-User标头值一样都将调度到同一个后端Pod,不一样的值则被重新调度
httpHeaderName: X-User
# 名为 v11 的子集
- name: v11
labels:
version: v1.1
# v11 子集并未定义负载均衡策略则继承全局负载均衡策略
# kubectl apply -f destinationrule-demoapp.yaml
destinationrule.networking.istio.io/demoapp configured
# kubectl get destinationrule
NAME HOST AGE
demoapp demoapp 6d16h
# 取出 ingress-gateway pod名称方便后续使用
# InGW=$(kubectl get pods -n istio-system -l app=istio-ingressgateway -o jsonpath={.items[0].metadata.name})
root@native01:~# echo $InGW
istio-ingressgateway-78f69bd5db-ln5vv
2、生效回此前定义的 virtualservice 路由策略
# cat 03-demoapp-subset/virutalservice-demoapp.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: demoapp
spec:
hosts:
- demoapp
http:
- name: canary
match:
- uri:
prefix: /canary
rewrite:
uri: /
route:
- destination:
host: demoapp
subset: v11
- name: default
route:
- destination:
host: demoapp
subset: v10
# kubectl apply -f 03-demoapp-subset/virutalservice-demoapp.yaml
virtualservice.networking.istio.io/demoapp configured
3、集群内直接使用 client直接对demoapp 进行访问测试
# kubectl run client --image=registry.cn-wulanchabu.aliyuncs.com/daizhe/admin-box -it --rm --restart=Never --command -- /bin/sh
If you don t see a command prompt, try pressing enter.
# 请求/canary 调度给 demoapp v11 子集,走 DestinationRule 全局负载均衡策略 -> 加权最少连接
root@client # curl demoapp:8080/canary
iKubernetes demoapp v1.1 !! ClientIP: 127.0.0.6, ServerName: demoappv11-7984f579f5-7nlrr, ServerIP: 10.220.104.143!
root@client # curl demoapp:8080/canary
iKubernetes demoapp v1.1 !! ClientIP: 127.0.0.6, ServerName: demoappv11-7984f579f5-ttfv9, ServerIP: 10.220.104.133!
# 请求 / 调度给 demoapp v10 子集,走 DestinationRule v10 子集 负载均衡策略 -> 一致性哈希
root@client # curl -H "X-User: user" demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-rvbwc, ServerIP: 10.220.104.147!
root@client # curl -H "X-User: user" demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-rvbwc, ServerIP: 10.220.104.147!
root@client # curl -H "X-User: user" demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-rvbwc, ServerIP: 10.220.104.147!
root@client #
root@client # curl -H "X-User: name" demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-4sr86, ServerIP: 10.220.104.145!
root@client # curl -H "X-User: name" demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-4sr86, ServerIP: 10.220.104.145!
root@client # curl -H "X-User: name" demoapp:8080
iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-4sr86, ServerIP: 10.220.104.145!
4.2、CircuitBreaker-TrafficPolicy-connectionPool 连接池配置
1、定义 VirtualService
# cat virutalservice-demoapp.yaml
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: demoapp
spec:
hosts:
- demoapp
http:
- name: canary
match:
- uri:
prefix: /canary
rewrite:
uri: /
route:
- destination:
host: demoapp
subset: v11
- name: default
route:
- destination:
host: demoapp
subset: v10
2、定义 DestinationRule
# cat destinationrule-demoapp.yaml
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: demoapp
spec:
host: demoapp
trafficPolicy:
loadBalancer:
simple: RANDOM
connectionPool:
tcp:
maxConnections: 100
connectTimeout: 30ms
tcpKeepalive:
time: 7200s
interval: 75s
http:
http2MaxRequests: 1000
maxRequestsPerConnection: 10
# 异常值检测
outlierDetection:
# 最大弹出比例 50%
maxEjectionPercent: 50
# 连续的 5xx 错误超过 5次 就开始弹出主机
consecutive5xxErrors: 5
# 检测时间间隔为 2分钟
interval: 2m
# 弹出的基准时长 1分钟
baseEjectionTime: 1m
# 健康主机小于 40% 时禁用弹出功能
minHealthPercent: 40
subsets:
- name: v10
labels:
version: v1.0
- name: v11
labels:
version: v1.1
# kubectl apply -f destinationrule-demoapp.yaml
destinationrule.networking.istio.io/demoapp configured
3、验证访问测试
# kubectl run client --image=registry.cn-wulanchabu.aliyuncs.com/daizhe/admin-box -it --rm --restart=Never --command -- /bin/sh
root@client /# while true; do curl proxy; sleep 0.$RANDOM; done
Proxying value: iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-4sr86, ServerIP: 10.220.104.145!
- Took 296 milliseconds.
Proxying value: iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-h7nw6, ServerIP: 10.220.104.129!
- Took 23 milliseconds.
Proxying value: iKubernetes demoapp v1.0 !! ClientIP: 127.0.0.6, ServerName: demoappv10-5c497c6f7c-4sr86, ServerIP: 10.220.104.145!
- Took 4 milliseconds.
# 外部访问测试
daizhe@localhost ~ % while true; do curl http://fe.toptops.top:52212/canary ; sleep 0.$RANDOM; done
Proxying value: iKubernetes demoapp v1.1 !! ClientIP: 127.0.0.6, ServerName: demoappv11-7984f579f5-ttfv9, ServerIP: 10.220.104.133!
- Took 20 milliseconds.
Proxying value: iKubernetes demoapp v1.1 !! ClientIP: 127.0.0.6, ServerName: demoappv11-7984f579f5-ttfv9, ServerIP: 10.220.104.133!
- Took 4 milliseconds.