一、集成Promethus和grafana

prometheus和grafana

  • Prometheus存储服务的监控数据,数据来自于istio组件mixer上报
  • Grafana开源数据可视化工具,展示Prometheus收集到的监控数据

istio已经默认帮我们把grafana和prometheus已经默认部署好了

执行命令查看istio自带的组件

kubectl get pods -n istio-ns

Service mesh 学习06 istio实战_实战

我们打开istio-demo.yaml文件找到找到prometheus和grafana

Service mesh 学习06 istio实战_实战_02

Service mesh 学习06 istio实战_实战_03

其实istio已经默认帮我们安装好了grafana和prometheus,只是对应的Service类型是clusterIP类型,表示集群内部可以访问

查看prometheus-ingress.yaml

#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: prometheus-ingress
  namespace: istio-system
spec:
  rules:
  - host: prometheus.istio.qy.com 
  http:
    paths:
    - path: /
      backend:
        serviceName: prometheus
        servicePort: 9090

绑定域名promethus.istio.qy.com

继续看下grafana-ingress.yaml

#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: grafana-ingress
  namespace: istio-system
spec:
  rules:
  - host: grafana.istio.qy.com
    http:
      paths:
      - path: /
        backend:
          serviceName: grafana
          servicePort: 3000

执行apply

kubectl apply -f prometheus-ingress.yaml
kubectl apply -f grafana-ingress.yaml

Service mesh 学习06 istio实战_实战_04

成功后访问prometheus域名 http://prometheus.istio.qy.com/graph

Service mesh 学习06 istio实战_实战_05

查看ingress

kubectl get ingress -n istio-system

Service mesh 学习06 istio实战_实战_06

通过域名访问 http://grafana.istio.qy.com

Service mesh 学习06 istio实战_实战_07

查看服务信息

kubectl get svc -o wide -n istio-system

Service mesh 学习06 istio实战_实战_08

选择datasource,选择promethus

Service mesh 学习06 istio实战_实战_09

选择settings ,把url改成prometheus即可,就是上图的ip

Service mesh 学习06 istio实战_实战_10

Service mesh 学习06 istio实战_实战_11

二、项目案例bookinfo

这是istio官方给我们提供的案例,Bookinfo 应用中的几个微服务是由不同的语言编写的。 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个服务、多个语言构成,并且 reviews 服务具有多个版本

Service mesh 学习06 istio实战_实战_12

大家一定要从spring cloud思维模式里面跳出来,站着服务网格的立场上思考问题,我们是不需要了解服务的业务代码是什么样的,业务的服务只需要交给istio管理即可

bookinfo自动注入

所以第一步我们需要给每一个服务配置一个Sidecar,但是配置sidecar我们前面也说过,可以有两种方式实现,一种是手动注入,一种是自动注入,如果自动注入需要与命名空间相关,需要准备一个命名空间

查看命名空间

kubectl get ns

创建命名空间

kubectl create namespace bookinfo-ns

Service mesh 学习06 istio实战_实战_13

配置自动注入

kubectl label namespace bookinfo-ns istio-injectinotallow=enabled

Service mesh 学习06 istio实战_实战_14

bookinfo启动

进入istio安装目录:/home/tools/istio-1.0.6/samples/bookinfo/platform/kube

找到bookinfo.yaml文件

查看需要的image个数:

cat bookinfo.yaml | grep image:

Service mesh 学习06 istio实战_实战_15

执行命令启动

kubectl apply -f  bookinfo.yaml -n bookinfo-ns

Service mesh 学习06 istio实战_实战_16

查看pod情况

kubectl get pods -n bookinfo-ns

Service mesh 学习06 istio实战_实战_17

# 会发现有两个container,有两个container的原因是因为我们有自动注入,这边有六个服务,其实只要四个服务,有一个服务有三个版本仅此而已

查看pod明细

kubectl describe pods reviews-v3-6dc9897554-fdn2z -n bookinfo-ns

查看service

kubectl get svc -n bookinfo-ns

Service mesh 学习06 istio实战_实战_18

  • 验证Bookinfo 应用是否正在运行,使用curl请求

进入到ratings服务内部,发送一个http请求,测试服务响应结果

kubectl exec -it $(kubectl get pod -l app=ratings -n bookinfo-ns -o jsnotallow='{.items[0].metadata.name}') -c ratings -n bookinfo-ns -- curl productpage:9080/productpage | grep -o "<title>.*</title>"

Service mesh 学习06 istio实战_实战_19

Service mesh 学习06 istio实战_实战_20

通过Ingress访问bookinfo项目

查看bookinfo.yaml文件

Service mesh 学习06 istio实战_实战_21

需要给productpage暴露的9080端口进行ingress域名绑定

  • 新建productpageIngress.yaml
#ingress
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
 name: productpage-ingress
spec:
 rules:
 - host: productpage.istio.qy.com
   http:
     paths:
     - path: /
       backend:
         serviceName: productpage
         servicePort: 9080

Service mesh 学习06 istio实战_实战_22

Service mesh 学习06 istio实战_实战_23

访问域名地址 http://productpage.istio.qy.com

Service mesh 学习06 istio实战_实战_24

通过IngressGateway访问

确定ip和端口

现在 Bookinfo 服务启动并运行中,需要使应用程序可以从外部访问 Kubernetes 集群,例如使用浏览器。可以用Istio Gateway来实现这个目标。

  • 为应用程序定义 Ingress 网关
kubectl apply -f bookinfo-gateway.yaml -n bookinfo-ns

然后查看gateway

kubectl get gateway -n bookinfo-ns

Service mesh 学习06 istio实战_实战_25

有了gateway之后我们需要配置一些环境变量

配置gateway ip环境

export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
# 把ingressgateway的ip设置成环境变量
kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}'
# 表示获取istio组件ingressgateway组件的ip

获取网关组件的ip

Service mesh 学习06 istio实战_实战_26

配置gateway 端口

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsnotallow='{.spec.ports[?(@.name=="http2")].nodePort}')
kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}'
# 表示获取istio组件ingressgateway组件的端口

Service mesh 学习06 istio实战_实战_27

ip:port设置成环境变量GATEWAY_URL

Service mesh 学习06 istio实战_实战_28

Service mesh 学习06 istio实战_实战_29

Service mesh 学习06 istio实战_实战_30

三、流量管理

放开bookinfo自定义路由权限

destination-rule-all.yaml 这个文件也是起到了一个路由的功能,必须先执行这个文件之后gateway路由规则才可以自定义

执行命令创建路由规则

kubectl apply -f destination-rule-all.yaml -n bookinfo-ns

Service mesh 学习06 istio实战_实战_31

查看destination-rule组件

kubectl get DestinationRule -n bookinfo-ns

Service mesh 学习06 istio实战_实战_32

分析下这个destination-rule-all.yaml文件

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule # 声明了一个资源,这个资源也是需要依赖于crd
metadata:
 name: productpage
spec:
 host: productpage
 subsets:
 - name: v1
   labels:
     version: v1 # 版本
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule  # 声明了一个资源,这个资源也是需要依赖于crd
metadata:
 name: reviews
spec:
 host: reviews
 subsets:
 - name: v1
   labels:
     version: v1 # 版本
 - name: v2
   labels:
     version: v2 # 版本
 - name: v3
   labels:
     version: v3 # 版本
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: ratings
spec:
 host: ratings
 subsets:
 - name: v1
   labels:
     version: v1
 - name: v2
   labels:
     version: v2
 - name: v2-mysql
   labels:
     version: v2-mysql
 - name: v2-mysql-vm
   labels:
     version: v2-mysql-vm
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
 name: details
spec:
 host: details
 subsets:
 - name: v1
   labels:
     version: v1
 - name: v2
   labels:
     version: v2

基于版本控制流量

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v3

此时会把所有的路由的流量全部都切换到v3版本也就是全部都是红星的版本

执行命令

kubectl apply -f virtual-service-reviews-v3.yaml -n bookinfo-ns

Service mesh 学习06 istio实战_实战_33

刷新页面发现只有v3版本页面

Service mesh 学习06 istio实战_实战_34

然后删除路由配置v3

kubectl delete -f virtual-service-reviews-v3.yaml -n bookinfo-ns

再次刷新页面有其它版本了

Service mesh 学习06 istio实战_实战_35

基于权重控制流量

virtual-service-reviews-50-v3.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 50 # 50%的流量到v1
    - destination:
        host: reviews
        subset: v3
      weight: 50 # 50%的流量到v3

执行命令

kubectl apply -f virtual-service-reviews-50-v3.yaml -n bookinfo-ns

Service mesh 学习06 istio实战_实战_36

刷新页面,v1和v3交替出现

删除路由配置

kubectl delete -f virtual-service-reviews-50-v3.yaml -n bookinfo-ns

基于用户来控制流量

virtual-service-reviews-jason-v2-v3.yaml

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v3

在登录的时候会在header头部增加一个jason,如果是jason登录那么会访问v2版本,其它的人访问的是v3

kubectl apply -f virtual-service-reviews-jason-v2-v3.yaml -n bookinfo-ns

Service mesh 学习06 istio实战_实战_37

Service mesh 学习06 istio实战_实战_38

四、故障注入

为了测试微服务应用程序 Bookinfo 的弹性,在访问的的时候会在header头部增加一个jason,如果是jason访问那么会访问v2版本,其它的人访问的是v3。 访问v3版本的人会注入一个50%几率的延迟2S请求访问。

故障注入:可以故意引发Bookinfo 应用程序中的 bug。尽管引入了 2 秒的延迟,我们仍然期望端到端的流程是没有任何错误的。

创建故障注入规则

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - fault:
      delay:
        percent: 50
        fixedDelay: 2s
    route:
    - destination:
        host: reviews
        subset: v3

执行命令

kubectl apply -f test.yaml -n bookinfo-ns

测试

1.通过浏览器打开 Bookinfo 应用。

2.使用headers头部不包含jason, 访问到 /productpage 页面。

3.你期望 Bookinfo 主页在有50%几率大约 2 秒钟加载完成并且没有错误,有50%的几率正常加载

4.查看页面的响应时间

Service mesh 学习06 istio实战_实战_39

五、流量迁移

一个常见的用例是将流量从一个版本的微服务逐渐迁移到另一个版本。在 Istio 中,您可以通过配置一系列规则来实现此目标, 这些规则将一定百分比的流量路由到一个或另一个服务。在本任务中,您将会把 50% 的流量发送到 reviews:v1,另外 50% 的流量发送到 reviews:v3。然后,再把 100% 的流量发送到 reviews:v3 来完成迁移。

Service mesh 学习06 istio实战_实战_40

六、istio的Observe

  • 如果需要metrics收集日志,需要先执行
kubectl apply -f metrics-crd.yaml
kubectl get instance -n istio-system

多次属性页面让metrics收集数据:

现在需要访问普罗米修斯看看有没有拿到metrics收集到的数据,我们可以通过ingress来访问

Service mesh 学习06 istio实战_实战_41

Service mesh 学习06 istio实战_实战_42

Service mesh 学习06 istio实战_实战_43

七、Istio的通信架构

Service mesh 学习06 istio实战_实战_44

Service mesh 学习06 istio实战_实战_45

Service mesh 学习06 istio实战_实战_46

Service mesh 学习06 istio实战_实战_47

Service mesh 学习06 istio实战_实战_48

Service mesh 学习06 istio实战_实战_49

Service mesh 学习06 istio实战_实战_50

Service mesh 学习06 istio实战_实战_51

Service mesh 学习06 istio实战_实战_52

Service mesh 学习06 istio实战_实战_53

八、Istio的超时与重试

Service mesh 学习06 istio实战_实战_54

Service mesh 学习06 istio实战_实战_55

九、Istio熔断器

Service mesh 学习06 istio实战_实战_56

Service mesh 学习06 istio实战_实战_57

Service mesh 学习06 istio实战_实战_58

创建客户端,发送请求

Service mesh 学习06 istio实战_实战_59

拿到容器id

Service mesh 学习06 istio实战_实战_60

Service mesh 学习06 istio实战_实战_61

Service mesh 学习06 istio实战_实战_62

Service mesh 学习06 istio实战_实战_63

503代表请求失败

Service mesh 学习06 istio实战_实战_64

Service mesh 学习06 istio实战_实战_65

十、Istio可视化

Service mesh 学习06 istio实战_实战_66

Service mesh 学习06 istio实战_实战_67

配置Ingress和gateway

export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')

export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')

export GATEWAY_URL=$INGRESS_HOST:$INGRESS_PORT

Service mesh 学习06 istio实战_实战_68

Service mesh 学习06 istio实战_实战_69

Service mesh 学习06 istio实战_实战_70

Service mesh 学习06 istio实战_实战_71

Service mesh 学习06 istio实战_实战_72

Service mesh 学习06 istio实战_实战_73

Service mesh 学习06 istio实战_实战_74

Service mesh 学习06 istio实战_实战_75