目录
一、实例介绍
1、创建bookinfo实例:
2、实例架构
3、访问
二、istio微服务流量接管
1、ingress-gateway访问productpage
2、权重路由
3、访问路径路由
4、路径重写
5、匹配优先级
6、DestinationRule 转发策略
7、根据header头配置路由策略
8、流量镜像
9、熔断
10、故障注入与超时机制
2、状态码
11、Prometheus监控指标展示
1、安装集成组件
2、可视化界面访问
$ kubectl create namespace bookinfo $ kubectl -n bookinfo create -f samples/bookinfo/platform/kube/bookinfo.yaml $ kubectl -n bookinfo get po NAME READY STATUS RESTARTS AGE details-v1-5974b67c8-wclnd 1/1 Running 0 34s productpage-v1-64794f5db4-jsdbg 1/1 Running 0 33s ratings-v1-c6cdf8d98-jrfrn 1/1 Running 0 33s reviews-v1-7f6558b974-kq6kj 1/1 Running 0 33s reviews-v2-6cb6ccd848-qdg2k 1/1 Running 0 34s reviews-v3-cc56b578-kppcx 1/1 Running 0 34s
该应用由四个单独的微服务构成。 这个应用模仿在线书店的一个分类,显示一本书的信息。 页面上会显示一本书的描述,书籍的细节(ISBN、页数等),以及关于这本书的一些评论。
Bookinfo 应用分为四个单独的微服务:
productpage
. 这个微服务会调用details
和reviews
两个微服务,用来生成页面。
details
. 这个微服务中包含了书籍的信息。
reviews
. 这个微服务中包含了书籍相关的评论。它还会调用ratings
微服务。
ratings
. 这个微服务中包含了由书籍评价组成的评级信息。
reviews
微服务有 3 个版本:
v1 版本不会调用
ratings
服务。v2 版本会调用
ratings
服务,并使用 1 到 5 个黑色星形图标来显示评分信息。v3 版本会调用
ratings
服务,并使用 1 到 5 个红色星形图标来显示评分信息
Bookinfo 是一个异构应用,几个微服务是由不同的语言编写的。这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews
服务具有多个版本。
使用ingress访问productpage服务:
ingress-productpage.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: productpage
namespace: bookinfo
spec:
rules:
- host: productpage.bookinfo.com
http:
paths:
- backend:
serviceName: productpage
servicePort: 9080
path: /
status:
loadBalancer: {}
如何实现更细粒度的流量管控?
注入sidecar容器
如何注入sidecar容器
使用
istioctl kube-inject
$ kubectl -n bookinfo apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
为命名空间打label
# 给命名空间打标签,这样部署在该命名空间的服务会自动注入sidecar容器 $ kubectl label namespace dafault istio-injection=enabled
注入bookinfo
$ kubectl -n bookinfo apply -f <(istioctl kube-inject -f samples/bookinfo/platform/kube/bookinfo.yaml)
流量路由
实现ingress解决不了的按照比例分配流量
ingress-gateway访问productpage
productpage-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: productpage-gateway
namespace: bookinfo
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- productpage.bookinfo.com
productpage-virtualservice.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: gateway-front-tomcat
namespace: bookinfo
spec:
gateways:
- productpage-gateway
hosts:
- productpage.bookinfo.com
http:
- route:
- destination:
host: productpage
port:
number: 9080
配置nginx,使用域名80端口访问。
upstream bookinfo-productpage {
server 192.168.0.121:32437;
}
server {
listen 80;
listen [::]:80;
server_name productpage.bookinfo.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_pass http://bookinfo-productpage;
}
}
$ nginx -s reload
此时,win本地hosts配置nginx域名解析可以正常访问,说明流量已经成功进入服务网格
需求一:只想访问
reviews-v3,所有流量都调度到v3也就是红心上面。其他不调度
# 设置一条路由规则,要求访问reviews服务的流量全部转到v3的后端
$ cat virtual-service-reviews-v3.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
namespace: bookinfo
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v3
# 定义流量访问的目的地,v1对应review服务里面label为version=v1的pod
$ cat destination-rule-reviews.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
namespace: bookinfo
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
- name: v3
labels:
version: v3
[root@k8s-master bookinfo]# kubectl get po -n bookinfo --show-labels | grep review
reviews-v1-d49966d6b-vn5tx 2/2 Running 2 15h app=reviews,istio.io/rev=,pod-template-hash=d49966d6b,security.istio.io/tlsMode=istio,version=v1
reviews-v2-644f5c9ddb-pjmnh 2/2 Running 2 15h app=reviews,istio.io/rev=,pod-template-hash=644f5c9ddb,security.istio.io/tlsMode=istio,version=v2
reviews-v3-d56b49bc8-brp5k 2/2 Running 2 15h app=reviews,istio.io/rev=,pod-template-hash=d56b49bc8,security.istio.io/tlsMode=istio,version=v3
$ kubectl apply -f virtual-service-reviews-v3.yaml # 访问productpage测试,此时发现页面一直停在v3版本不会变化,需求实现。
需求二:实现如下流量分配:
90% -> reivews-v1 10% -> reviews-v2 0% -> reviews-v3
# 同样的方式,刚才已经定义过v1、v2、v3的去向了,现在只需要增加v1和v2路由规则即可
$ cat virtual-service-reviews-90-10.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
namespace: bookinfo
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 90
- destination:
host: reviews
subset: v2
weight: 10
$ kubectl apply -f virtual-service-reviews-90-10.yaml
此时,再次访问,v3就不会出现了
需求:意思是根据不同路径访问不同页面
实现效果如下:
# 定义允许外部流量进入网格,直接编辑已有gateway
- hosts:
- productpage.bookinfo.com
- bookinfo.com
# 添加路由配置,通过网关productpage-gateway访问bookinfo.com的域名,匹配以下规则,此时只到服务发现层面,如果需要针对具体服务配置路由分配策略需要添加subset。
$ kubectl -n bookinfo edit gw productpage-gateway
$ cat bookinfo-routing-with-uri-path.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
namespace: bookinfo
spec:
gateways:
- productpage-gateway
hosts:
- bookinfo.com
http:
- name: productpage-route
match:
- uri:
prefix: /productpage
route:
- destination:
host: productpage
- name: reviews-route
match:
- uri:
prefix: /reviews
route:
- destination:
host: reviews
- name: ratings-route
match:
- uri:
prefix: /ratings
route:
- destination:
host: ratings
nginx中新增bookinfo.com配置:
upstream bookinfo {
server 192.168.0.121:32437;
}
server {
listen 80;
listen [::]:80;
server_name bookinfo.com;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_pass http://bookinfo;
}
}
本地hosts添加bookinfo.com域名解析
访问:
http://bookinfo.com/productpage
http://bookinfo.com/ratings/1
http://bookinfo.com/reviews/1
实际的访问对应为:
bookinfo.com/productpage -> productpage:8090/productpage bookinfo.com/ratings -> ratings:9080/ratings bookinfo.com/reviews -> reviews:9080/reviews
实际访问productpage页面,由于需要引用css、js等静态资源,因此需要补充对
/static
路径的转发:... http: - name: productpage-route match: - uri: prefix: /productpage - uri: prefix: /static route: - destination: host: productpage ...
virtualservice
的配置中并未指定service的port端口,转发同样可以生效?
注意,若service中只有一个端口,则不用显式指定端口号,会自动转发到该端口中
如果想实现rewrite的功能,隐藏真实url路径名称,很简单:
bookinfo.com/rate -> ratings:8090/ratings
... - name: ratings-route match: - uri: prefix: /haha rewrite: uri: "/ratings" route: - destination: host: ratings ...
需求:我们可以根据URL访问不同的后端,但是我们不可能考虑到所有的url后缀,此时点击登录发现
/login
的匹配也没有添加,后续有可能有别的,因此可以在规则列表最后添加一个规则,作为默认的转发规则。
$ kubectl -n bookinfo edit vs bookinfo ... - name: default-route route: - destination: host: productpage
默认会使用轮询策略,此外也支持如下负载均衡模型,可以在 DestinationRule
中使用这些模型,将请求分发到特定的服务或服务子集。
Random:将请求转发到一个随机的实例上
Weighted:按照指定的百分比将请求转发到实例上
Least requests:将请求转发到具有最少请求数目的实例上
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: my-destination-rule
spec:
host: my-svc
trafficPolicy: #默认的负载均衡策略模型为随机
loadBalancer:
simple: RANDOM
subsets:
- name: v1 #subset1,将流量转发到具有标签 version:v1 的 deployment 对应的服务上
labels:
version: v1
- name: v2 #subset2,将流量转发到具有标签 version:v2 的 deployment 对应的服务上,指定负载均衡为轮询
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3 #subset3,将流量转发到具有标签 version:v3 的 deployment 对应的服务上
labels:
version: v3
该项目默认登录时会将用户名写入head的请求头,这个一般在代码中实现,我们可以根据这个特性,利用istop获取请求的head头信息。
需求:v2为正式版本,v3为测试版本,内测用户testuser登录时访问v3界面,其他用户或者未登录访问v2界面。
$ cat virtual-service-reviews-header.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
namespace: bookinfo
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: testuser
route:
- destination:
host: reviews
subset: v3
- route:
- destination:
host: reviews
subset: v2
$ kubectl apply -f virtual-service-reviews-header.yaml # 刷新观察http://bookinfo.com/productpage
更多支持的匹配类型可以在此处查看。
https://istio.io/latest/docs/reference/config/networking/virtual-service/#HTTPMatchRequest
背景:
很多情况下,当我们对服务做了重构,或者我们对项目做了重大优化时,怎么样保证服务是健壮的呢?在传统的服务里,我们只能通过大量的测试,模拟在各种情况下服务的响应情况。虽然也有手工测试、自动化测试、压力测试等一系列手段去检测它,但是测试本身就是一个样本化的行为,即使测试人员再完善它的测试样例,无法全面的表现出线上服务的一个真实流量形态 。
流量镜像的设计,让这类问题得到了最大限度的解决。流量镜像讲究的不再是使用少量样本去评估一个服务的健壮性,而是在不影响线上坏境的前提下将线上流量持续的镜像到我们的预发布坏境中去,让重构后的服务在上线之前就结结实实地接受一波真实流量的冲击与考验,让所有的风险全部暴露在上线前夕,通过不断的暴露问题,解决问题让服务在上线前夕就拥有跟线上服务一样的健壮性。由于测试坏境使用的是真实流量,所以不管从流量的多样性,真实性,还是复杂性上都将能够得以展现,同时预发布服务也将表现出其最真实的处理能力和对异常的处理能力。
实践
# 准备httpbin v1
$ cat httpbin-v1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v1
namespace: bookinfo
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
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:80", "httpbin:app"]
# 准备httpbin v2
$ cat httpbin-v2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-v2
namespace: bookinfo
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v2
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:80", "httpbin:app"]
$ istioctl kube-inject -f httpbin-v2.yaml | kubectl create -f -
$ istioctl kube-inject -f httpbin-v1.yaml | kubectl create -f -
# 测试访问是否正常
$ curl $(kubectl -n bookinfo get po -l version=v1,app=httpbin -ojsonpath='{.items[0].status.podIP}')/headers
{
"headers": {
"Accept": "*/*",
"Content-Length": "0",
"Host": "10.244.0.88",
"User-Agent": "curl/7.29.0",
"X-B3-Sampled": "1",
"X-B3-Spanid": "777c7af4458c5b81",
"X-B3-Traceid": "6b98ea81618deb4f777c7af4458c5b81"
}
}
# Service文件
$ cat httpbin-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: bookinfo
labels:
app: httpbin
spec:
ports:
- name: http
port: 8000
targetPort: 80
selector:
app: httpbin
$ kubectl apply -f httpbin-svc.yaml
# 创建gateway和virtualservice,由于都是使用http请求,因此,直接
# 使用bookinfo.com/httpbin访问,因此直接修改bookinfo这个virtualservice即可
$ kubectl -n bookinfo get vs
NAME GATEWAYS HOSTS
bookinfo [bookinfo-gateway] [bookinfo.com]
gateway-front-tomcat [productpage-gateway] [productpage.bookinfo.com]
reviews [reviews]
$ kubectl -n bookinfo edit vs bookinfo
#添加httpbin的规则
...
- match:
- uri:
prefix: /httpbin
name: httpbin-route
rewrite:
uri: /
route:
- destination:
host: httpbin
subset: v1
...
$ cat httpbin-destinationRule.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: httpbin
namespace: bookinfo
spec:
host: httpbin
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
$ kubectl apply -f httpbin-destinationRule.yaml
# 访问http://bookinfo.com/httpbin/headers,查看日志
# 此时发起请求,查看httpbin-v1的日志有刷,v2没反应,因为上面vs规则只匹配了v1,现在我们希望在访问v1的同时,流量也转发v2一份
[root@k8s-master bookinfo]# kubectl -n bookinfo logs -f httpbin-v1-66c7d456fb-hhqjv -c httpbin
[2022-01-17 09:04:00 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2022-01-17 09:04:00 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2022-01-17 09:04:00 +0000] [1] [INFO] Using worker: sync
[2022-01-17 09:04:00 +0000] [9] [INFO] Booting worker with pid: 9
127.0.0.6 - - [17/Jan/2022:09:05:48 +0000] "GET /headers HTTP/1.1" 200 257 "-" "curl/7.29.0"
127.0.0.1 - - [17/Jan/2022:09:11:57 +0000] "GET //headers HTTP/1.1" 200 1133 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
127.0.0.1 - - [17/Jan/2022:09:13:07 +0000] "GET //headers HTTP/1.1" 200 1168 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/97.0.4692.71 Safari/537.36"
[root@k8s-master ~]# k logs -f httpbin-v2-69b898fddc-zv2vj -c httpbin
kubectl -n bookinfo logs -f httpbin-v2-69b898fddc-zv2vj -c httpbin
[2022-01-17 09:04:15 +0000] [1] [INFO] Starting gunicorn 19.9.0
[2022-01-17 09:04:15 +0000] [1] [INFO] Listening at: http://0.0.0.0:80 (1)
[2022-01-17 09:04:15 +0000] [1] [INFO] Using worker: sync
[2022-01-17 09:04:15 +0000] [9] [INFO] Booting worker with pid: 9
# 为httpbin-v1添加mirror设置,mirror点为httpbin-v2,mirror_percent表示转发100%的流量
$ kubectl -n bookinfo edit vs bookinfo
...
- match:
- uri:
prefix: /httpbin
name: httpbin-route
rewrite:
uri: /
route:
- destination:
host: httpbin
subset: v1
mirror:
host: httpbin
subset: v2
mirror_percent: 100
...
此时访问页面即v1服务,v2后台日期同步刷新,说明接收到流量镜像。
介绍
熔断(Circuit Breaker),原是指当电流超过规定值时断开电路,进行短路保护或严重过载保护的机制 。对于微服务系统而言,熔断尤为重要,它可以使系统在遭遇某些模块故障时,通过服务降级等方式来提高系统核心功能的可用性,得以应对来自故障、潜在峰值或其他未知网络因素的影响。
准备环境
Istio 是通过 Envoy Proxy 来实现熔断机制的,Envoy 强制在网络层面配置熔断策略,这样就不必为每个应用程序单独配置或重新编程。下面就通过一个示例来演示如何为 Istio 网格中的服务配置熔断的连接数、请求数和异常检测。istio的熔断本质是一种限流
创建httpbin服务
创建测试客户端
我们已经为 httpbin
服务设置了熔断策略,接下来创建一个 Java 客户端,用来向后端服务发送请求,观察是否会触发熔断策略。这个客户端可以控制连接数量、并发数、待处理请求队列,使用这一客户端,能够有效的触发前面在目标规则中设置的熔断策略。该客户端的
deployment yaml 内容如下:
# httpbin-client-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin-client-v1
namespace: bookinfo
spec:
replicas: 1
selector:
matchLabels:
app: httpbin-client-v1
version: v1
template:
metadata:
labels:
app: httpbin-client-v1
version: v1
spec:
containers:
- image: ceposta/http-envoy-client-standalone:latest
imagePullPolicy: IfNotPresent
name: httpbin-client
command: ["/bin/sleep","infinity"]
这里我们会把给客户端也进行 Sidecar 的注入,以此保证 Istio 对网络交互的控制:
$ kubectl apply -f <(istioctl kube-inject -f httpbin-client-deploy.yaml)
验证
先尝试通过单线程(NUM_THREADS=1
)创建一个连接,并进行 5 次调用(默认值:NUM_CALLS_PER_CLIENT=5
):
$ CLIENT_POD=$(kubectl get pod -n bookinfo | grep httpbin-client | awk '{ print $1 }') $ kubectl -n bookinfo exec -it $CLIENT_POD -c httpbin-client -- sh -c 'export URL_UNDER_TEST=http://httpbin:8000/get export NUM_THREADS=1 && java -jar http-client.jar'
下面尝试把线程数提高到 2:
$ kubectl -n bookinfo exec -it $CLIENT_POD -c httpbin-client -- sh -c 'export URL_UNDER_TEST=http://httpbin:8000/get export NUM_THREADS=2 && java -jar http-client.jar'
创建DestinationRule, 针对 httpbin
服务设置熔断策略:
$ kubectl apply -f - <
maxConnections : 限制对后端服务发起的
HTTP/1.1
连接数,如果超过了这个限制,就会开启熔断。maxPendingRequests : 限制待处理请求列表的长度, 如果超过了这个限制,就会开启熔断。
maxRequestsPerConnection : 在任何给定时间内限制对后端服务发起的
HTTP/2
请求数,如果超过了这个限制,就会开启熔断。
可以查看设置的熔断策略在envoy的配置片段:
$ istioctl pc cluster httpbin-client-v1-56b86fb85c-vg5pp.bookinfo --fqdn httpbin.bookinfo.svc.cluster.local -ojson ... "connectTimeout": "10s", "maxRequestsPerConnection": 1, "circuitBreakers": { "thresholds": [ { "maxConnections": 1, "maxPendingRequests": 1, "maxRequests": 4294967295, "maxRetries": 4294967295 } ] }, ...
istio的熔断策略本质上是一种代理层面的补救措施,不会侵入代码层,若要想真正实现异常规避,最好的方式还是通过代码实现重试或者异常处理比较有效
在一个微服务架构的系统中,为了让系统达到较高的健壮性要求,通常需要对系统做定向错误测试。比如电商中的订单系统、支付系统等若出现故障那将是非常严重的生产事故,因此必须在系统设计前期就需要考虑多样性的异常故障并对每一种异常设计完善的恢复策略或优雅的回退策略,尽全力规避类似事故的发生,使得当系统发生故障时依然可以正常运作。而在这个过程中,服务故障模拟一直以来是一个非常繁杂的工作。
为什么要有故障注入,为了提高程序兼容性,测试存在大量404、502时,系统运行是否正常。不能因为有部分失败请求就系统挂了。
istio提供了无侵入式的故障注入机制,让开发测试人员在不用调整服务程序的前提下,通过配置即可完成对服务的异常模拟。目前,包含两类:
abort:非必配项,中断故障,配置一个 Abort 类型的对象。用来注入请求异常类故障。简单的说,就是用来模拟上游服务对请求返回指定异常码时,当前的服务是否具备处理能力。
delay:非必配项,延迟故障,配置一个 Delay 类型的对象。用来注入延时类故障。通俗一点讲,就是人为模拟上游服务的响应时间,测试在高延迟的情况下,当前的服务是否具备容错容灾的能力。
1、延迟与超时
目前针对luffy登录用户,访问服务的示意为:
productpage --> reviews v2 --> ratings \ -> details
可以通过如下方式,为ratings
服务注入2秒的延迟:
# 请求ratings这个hosts时,注入2s的延迟
$ cat virtualservice-ratings-2s-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
namespace: bookinfo
spec:
hosts:
- ratings
http:
- fault:
delay:
percentage:
value: 100
fixedDelay: 2s
route:
- destination:
host: ratings
$ kubectl apply -f virtualservice-ratings-2s-delay.yaml # 再次访问http://bookinfo.com/productpage,可以明显感觉2s的延迟,network可以看到
可以查看对应的envoy的配置:
$ istioctl pc r ratings-v1-556cfbd589-89ml4.bookinfo --name 9080 -ojson此时的调用为:
productpage --> reviews v2 -(延迟2秒)-> ratings \ -> details
此时,为reviews服务添加请求超时时间:
$ kubectl -n bookinfo edit vs reviews
...
http:
- match:
- headers:
end-user:
exact: testuser
route:
- destination:
host: reviews
subset: v2
timeout: 1s
- route:
- destination:
host: reviews
subset: v3
...
此使的调用关系为:
productpage -(0.5秒超时)-> reviews v2 -(延迟2秒)-> ratings \ -> details
此时,我们相当于设置review请求rating服务时注入2s的延迟,然后testuser用户注入1s的超时,如果使用testuser用户,因为超时会报错,如果使用非testuser用户,则会出现只延迟,不会失败的情况。
删除延迟:
$ kubectl -n bookinfo delete vs ratings
# 注入请求details服务时有50%返回500错误码的几率
$ cat virtualservice-details-aborted.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: details
namespace: bookinfo
spec:
hosts:
- details
http:
- fault:
abort:
percentage:
value: 50
httpStatus: 500
route:
- destination:
host: details
$ kubectl apply -f virtualservice-details-aborted.yaml
# 再次刷新查看details的状态,查看productpage的日志
$ kubectl -n bookinfo logs -f $(kubectl -n bookinfo get po -l app=productpage -ojsonpath='{.items[0].metadata.name}') -c istio-proxy
[2020-11-09T09:00:16.020Z] "GET /details/0 HTTP/1.1" 500 FI "-" "-" 0 18 0 - "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36" "f0387bb6-a445-922c-89ab-689dfbf548f8" "details:9080" "-" - - 10.111.67.169:9080 10.244.0.52:56552 - -
https://istio.io/latest/docs/ops/integrations
Grafana(图标展示)
$ kubectl apply -f samples/addons/grafana.yaml
Jaeger(分布式追踪)
$ kubectl apply -f samples/addons/jaeger.yaml
Kiali(针对istio可视化组件)
# 完善扩展组件地址:
grafana url: "http://grafana.istio.com"
tracing url: "http://jaeger.istio.com"
$ kubectl apply -f samples/addons/kiali.yaml
Prometheus(监控)
$ kubectl apply -f samples/addons/prometheus.yaml
创建kiali报错:
unable to recognize "samples/addons/kiali.yaml": no matches for kind "MonitoringDashboard" in version "monitoring.kiali.io/v1alpha1"
解决:
需要创建“CustomResourceDefinition”
cd istio-1.8.2/samples/addons/;vim kiali-crd.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: monitoringdashboards.monitoring.kiali.io
spec:
group: monitoring.kiali.io
names:
kind: MonitoringDashboard
listKind: MonitoringDashboardList
plural: monitoringdashboards
singular: monitoringdashboard
scope: Namespaced
versions:
- name: v1alpha1
served: true
storage: true
kubectl apply -f kiali-crd.yaml
参照:https://blog.csdn.net/qq_41674452/article/details/113345163
$ cat prometheus-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: prometheus
namespace: istio-system
spec:
rules:
- host: prometheus.istio.com
http:
paths:
- backend:
serviceName: prometheus
servicePort: 9090
path: /
status:
loadBalancer: {}
$ kubectl apply -f prometheus-ingress.yaml
[root@k8s-master warning]# kubectl get po -n istio-system -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
grafana-75b5cddb4d-m6rph 1/1 Running 0 25m 10.244.1.216 k8s-node2
istio-egressgateway-66f8f6d69c-6mdkj 1/1 Running 3 46h 10.244.1.210 k8s-node2
istio-ingressgateway-758d8b79bd-xvxt8 1/1 Running 3 46h 10.244.1.212 k8s-node2
istiod-7556f7fddf-kjhpr 1/1 Running 3 46h 10.244.1.209 k8s-node2
jaeger-5795c4cf99-w5lzg 1/1 Running 0 25m 10.244.1.217 k8s-node2
kiali-6c49c7d566-n5hpr 1/1 Running 0 8m44s 10.244.1.219 k8s-node2
prometheus-9d5676d95-67hvb 2/2 Running 0 25m 10.244.1.218 k8s-node2
配置nginx服务机器的hosts域名解析;查看默认添加的targets列表,默认已经集成好的:
其中最核心的是kubernetes-pods
的监控,服务网格内的每个服务都作为一个target被监控,而且服务流量指标直接由sidecar容器来提供指标。
$ kubectl -n bookinfo get po -owide $ curl 10.244.0.53:15020/stats/prometheus
对于这些监控指标采集的数据,可以在grafana中查看到。
$ cat grafana-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: grafana
namespace: istio-system
spec:
rules:
- host: grafana.istio.com
http:
paths:
- backend:
serviceName: grafana
servicePort: 3000
path: /
status:
loadBalancer: {}
$ for i in $(seq 1 10000); do curl -s -o /dev/null "http://bookinfo.com/productpage"; done
访问界面后,可以查看到Istio Mesh Dashboard等相关的dashboard,因为在grafana的资源文件中, 中以 ConfigMap 的形式挂载了 Istio各个组件的仪表盘 JSON 配置文件:
$ kubectl -n istio-system get cm istio-services-grafana-dashboards NAME DATA AGE istio-services-grafana-dashboards 3 7d1h
jaeger
$ cat jaeger-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: jaeger
namespace: istio-system
spec:
rules:
- host: jaeger.istio.com
http:
paths:
- backend:
serviceName: tracing
servicePort: 80
path: /
status:
loadBalancer: {}
$ kubectl apply -f jaeger-ingress.yaml
kiali
kiali 是一个 可观测性分析服务
$ cat kiali-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: kiali
namespace: istio-system
spec:
rules:
- host: kiali.istio.com
http:
paths:
- backend:
serviceName: kiali
servicePort: 20001
path: /
status:
loadBalancer: {}
$ kubectl apply -f kiali-ingress.yaml
集成了Prometheus、grafana、tracing、log、