揭开服务网格~Istio Service Mesh神秘的面纱
一、写在前面
下文跟大家介绍的Istio服务网格,我去逛他们的官网(istio的需要FQ)发现,其实官方文档是真的真的好,各种概念给你讲的清清楚楚,各种实战的案例给你枚举的明明白白,让我一度有放弃写本文的打算。还写个毛,没有谁写的比官网更好、更详细,网上的各种博客,大概率也是都是对着文档抄~。
所以大家想学学istio,官方英文文档绝对是第一选择,然后在本文中,我尽量多写点自己的理解,以及介绍Istio的能力+告诉你对应的官方文档的位置~
推荐收藏-阅读原文,格式有所调整,阅读体验感更佳
推荐收藏-阅读原文,格式有所调整,阅读体验感更佳
https://mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g
https://mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g
https://mp.weixin.qq.com/s/UPQYOGZWkF9Njcv76C_v-g
推荐收藏-阅读原文,格式有所调整,阅读体验感更佳
推荐收藏-阅读原文,格式有所调整,阅读体验感更佳
二、微服务与K8S
下图中是阿里的微服务框架Dubbo的架构图,写过相关代码的同学会比较清楚Dubbo中的各个组件及其作用。
- 注册中心 保存服务名称&服务地址的映射关系,当服务地址发生变动时, 主动通知消费者。
- 服务提供者:提供服务接口的实现类,注册/暴露服务 (远程注册, 本地注册)
- 服务消费者:启动时从注册中心拉取服务提供者的地址, 缓存在本地,根据负载均衡策略选出一个服务进行远程调用
- 监控中心:统计RPC过程的细节数据, 如: 服务调用次数, 调用时间
Ps:了解更多,可以看我这篇笔记【探究Dubbo的拓展机制】
无论是阿里的Dubbo或是Spring生态中的SpringCloud微服务框架也罢,普遍存在的现象是:开发者在基础此类微服务框架开发项目时不可避免的需要构建诸如Euraka、Zuul偏网络层面的项目,以及写相关的代码。
再之后Kubernetes生态逐渐成熟,像Dubbo之类微服务的能力,如:服务发现、服务注册、负载均衡、动态水平扩展之类的能力,K8S组件其实都已经原生支持了。
就如上简图,对于K8S来说,使用者只需要提供一个容器镜像即可,它能帮我们将镜像编排/部署进Pod中,并提供了完整的将Pod暴露出去提供服务的资源对象和解决方案,而且支持全部变成语言。
对于Java应用来说,看起来开发者只需要将SpringBoot编译产出的Jar包打包进一个有JVM运行环境的Docker镜像中,再把镜像的地址告诉K8S,它便能将Java应用启动部署好对外提供服务。
这时再回头看SpringCloud那套微服务框架的又是什么Eureka、又是什么Zull、Feign等等组件,好像确实没啥存在的必要了~
当然对于一些存量的项目来讲,若是完全弃用Eureka类似的组件,在代码层面的改造成本不亚于重写~,再就是像Eureka这种组件也是可以部署进K8S中提供服务发现能力的,具体怎么搞、要不要搞,见仁见智~
三、服务网格与K8S
还是先回到这张简图,首先得肯定的是,K8S本来就是支持编排/部署、服务发现、负载均衡等一系列能力的。
然后我很直观的感觉:大家吹捧的服务网格,本质上其实是对K8S流量调度&流量治理能力的增强。
要是说:服务网格实现了将业务逻辑和网络策略的隔离,不能说不对,但不是重点,因为原生的K8S各组件已经具备这个能力了。
所以说划重点:
- K8S本身是有流量调度和流量治理能力,但是能力弱。
- 服务网络这种产品的中心思想是:流量治理,四个字,尤其是在负载调用链路治理业务场景下尤为出色。
所以其实如果你不想用什么Istio的金丝雀发布、或者是流量治理能力,完全可不不用服务网格能力。就原生的Ingress+service+deployment完全可以满足我们部署web服务的需求。
四、常见的产品
产品 | 简介 |
---|---|
Linkerd | 是一款高性能网络代理程序,标志着Service Mesh时代的开始。 |
Envoy | 有C++开发的,为云原生应用而设计,是一款高性能的网络代理 |
Istio | 底层为Envoy,是Service Mesh的典型实现 |
Kuma | 是一款基于Envoy构建的服务网络控制平面,Kuma设计的数据平面和控制平面可以极大的降低开发团队使用服务网格的难度。 |
五、Istio架构
中文版:https://istio.io/latest/zh/docs/ops/deployment/architecture/
推荐先完整的看一遍Concept篇:https://istio.io/latest/docs/concepts/traffic-management/
若是使用Istio这款服务网络产品,它会以side car的方式为我们业务Pod自动默认注入proxy容器,Proxy容器的底层是Envoy网络策略代理,由proxy统一提供网络相关能力。
在研发同学的视角来看,他只需要关注自己的业务逻辑就好~
不足之处:每个业务pod被自动注入一个用来实现网络策略的边车proxy容器,进出业务容器的流量都要流经Proxy代理,看起来多了一步,感觉会变慢。好在Proxy与业务容器在同一个Pod中可共享NetworkNamespace,通信使用本地回环网卡、网络耗时可以忽略不计。
下图是Istio的架构图:
参考这篇:https://istio.io/latest/docs/ops/deployment/architecture/
- Istio将服务网络划分成两大部分
- Control plane:控制平面,由Pilot、Citadel、Galley组成(istio1.5之前这三个组件独立为3个pod部署,1.5之后融合成istiod),负责服务发现、配置、认证,是配置进行统一的管理然后分发给不通的数据平面。
- Data plance:数据平面
- 控制平面
- Pilot:为Eonvoy提供服务发现能力,为AB测试、金丝雀发布、流量熔断、重试、超时提供流量管控能力
- Citadel:可用于升级服务网格中未加密的流量。
- Galley:配置管理,验证配置信息的正确性,经过验证后的配置才会发送给Proxy使用,使用网格配置协议(Mesh Configuration Protol)和其他组件进行配置交互。
- 每个业务Pod中都会被注入一个Proxy容器(Envoy),业务容器进出的流量都会流经proxy调度。
- 服务发现、负载均衡、服务熔断、健康检查、基于流量百分比划分的灰度发布、故障注入、丰富的度量指标
- Ingress traffic:管控入口流量。
- Egress traffic:管控出口流量。
- 东西流量:pod间相互访问的流量。
- 南北流量:从Ingress traffic进来的流量,从Egress traffic出去的流量。
六、Istio的核心资源介绍
参考这篇:https://istio.io/latest/docs/concepts/traffic-management/
6.1、VirtualService
- K8S中的Serivce最终生成的是iptables规则或者是ipvs规则
- VirtualService最终生成的Istio规则
我们都知道K8S中原生的Service本质上代理着一组Pod,当我们访问Service时,它可以将流量下发到它代理的那组Service上,无论是随机还是轮询,原生的Service所做的,其实只是简单的:流量下发
而VirtualService相较于原生的Service的流量下发能力外,还有流量管理的能力,划重点:管理东西流量。
比如:按比例管理流量打到相同应用的不同版本的Pod中(金丝雀发布)
比如:根据不同的用户来源、根据请求中携带的不同header管理流量(A/B 测试)
VS模版
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
# 可以是ip地址、DNS名称、K8S中的Service名、FQDN、也可以是通配符*
hosts:
- reviews
http:
# 匹配规则,不强制有
- match:
# 匹配请求头:end-user 完全等于 jason的流量
- headers:
end-user:
exact: jason
# 命中匹配后,将流量route到哪里去
route:
- destination:
# 指定路由到host=reviews的service中
# 有命名空间限制,推荐写成:${svc-name}.${namespace}.svc.cluster.local
host: reviews
# subset是由dr资源划分的版本号,也就是v2版本的reviews
subset: v2
# 从上到下匹配,若未匹配到响应的请求头,默认走下面这条配置
- route:
- destination:
host: reviews
subset: v3
6.2、Destination Rule
大白话讲讲上下文:
比如现在我们有个代码库叫:usercenter 用户中心。然后上线发布这个代码库,编译产出、打包镜像、通过Deployment资源将镜像部署进K8S中,并为Pod搭上标签app=usercenter
,得到了一组具有app=usercenter
标签的 pod。然后再通过一个叫svc-usercenter
代理有app=usercenter
的pod对外提供服务。
然后我们对usercenter进行一次比较大的迭代升级,为了使用Istio的特性,于是我们新搞一个Deployment V2部署最新的镜像,然后给pod多打一个叫version=v2
的label,因为这组新的pod也有app=usercenter
的标签,所以他们也能被svc-usercenter
代理。
但是问题是我们不直接使用原生K8S的Service而是使用Istio的VirtualService,通过vs的规则可以找到svc-usercenter
的不同subset,那这个子集是如何划分的呢?答案就是:通过DestinationRule
资源,根据pod的不同version
label的不同值划分,如下
如下示例,参考:https://istio.io/latest/docs/reference/config/networking/destination-rule/
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
# 后端真实服务service地址
# 有命名空间限制,推荐写成:${svc-name}.${namespace}.svc.cluster.local
host: my-svc
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
# 带有version=v1的pod划分进subset=v1
- name: v1
labels:
version: v1
# 带有version=v2的pod划分进subset=v2
- name: v2
labels:
version: v2
# 负载均衡策略为随机
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
# 带有version=v3的pod划分进subset=v3的子集
- name: v3
labels:
version: v3
6.3、Gateway
- 通过VistualService管理东西流量
- 通过Gateway管理南北流量
之前是使用Ingress代理Service,接受最外层的HTTP/TCP流量,并将流量转发到不同的Service中
使用Istio之后,Istio提供Gateway组件IngressGateway在网格的最外层接收HTTP/TCP流量,并将请求转发到网格内部的VS,也支持出口流量的管理,可以将出口流量固定从EgressGateway的服务中代理出去。
注意:IngressGateway、EgressGateway是两类Pod
示例:一般Gateway上只配置端口、主机名、证书
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
# ingress-gateway/egress-gateway pod的标签
app: my-gateway-controller
# 配置不同的入口,也就是不同主机地址及其port
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host.example.com
# 也可以是通配符*
# - "*"
tls:
mode: SIMPLE
credentialName: ext-host-cert
6.4、SE
使用ServiceEntry资源对象可以将一个服务网格外部的应用添加进服务网格的服务注册表中,添加完之后,Envoy 代理可以将流量发送到服务,就好像它实打实的在网格中一样。
它的典型应用场景是:若我们开发的应用依赖较多的其他上下游服务,这时可以将我们的本地开发机上的应用接入进服务网格中,作为其中的一环,复用网格中的其他应用做我们的上下游,方便快速开发~
了解更多参考:https://istio.io/latest/docs/concepts/traffic-management/#service-entries
七、安装
7.1、安装istio
根据自己的K8S集群版本选择要安装的Istio版本:https://istio.io/latest/docs/releases/supported-releases/
下文使用Operator安装:https://istio.io/latest/docs/setup/install/
下载istio客户端工具:https://github.com/istio/istio/tags
# 下载
wget https://github.com/istio/istio/releases/download/1.11.6/istio-1.11.6-linux-amd64.tar.gz
# 解压
tar -xzvf istio-1.11.6-linux-amd64.tar.gz
# 将工具放到/usr/local/bin下
mv istio-1.11.6/bin/istioctl /usr/local/bin/
# 查看
$ istioctl version
no running Istio pods in "istio-system"
1.11.6
安装:https://istio.io/latest/docs/setup/install/operator/#install
自动部署istio的operator
$ istioctl operator init
查看operator是否正常
$ kubectl get pod -n istio-operator
NAME READY STATUS RESTARTS AGE
istio-operator-55f48b7495-r8hnn 1/1 Running 0 5m8s
通过CRD安装Istio
vim istio-operator.yaml
apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
metadata:
namespace: istio-system
name: example-istiocontrolplane
spec:
profile: default
components:
# 默认igressGateways使用Loadbalancer,为兼容自己的K8S集群,改成NodePort类型
ingressGateways:
- name: istio-igressgateway
enabled: true
k8s:
service:
type: NodePort
ports:
- port: 15020
nodePort: 30520
name: status-port
- port: 80
# 通过宿主机ip+30080可访问到服务网格内的应用
nodePort: 30080
name: http2
targetPort: 8080
- port: 443
nodePort: 30443
name: https
targetPort: 8443
更多istio-operator配置参考:https://istio.io/latest/docs/reference/config/istio.operator.v1alpha1/
安装:
$ istioctl manifest apply -f istio-operator.yaml
✔ Istio core installed
✔ Istiod installed
✔ Ingress gateways installed
✔ Installation complete
查看安装结果:
$ kubectl get po,svc -n istio-system
7.2、安装kiali和jaeger
进入istio的解压目录安装
$ kubectl apply -f samples/addons/kiali.yaml
serviceaccount/kiali created
configmap/kiali created
clusterrole.rbac.authorization.k8s.io/kiali-viewer created
clusterrole.rbac.authorization.k8s.io/kiali created
clusterrolebinding.rbac.authorization.k8s.io/kiali created
role.rbac.authorization.k8s.io/kiali-controlplane created
rolebinding.rbac.authorization.k8s.io/kiali-controlplane created
service/kiali created
deployment.apps/kiali created
查看状态
$ kubectl get svc,po -n istio-system -l app=kiali
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kiali ClusterIP 192.168.138.0 <none> 20001/TCP,9090/TCP 65s
NAME READY STATUS RESTARTS AGE
pod/kiali-787bc487b7-fhjpq 1/1 Running 0 65s
将kiali的svc类型修改成NodePort
$ kubectl edit svc kiali -n istio-system
安装jaeger
$ kubectl apply -f samples/addons/jaeger.yaml
7.3、安装Prometheus和Kibana
Istio可以展示请求数量的统计,请求的持续时间,这些指标可以使用Prometheus采集
Istio内置了Promethetus和Garfana的安装文件
$ kubectl create -f samples/addons/prometheus.yaml -f samples/addons/grafana.yaml
八、官方练习项目Book-Info
8.1、安装
参考:https://istio.io/latest/docs/examples/bookinfo/
创建项目:
$ kubectl create ns bookinfo
# 要添加istio-injection=enabled后,才会被自动注入istio的proxy
$ kubectl label ns bookinfo istio-injection=enabled
$ kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n bookinfo
部署完之后可以发现,pod每个业务Pod都含有两个容器,除了我们自己的业务容器之外还被注入了一个Istio的Proxy容器,使用的镜像是docker.io/istio/proxyv2:1.11.6
,若
在kiali中查看,可以在kiali中开启Auto Injection(其实就是给namespace添加label:istio-injection=enabled
)
将productpage-svc修改成NodePort,然后访问:http://10.10.10.201:30916/productpage
访问几次之后可以在Kiali中查看到流量的链路
8.2、使用域名的方式发布
类比Ingress去理解,在Ingress中我们可以用域名的方式去发布服务,前提是我们得先安装好IngressController(相当于Nginx),然后通过创建Ingress资源对象(相当于nginx.conf)去生成IngressController的配置。
在Istio架构体系中,和IngressController作用相当的软件是:IngressGateway,之前已经装过了,如下
再就是如何配置IngressGateway?答案是:通过创建Gateway资源对象配置IngressGateway
产品名: | Ingress | Istio |
---|---|---|
类比功能: | IngressController | IngressGateway |
类比功能: | Ingress | Gateway |
BookInfo项目的Gateway配置和VS配置如下
$ vim samples/bookinfo/networking/bookinfo-gateway.yaml
# 修改vs的host为具体的域名
# 创建
$ kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n bookinfo
bookinfo-gateway.yaml详情如下:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
# 这个标签由istio-igressgateway-65846c5 pod携带
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
# 接受所有域名的流量
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
# 当前vs仅对如下域名生效
- "bookinfo.kubeeasy.com"
gateways:
# 指定和哪个gateway绑定
- bookinfo-gateway
http:
- match:
- uri:
exact: /productpage
- uri:
prefix: /static
- uri:
exact: /login
- uri:
exact: /logout
- uri:
prefix: /api/v1/products
route:
- destination:
# host的值为真实的svc的name,由于在同一个命名空间下,可以不加svc.local后缀
host: productpage
port:
# svc的端口号
number: 9080
查看资源
$ kubectl get gw,vs -n bookinfo
NAME AGE
gateway.networking.istio.io/bookinfo-gateway 3m32s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/bookinfo ["bookinfo-gateway"] ["bookinfo.kubeeasy.com"] 3m32s
修改本机host,将bookinfo.kubeeasy.com解析成istio-system命名空间下ingressgateway-pod所在机器ip
配置之后可以使用域名访问:http://bookinfo.kubeeasy.com:30916/productpage
生产环境参考
九、Istio实用的能力
9.1、支持的负载均衡算法
默认负载均衡算法是:轮询
全局负载均衡配置
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: bookinfo-ratings
spec:
host: ratings.prod.svc.cluster.local
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
也可以配置指定subset的负载均衡
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
# 后端真实服务service地址
# 有命名空间限制,推荐写成:${svc-name}.${namespace}.svc.cluster.local
host: my-svc
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
# 带有version=v1的pod划分进subset=v1
- name: v1
labels:
version: v1
# 带有version=v2的pod划分进subset=v2
- name: v2
labels:
version: v2
# 负载均衡策略为随机,它的优先级大于上面的RANDOM
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
参考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings
更过负载均衡配置项参考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#LoadBalancerSettings-SimpleLB
9.2、金丝雀发布
首先我们在部署项目时需要两个标签去标记pod。
如上图:app
、version
。其中的app标签是给service使用的,version标签用来给istio划分subnet
- 使用DR换分subnet
- 使用vs做流量的route
- 使用新的deployment部署新的应用pod,version标签值有别于老版本(此时vs不会将流量route过来)
- 修改vs调整切换流量
Step1:首先创建DR
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
# 后端真实服务service地址,通过这个service可以找到endpoint全集
# 然后根据不同的标签将endpoint全集划分成不同的subnet
host: my-svc
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
# 带有version=v1的pod划分进subset=v1
- name: v1
labels:
version: v1
# 带有version=v2的pod划分进subset=v2
- name: v2
labels:
version: v2
# 负载均衡策略为随机
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
# 带有version=v3的pod划分进subset=v3的子集
- name: v3
labels:
version: v3
Step2:创建VirtualService,将流量全部打到指定service的subnet-v1的endpoint上
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
# 可以是ip地址、DNS名称、K8S中的Service名、FQDN、也可以是通配符*
hosts:
- reviews
http:
- route:
- destination:
# service 名称
host: my-svc
subset: v1
Step3:使用新的deployment部署新的应用pod,version标签值有别于老版本(此时vs不会将流量route过来)
Step4:修改vs调整切换流量
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
# 可以是ip地址、DNS名称、K8S中的Service名、FQDN、也可以是通配符*
hosts:
- reviews
http:
- route:
- destination:
# service 名称
host: my-svc
subset: v1
# 80%的流量转发到v1版本的subset中
weight: 80
- route:
- destination:
# service 名称
host: my-svc
subset: v2
# 80%的流量转发到v2版本的subset中
weight: 20
9.3、AB测试
什么是:所谓AB测试就是说将新上线的服务推送给部分指定的人群,比如先开放给公司内部的人,或者是先开放给某个城市的人使用。
怎么做:在Istio中的VS可以通过匹配请求头的方式完成流量的划分,如下match部分,以此来实现AB测试。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
# 可以是ip地址、DNS名称、K8S中的Service名、FQDN、也可以是通配符*
hosts:
- reviews
http:
# 匹配规则,不强制有
- match:
# 匹配请求头:end-user 完全等于 jason的流量
- headers:
end-user:
exact: jason
# 命中匹配后,将流量route到哪里去
route:
- destination:
# 指定路由到host=reviews的service中
host: reviews
# subset是由dr资源划分的版本号,也就是v2版本的reviews
subset: v2
# 从上到下匹配,若未匹配到响应的请求头,默认走下面这条配置
- route:
- destination:
host: reviews
subset: v3
除了匹配请求头之外,更多匹配模式参考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPMatchRequest
9.4、地址重定向
需求:将访问www.1.com的流量跳转到www.2.com
参考实现:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPRedirect
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- "bookinfo.v111.com"
gateways:
- bookinfo-gateway
http:
- match:
- uri:
exact: /v1/getProductRatings
redirect:
uri: /v2/bookRatings
authority: bookinfo.v222.com
将请求:bookinfo.v111.com/v1/getProductRatings
的流量转发到bookinfo.v222.com/v2/bookRatings
9.5、地址重写
如:访问ratings.prod.svc.cluster.local
rewrite到ratings.prod.svc.cluster.local/index.html
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- match:
- uri:
prefix: /
rewrite:
uri: /index.html
route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
9.6、连接数控制
参考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#OutlierDetection
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-cb-policy
spec:
host: reviews.prod.svc.cluster.local
# 可配置在subset级别
trafficPolicy:
# 连接池的配置,可以和熔断detection分开使用
connectionPool:
tcp:
# 最大的连接数
maxConnections: 100
http:
# 最大请求数
http2MaxRequests: 1000
# 每个请求最大的链接数
maxRequestsPerConnection: 10
超过最大的连接数外的请求会被拒绝不处理。
9.7、服务熔断
服务熔断谨慎使用,比如有人恶意访问我们的应用触发了熔断机制,被熔断的服务不再处理任何请求,等待熔断时间之后,服务被重启,此时恶意攻击者可能还是在攻击
参考:https://istio.io/latest/docs/reference/config/networking/destination-rule/#OutlierDetection
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews-cb-policy
spec:
host: reviews.prod.svc.cluster.local
# 可配置在subset级别
trafficPolicy:
# 连接池的配置,可以和熔断detection分开使用
connectionPool:
tcp:
# 最大的连接数
maxConnections: 100
http:
# 最大请求数
http2MaxRequests: 1000
# 每个请求最大的链接数
maxRequestsPerConnection: 10
outlierDetection:
# 持续出现7个5xx错误后,服务熔断
consecutive5xxErrors: 7
# 每间5分钟探测一次
interval: 5m
# 熔断的时间
baseEjectionTime: 15m
# 被熔断服务的最大百分比
maxEjectionPercent: 50
限制最大连接数和熔断一起配置效果是:超过最大请求数的连接被拒绝处理,返回5xx状态码,当5xx出现的数量达到consecutive5xxErrors
配置的阈值之后,会触发熔断,熔断时常baseEjectionTime
bookinfo项目中有fortio压测工具
$ kubectl apply -f samples/httpbin/sample-client/fortio-deploy.yaml -n bookinfo
压测命令-c
指定并发数,-n
发送的请求数
$ kubectl exec -ti $fortio-pod-name -n bookinfo -- fortio load -c 2 - qps 0 -n 20 -loglevel Warning http://ratings:9080/ratings/0 | grep Code
9.8、故障注入
9.8.1、延时故障
什么是延时故障:通过配置的方式延长本次请求的请求时长
目的:观测请求的上游针对这种情况是如何处理的
参考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Delay
参考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews-route
spec:
hosts:
- reviews.prod.svc.cluster.local
http:
- match:
- sourceLabels:
env: prod
route:
- destination:
host: reviews.prod.svc.cluster.local
subset: v1
# 添加故障
fault:
# 故障类型为delay
delay:
# 故障注入的比例
percentage:
value: 10
# 延时时间
fixedDelay: 5s
9.8.2、中断故障
强行中断本次请求,观测上游的是如何处理的。
参考:https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPFaultInjection-Abort
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings-route
spec:
hosts:
- ratings.prod.svc.cluster.local
http:
- route:
- destination:
host: ratings.prod.svc.cluster.local
subset: v1
fault:
# 中断故障
abort:
# 中断0.1%的请求
percentage:
value: 0.1
# 中断的错误状态码
httpStatus: 400