服务网格实现之istio设计概要文档

分类:技术

​ istio是服务网格实现方式之一,也是目前开源落地实现service-mesh的比较成熟方案,istio不仅提供了服务之间的流量控制,访问控制策略,还集成了各种链路服务及相关扩展接口,而这一切都是无须上层业务感知的,和业务充分解耦。目前我公司基于阿里云ACM来实现本公司……

前言

项目背景

​ 由于目前我司后端服务架构比较多样化,有用响应式vert.x,有用springboot,语言上有kotlin,java,Rust等,通信有http,gRPC,部署上采用阿里云kubernetes ACK集群部署,此时kubenetes和docker容器化技术到来解决了微服务的容器化管理实现以及微服务的弹性伸缩,但是服务治理方面的挑战也随之而来,采用这套架构目前的短板就是服务治理功能几乎没有,可以采用kubernetes的Ingress网络或者service实现入口服务网关、负载均衡,或者灰度,但是实现方式上都不灵活不优雅,另外grpc服务之间的的流量治理怎么做?不同的开发语言与框架的治理能力差异,治理逻辑与业务逻辑耦合造成的复杂性……有没有用一种非常优雅的方式、无关开发框架语言、不侵入业务代码、让开发只关注于业务实现,服务治理和业务开发完全解耦,那就是目前新一代的微服务实现Service Mesh的落地方案istio。

​ istio不仅提供了服务之间的流量控制,访问控制策略,还集成了各种链路服务及相关扩展接口,而这一切都是无须上层业务感知的,和业务充分解耦。好处是开发只需要关注自己业务开发,通信,负载均衡、限流,降级、熔断,认证安全等都都下沉到底层处理,完全解耦。功能不需要侵入代码,应用服务不需要重启。所以结合我司架构,再加上我司采用kubernetes容器编排方式完全适合使用istio来做服务治理和服务监控来优化架构

名词解释

  • 数据平面

    有一组部署为边车的智能代理(Envoy)组成,代理控制着微服务之间的所有的网络通信,他们还收集和报告所有的网格流量的遥测数据

  • 控制平面

    组件为istiod,负责配置管理数据平面

  • Envoy

    Istio使用的是Envoy代理的扩展版本。Envoy是一个用C++开发的高性能代理,用于调解服务网中所有服务的所有入站和出站流量。Envoy代理是唯一与数据平面流量交互的Istio组件;Envoy代理是作为服务的边车部署的,通过Envoy的许多内置功能逻辑上增强了服务的功能

  • Istiod

    Istiod提供服务发现、配置、证书管理

  • 南北流量管理/东西流量管理

    使用Ingress将Kubernetes中应用暴露成对外提供的服务,针对这个对外暴露的服务可以实现灰度发布,流量管理等,我们把这种流量管理称之为南北流向的流量管理,也就是入口请求到集群服务的流量管理。

    Istio是侧重于集群内服务之间的东西向流量管理,或者称之为服务网格之间的流量管理

由于istio涉及的概念比较多,这里只列出上述基本概念,其它的没有列出的可详见另一篇《isito架构实现及实现特性》学习笔记。

项目目标

​ 在现有公司系统基础上引入istio使后端系统具有服务治理方面的能力,来实现项目架构服务治理和业务开发分开各司其职专注于自己领域内的事情,达到完全解耦。

总体设计

系统概述

由于目前线上环境使用阿里云kubernetes ACK托管版来管理容器集群,所以isito的落地就采用阿里云的服务网格ASM平台来实现。

通过阿里云ASM引入istio,是后端系统集群具有服务治理的能力

流量管理
金丝雀/灰度发布:实现业务从老版本到新版本的平滑过渡,并避免升级过程中出现的问题对用户造成影响

​ 超时、重试、熔断、故障注入:是istio提供的弹性能力,应对故障的一种策略,让系统具有容错和适应能力

​ 流量镜像:镜像会将实时流量的副本发送到镜像服务。这个镜像服务可以是其他另外一个版本指定,可以通过这个镜像流量我们分析高并发产生的问题等

可观测性

​ 分布式链路跟踪:为分布式应用的开发者提供了完整的调用链路还原、调用请求量统计、链路拓扑、应用依赖分析等能力,可以帮助开发者快速分析和诊断分布式应用架构下的性能瓶颈,提升开发诊断效率

​ 通过Kiali对网格实现可观测性:为我们提供了查看相关服务与配置提供了统一化的可视化界面,并且能在其中展示他们的关联;同时他还提供了界面让我们可以很方便的验证 istio 配置与错误提示

系统结构

前言

项目背景

​ 由于目前呼啦亲子的后端服务架构比较多样化,有用响应式vert.x,有用springboot,语言上有kotlin,java,Rust等,通信有http,gRPC,部署上采用阿里云kubernetes ACK集群部署,此时kubenetes和docker容器化技术到来解决了微服务的容器化管理实现以及微服务的弹性伸缩,但是服务治理方面的挑战也随之而来,采用这套架构目前的短板就是服务治理功能几乎没有,可以采用kubernetes的Ingress网络或者service实现入口服务网关、负载均衡,或者灰度,但是实现方式上都不灵活不优雅,另外grpc服务之间的的流量治理怎么做?不同的开发语言与框架的治理能力差异,治理逻辑与业务逻辑耦合造成的复杂性……有没有用一种非常优雅的方式、无关开发框架语言、不侵入业务代码、让开发只关注于业务实现,服务治理和业务开发完全解耦,那就是目前新一代的微服务实现Service Mesh的落地方案istio。

​ istio不仅提供了服务之间的流量控制,访问控制策略,还集成了各种链路服务及相关扩展接口,而这一切都是无须上层业务感知的,和业务充分解耦。好处是开发只需要关注自己业务开发,通信,负载均衡、限流,降级、熔断,认证安全等都都下沉到底层处理,完全解耦。功能不需要侵入代码,应用服务不需要重启。所以结合我司架构,再加上我司采用kubernetes容器编排方式完全适合使用istio来做服务治理和服务监控来优化架构

名词解释

  • 数据平面

    有一组部署为边车的智能代理(Envoy)组成,代理控制着微服务之间的所有的网络通信,他们还收集和报告所有的网格流量的遥测数据

  • 控制平面

    组件为istiod,负责配置管理数据平面

  • Envoy

    Istio使用的是Envoy代理的扩展版本。Envoy是一个用C++开发的高性能代理,用于调解服务网中所有服务的所有入站和出站流量。Envoy代理是唯一与数据平面流量交互的Istio组件;Envoy代理是作为服务的边车部署的,通过Envoy的许多内置功能逻辑上增强了服务的功能

  • Istiod

    Istiod提供服务发现、配置、证书管理

  • 南北流量管理/东西流量管理

    使用Ingress将Kubernetes中应用暴露成对外提供的服务,针对这个对外暴露的服务可以实现灰度发布,流量管理等,我们把这种流量管理称之为南北流向的流量管理,也就是入口请求到集群服务的流量管理。

    Istio是侧重于集群内服务之间的东西向流量管理,或者称之为服务网格之间的流量管理

由于istio涉及的概念比较多,这里只列出上述基本概念,其它的没有列出的可详见另一篇《isito架构实现及实现特性》学习笔记。

项目目标

​ 在现有公司系统基础上引入istio使后端系统具有服务治理方面的能力,来实现项目架构服务治理和业务开发分开各司其职专注于自己领域内的事情,达到完全解耦。

总体设计

系统概述

由于目前线上环境使用阿里云kubernetes ACK托管版来管理容器集群,所以isito的落地就采用阿里云的服务网格ASM平台来实现。

通过阿里云ASM引入istio,是后端系统集群具有服务治理的能力

流量管理
金丝雀/灰度发布:实现业务从老版本到新版本的平滑过渡,并避免升级过程中出现的问题对用户造成影响

​ 超时、重试、熔断、故障注入:是istio提供的弹性能力,应对故障的一种策略,让系统具有容错和适应能力

​ 流量镜像:镜像会将实时流量的副本发送到镜像服务。这个镜像服务可以是其他另外一个版本指定,可以通过这个镜像流量我们分析高并发产生的问题等

可观测性

​ 分布式链路跟踪:为分布式应用的开发者提供了完整的调用链路还原、调用请求量统计、链路拓扑、应用依赖分析等能力,可以帮助开发者快速分析和诊断分布式应用架构下的性能瓶颈,提升开发诊断效率

​ 通过Kiali对网格实现可观测性:为我们提供了查看相关服务与配置提供了统一化的可视化界面,并且能在其中展示他们的关联;同时他还提供了界面让我们可以很方便的验证 istio 配置与错误提示

系统结构

详细设计

金丝雀/灰度发布

实现流程图

![image-20220502121317504](/Users/shuangfan/Library/Application Support/typora-user-images/image-20220502121317504.png)

部署文件编写:

deployment文件

v1和v2版本

apiVersion: apps/v1
kind: Deployment
metadata:
  name: goods-service-v1
  labels:
    app: goods-service
    version: v1     #版本
spec:
  replicas: 1   # 副本数
  selector:
    matchLabels:
      app: goods-service
      version: v1
  template:
    metadata:
      labels:
        app: goods-service
        version: v1
    spec:
      containers:
        - name: goods-service   #容器名字
          image: registry.cn-shenzhen.aliyuncs.com/itfan/goodsservice:v1.0
          imagePullPolicy: Always
          tty: true
          ports:
            - name: grpc
              protocol: TCP
              containerPort: 8053
              
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: goods-service-v2
  labels:
    app: goods-service
    version: v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: goods-service
      version: v2
  template:
    metadata:
      labels:
        app: goods-service
        version: v2
    spec:
      containers:
        - name: goods-service
          image: registry.cn-shenzhen.aliyuncs.com/itfan/goodsservice:v2.0
          imagePullPolicy: Always
          tty: true
          ports:
            - name: grpc
              protocol: TCP
              containerPort: 8053

svc文件

关键点在selector,选择器,也就说所有的流量都会通过svc打到有app标签的deployment里面

apiVersion: v1
kind: Service
metadata:
  name: goods-service
spec:
  type: ClusterIP
  ports:
    - name: grpc
      port: 8053
      targetPort: 8053
  selector:
    app: goods-service   #deployment的label里的标签

DestinationRule

绑定svc

新建subset

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: goods-service
spec:
  host: goods-service  # svc的名字,这里绑定了svc
  subsets:
  - name: v1       #sebset的名字
    labels:
      version: v1  #subset子集要绑定的deployment的标签指定到对应版本
  - name: v2
    labels:
      version: v2

VirtualService

绑定svc

绑定sebset,同时指定流量权重

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: goods-service
spec:
  hosts:
  - goods-service
  http:
  - route:
    - destination:
        host: goods-service     #绑定svc
        subset: v1              #绑定签名定义的sebset子集
      weight: 80                #流量的权重,把80#流量达到v1版本
    - destination:
        host: goods-service
        subset: v2
      weight: 20

注意:如果是通过kuernetes原生的ingress来访问,以上不会生效,必须使用gateway才行

超时/重试

文件结构和上述金丝雀/灰度发布例子类似

只是超时策略是在VirtualService中配置

Istio让您可以轻松地使用虚拟服务在每个服务的基础上动态调整超时/重试而无需编辑您的服务代码

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
    timeout: 10s   #超时配置10s
    retries:       #重试配置,最多三次重试,每次重试超时时间为2秒         
      attempts: 3
      perTryTimeout: 2s

熔断

可以在服务中的各个主机的调用设置限制,如并发连接的数量或对该主机的调用失败的次数,一旦达到该限制,断路器就会“跳闸”

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
    trafficPolicy:     #熔断配置
      connectionPool:
        tcp:
          maxConnections: 100    #将v1子集的reviews服务工作负载的兵法连接数限制为100

故障注入

故障注入是一种将错误引入系统的测试方法,以确保系统能够承受并从错误条件下恢复

故障的注入类型分两种:延迟和终止

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - fault:
      delay:   #延迟故障,这个虚拟服务在每1000个请求中,有一个请求会对服务引入5秒的延迟
        percentage:
          value: 0.1
        fixedDelay: 5s
    route:
    - destination:
        host: ratings
        subset: v1

流量镜像

在一些高并发等测试中排查问题中很有用

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: httpbin
spec:
  hosts:
    - httpbin
  http:
  - route:
    - destination:
        host: httpbin
        subset: v1
      weight: 100
    mirror:          #流量100%的打到v1版本通过流量镜像,同时还会把流量100%的打到v2中
      host: httpbin
      subset: v2
    mirror_percent: 100