service-mesh

01 架构的发展历史

1.1单机小型时代
1.2 垂直坼分
1.3 集群化负载均衡架构
用户量越来越大,就意味着需要更多的小型机,但是小型机价格昂贵,操作维护成本高。
此时更优的选择是采用多个 pc 机部署同一个应用的方案,但是此时就需要对这些应用做负载均衡,因为客户端不知道请求会落到哪一个后端 pc 应用上的。
负载均衡可以分为硬件层面和软件层面。
硬件层面:F5
软件负载层面:LVS,NGINX,Haproxy
负载均衡的思想:对外暴露一个统一的接口,根据用户的请求进行对应规则转发,同时负载均衡还可以做限流等等
有了负载均衡之后,后端的应用可以根据流量的大小进行动态扩容,我们称之为“水平扩容”
阿里巴巴在2008年提出去"IOF",也就是 IBM 小型机,Oracle数据库,EMC存储,全部改成集群化负载均衡架构,在2013年支付宝最后一台IBM小型机下线。
优点: 应用跟应用解耦,系统容错提高了,也解决了独立应用发布的问题,同时可以水平扩展来提供应用的高并发量。

1.4服务化改造架构
虽然系统经过了垂直坼分,但是坼分之后发现在论坛和聊天室中有重复的功能,比如,登录功能,用户注册,发邮件等等,一旦项目大了,集群部署多了,这些重复的功能无疑会造成资源浪费,所以会把重复功能抽取出来,名字叫“xx服务(Service)”
为了解决服务跟服务如何相互调用,需要一个程序之间的通信协议,所以就有了远程调用(RPC),作用就是让服务之间的程序调用变得像在本地调用一样的简单。
优点:在前面的架构之上解决了业务重用的问题。
服务发现
服务注册
服务熔断,降级
负载均衡

1.5 服务治理
随着业务的增大,基础服务越来越多,调用网的关系由最初的几个增加到机十个,造成了调用链路错综复杂,需要对服务进行治理。
服务治理要求:
1.当我们服务节点数几十上百的时候,需要对服务动态的感知,引入了注册中心
2,当服务链路调用很长的时候如何实现链路的监控
3,单个服务的异常,如何能避免整条链路的异常(雪崩),需要考虑熔断,降级,限流
4.服务高可用:负载均衡
​
典型框架比如有: Dubbo,默认采用的是 zookeeper作为注册中心

1.6 微服务时代
分布式微服务
微服务是在2012年提出,微服务的希望的重点是一个服务只负责一个独立的功能。
坼分原则,任何一个需求不会因为发布或者维护而影响到不相关的服务,一切可以做到独立部署。
比如传统的"用户中心"服务,对于微服务来说,需要根据业务再次撤分,可能需要撤分成"买家服务",“卖家服务”,“商家服务” 等
典型代表: spring cloud,相对于传统分布式架构,Springcloud使用的是HTTP作为RPC远程调用,配合上注册中心 Eureka 和 API网格 Zuul,可以做到细分内部访问的同时又可以对外暴露统一的接口,让外部对系统内部架构无感,此外,Spring Cloud 的 config组件还可以把配置统一管理
马丁大师对微服务的定义:
https://martinfowler.com/articles/microservices.html
典型框架:spring cloud
通信协议: HTTP
注册中心: Eureka
API网关: zuul
配置中心: config
​
回想一下 spring cloud 是怎么解决服务通信,服务治理?
1.业务代码里面: 加上 maven 依赖,加上注解,加上配置---打成 jar 的时候,还需要把这些业务代码也要融合在一起。
2.开发人员要投入很大的精力来学习 spring cloud
3.微服务是多语言调用,维护成本高,
4.微服务坼分越细,感觉是轻量级,维护成本很高。
​

1.7 服务网格新时期 (service mesh)
1.7.1 背景
早期 我们最开始用 spring+springMVC+Mybatis 写业务
微服务时代
微服务时代有了 spring cloud 就完美了吗?不妨想一想会有哪些问题?
1.最初是为了业务而写代码,比如登录功能,支付功能等,到后面会发现要解决网络通信的问题,虽然有 spring cloud 里面的组件帮我们解决了,但是细想一下是怎么解决的?在业务代码里面加上 spring cloud maven 依赖,加上spring cloud 组件注解,写配置,打成 jar 的时候还必须要把业务的代码也要融合在一起,称为"侵入式框架";
2.微服务中支持不同的语言开发,也需要维护不同语言和非业务代码成本;
3.业务代码开发者应该把更多的精力投入到业务熟悉度上,而不应该是非业务上,spring cloud 虽然能解决微服务领域的很多问题,但是学习成本还是较大的;
4.互联网公司产品的版本升级是非常频繁的,为了维护各个版本的兼容性,权限,流量等,因为 spring cloud 是“代码侵入式的框架”,这时候版本的升级就注定要让非业务代码一起,一旦出现问题,再加上多语言之间的调用,工程师是非常痛苦的;
5.其实我们到目前为止应该感觉到了,服务坼分得越细,只是感觉上是轻量级解耦了,但是维护成本却越高了,那么怎么办呢?网络的问题还是要交给网络本身来解决


问题解决思路:
# 本质上是要解决服务之间通信的问题,不就该非业务的代码融合到业务代码中
# 也就是从客户端发出的请求,要能够顺利到达对应的服务,这中间的网络通信的过程要和业务代码尽量无关


服务通信无非就是:
服务发现,
负载均衡,
版本控制等等

# 在很早之前的单体架构中,其实通信问题也是需要些在业务代码中的,那时候是怎么解决通信问题的?
早期我们在写代码的时候,将网络协议,流量控制,数据包接送,发送等问题都写入代码中一起解决,后来我们就网络功能,流量处理等业务处理下沉到网络七层模型,TCP,UDP层网络转发非业务代码功能下沉到计算机网络模型中
网络功能处理下沉网络七层模型:
1. 应用层
2. 表示层
3. 会话层
4. 传输层
5. 网络层
6. 数据链路层
7. 物理层
1.7.2 SideCar
A服务
业务代码
sidecar(负载,限流,服务发现)
​
B服务
业务代码
sidecar(负载,限流,服务发现)
​
最后AB服务通信是通过 sidecar(代理) 来解决
sidecar 比代理功能更加丰富,他支持负载,限流,服务发现等
​
sidecar 解决了微服务架构相关的复杂性,并且提供了负载均衡,服务发现,流量管理,电路中断,遥测,故障注入等功能特性
sidecar模式是以这种应用(网络通信)功能从应用本身剥离出来作为单独进程的方式,该模式允许我们向应用无侵入添加功能,避免了为满足第三方组件需求添加额外配置代码。
​
sidecar的探索之路:
很多公司借鉴了 proxy 模式,推出了 sidecar 的产品,比如 
2014年 Netflix 的 Prana,
2015年 唯品会发布了 local proxy
2016年 twitter 发布第一款 service Mesh项目: linkerd
蚂蚁金服的 SofaMesh
​
​
服务业务代码与 sidecar 绑定在一起,每个服务都配置了一个sidecar代理,每个服务所有的流量都经过 sidecar,sidecar帮我们屏蔽了通信的细节,我的业务开发人员只需要关注业务就行了,而通信的事情交给sidecar处理。
​
总结:可以理解成是代理,(管理服务的进出口流量,对流量有一定的治理功能)控制了服务的流量的进出,sidecar是为了通用基础设施而设计,可以做到与公司框架技术无侵入性。

1.7.3 linkerd
2016年1月,离开 Twitter 的基础设施工程师打造的一个服务网格项目,第一个 Service Mesh 项目由此诞生,解决通用性,
linkerd 很好地结合了 kubernetes 所提供的功能,以此为基础,在每个 kubernetes Node上都部署运行一个 linkerd 实例,用代理的方式将加入 Mesh 的 Pod 通信转接给 Linkerd,这样 Linkerd就能在通信链路中完成对通信的控制和监控。
​
linkerd设计思路:
linkerd在 sidecar 基础上增加了数据上报,日志收集,还增加了链路的监控,也是一款无需侵入到应用的内部,就能够管理服务的流量,并且 linkerd 能兼容 kubernetes 提供的所有功能。
每一个服务都有一个 sidecar.所有的流量都通过 sidecar,而服务无需关心通信的问题,linkerd 的设计思想与 sidecar 很相似,他的目标也是来屏蔽网络通信的细节。
linkerd 的优点: 
1. 他无需侵入业务代码就可以进行通信(服务流量管理)管理-无须侵入工作负载的代码,直接进行通信监视和管理
2. 他能够兼容 kubernetes 提供的所有功能,还支持多种底层平台
3. 提供了统一的配置方式,用于管理服务之间的通信和边缘通信

linkerd 由 Scala 编写 官网地址

https://github.com/linkerd/linkerd
https://github.com/linkerd/linkerd/releases/tag/1.7.5
https://github.com/linkerd/linkerd/archive/refs/tags/1.7.5.tar.gz

# 下载
root@ubuntu:~# ls
index.html  snap  yueyang-cloud-main  yueyang-cloud-main.tar.gz
root@ubuntu:~# wget https://github.com/linkerd/linkerd/archive/refs/tags/1.7.5.tar.gz
--2024-04-10 00:15:17--  https://github.com/linkerd/linkerd/archive/refs/tags/1.7.5.tar.gz
Resolving github.com (github.com)... 20.205.243.166
Connecting to github.com (github.com)|20.205.243.166|:443... connected.
HTTP request sent, awaiting response... 302 Found
Location: https://codeload.github.com/linkerd/linkerd/tar.gz/refs/tags/1.7.5 [following]
--2024-04-10 00:15:18--  https://codeload.github.com/linkerd/linkerd/tar.gz/refs/tags/1.7.5
Resolving codeload.github.com (codeload.github.com)... 20.205.243.165
Connecting to codeload.github.com (codeload.github.com)|20.205.243.165|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [application/x-gzip]
Saving to: ‘1.7.5.tar.gz’

1.7.5.tar.gz                                [    <=>                                                                       ]   1.03M  1.26MB/s    in 0.8s

2024-04-10 00:15:19 (1.26 MB/s) - ‘1.7.5.tar.gz’ saved [1079951]

root@ubuntu:~# ls
1.7.5.tar.gz  index.html  snap  yueyang-cloud-main  yueyang-cloud-main.tar.gz
root@ubuntu:~# tar -zvxf 1.7.5.tar.gz
linkerd-1.7.5/
linkerd-1.7.5/.circleci/
linkerd-1.7.5/.circleci/config.yml
linkerd-1.7.5/.github/
linkerd-1.7.5/.github/CODEOWNERS
linkerd-1.7.5/.gitignore

root@ubuntu:~# ls
1.7.5.tar.gz  index.html  linkerd-1.7.5  snap  yueyang-cloud-main  yueyang-cloud-main.tar.gz
root@ubuntu:~# cd linkerd-1.7.5/
root@ubuntu:~/linkerd-1.7.5# ls
admin        ci                  CONTRIBUTING.md  GOVERNANCE.md      istio        linkerd         namer       protoc     telemetry
ADOPTERS.md  CODE_OF_CONDUCT.md  DCO              grpc               istio-proto  MAINTAINERS.md  namerd      README.md  test-util
BUILD.md     config              etcd             interpreter        k8s          marathon        PLUGINS.md  router     validator
CHANGES.md   consul              finagle          ISSUE_TEMPLATE.md  LICENSE      mesh            project     sbt
root@ubuntu:~/linkerd-1.7.5#

总结:

1. 帮我们屏蔽了通信细节

2. 无须接入代码内部

3. 兼容 kubernetes

缺点:

1. 部署繁琐

2. 只是实现了数据层面的问题,没有实现对数据层面进行管理问题

数据层面:通过 sidecar 解决了数据处理问题

1.7.4 istio

控制平面:管理数据平面(sidecar)

istio 由 Google,IBM,和Lyft 共同发起的开源项目 由 go 语言编写

istio 即有数据平面也有控制平面

linkerd 只有数据平面

官网下载地址:
https://github.com/istio/istio/releases/download/1.21.1/istio-1.21.1-linux-amd64.tar.gz

1.7.5 什么是服务网格
服务网格:指的是微服务应用之间的交互,随着规模和复杂性的增加,服务跟服务调用错综复杂。
现代应用程序通常被架构为微服务的分布式集合,每个微服务集合都执行一些离散的业务功能。服务网格是可以添加到应用程序中的专用基础架构层。它允许您透明地添加可观测性、流量管理和安全性等功能,而无需将它们添加到您自己的代码中。术语“服务网格”既描述了用于实现此模式的软件类型,也描述了使用该软件时创建的安全域或网络域。
随着分布式服务的部署(例如在基于 Kubernetes 的系统中)的规模和复杂性不断增长,它可能变得更加难以理解和管理。其要求可能包括发现、负载均衡、故障恢复、指标和监视。服务网格通常还可以满足更复杂的操作要求,例如 A/B 测试、金丝雀部署、速率限制、访问控制、加密和端到端身份验证。
服务到服务通信使分布式应用程序成为可能。随着服务数量的增加,在应用程序集群内和应用程序集群之间路由此通信变得越来越复杂。Istio 有助于降低这种复杂性,同时减轻开发团队的压力。
如果每一个格子都是一个 sidecar 数据平面,然后 sidecar 进行彼此通信,那么 servicermesh就是来管理每个格子的控制平面,这就是服务网格,从架构层面看起来跟网格很像。

特点

1.基础设施:服务网格是一种处理服务之间通信的基础设施层

2. 支撑云原生:服务网格尤其适用于在云原生场景下帮助应用程序在复杂的服务间可靠地传递请求。

3. 网络代理:在实际使用中,服务网格,一般是通过一组轻量级网络代理来执行治理逻辑的。

4. 对应用透明:轻量级网络代理与应用程序部署在一起,但应用感知不到代理的存在,还是使用原来的方式工作。

1.7.6 什么是 Service Mesh

istio 就是 service Mesh 的一个框架

istio官网 也对什么是service mesh 给出了定义,地址如下
https://istio.io/latest/about/service-mesh/#yyhy-use-istio
https://istio.io/docs/concepts/what-is-istio/#what-is-a-service-mesh
https://istio.io/latest/about/service-mesh/#what-is-a-service-mesh
​
​
解决微服务之间服务跟服务之间通信的问题,可以包括服务发现,负载平衡,故障恢复,度量和监视,服务网格通常还具有更复杂的操作需求,如A/B测试,速率限制,访问控制和端到端身份验证。

1.7.7 CNCF云原生组织发展和介绍

云原生发展历史时间轴

微服务->kubernetes->linkerd->Envoy->Istio->

# 微服务
马丁大师在2014年定义了微服务
# kubernetes
从2014年6月有Google正式开源,到2015年7月发布1.0这个正式版本并加入CNCF基金会,再到2018你3月从CNCF基金会毕业,迅速成为容器编排领域的标准,是开源历史上发展最快的项目之一。
# linkerd
Scala语言编写,运行在JVM中,Service Mesh名词的创造者
2016年01月15号,0.0.7发布
2017年01月23号,加入CNCF组织
2017年04月25号,1.0版本发布

# Envoy
envoy是一个开源的服务代理,为云原生设计的程序,由C++语言编程[Lyft]
2016年09月13号,1.0发布
2017年09月14号,加入CNCF组织

# Istio
Google,IBM,Lyft发布0.1版本
Istio是开源的微服务管理,保护和监控框架,Istio为希腊语,意思是"起航"。

CNCF介绍

CNCF 是一个开源软件基金会,致力于使云原生计算具有普遍性和可持续性。云原生计算使用开源软件技术栈将应用程序部署为微服务,将每个部分打包到自己的容器中,并动态编排这些容器以优化资源利用率。云原生技术使软件开发人员能够更快地构建出色的产品。

CNCF解决了什么问题

  • 统一基础平台: kubernetes

  • 如果我们需要日志监控:Prometheus

  • 需要代理:Envoy

  • 需要分布式链路跟踪:jaeger

  • ...

地址:Cloud Native Computing Foundation

介绍几个常用的已经毕业的云原生项目

  • kubernetes

kubernetes 是世界上最受欢迎的容器编排平台也是第一个CNCF项目,kubernetes 帮助用户构建,扩展和管理应用程序及其生命周期。

  • Prometheus

Prometheus 为云原生应用程序提供实时监控,警报包括强大的查询和可视化能力,并与许多流行的开源数据导入,导出工具集成。

1.7.8 国内兴起的服务网格
前面提到,在Service Mesh 这个概念得到具体定义之前,实际上已经有很多厂商开始了微服务新的尝试,这一动作势必引发对微服务治理的强劲需求,在 Service Mesh概念普及之后,有的厂商意识到自身产品也具备 Service Mesh 的特征,也有厂商受其启发,将自有的服务治理平台进行完善和改造,推出自己的 Service Mesh产品,例如,蚂蚁金服,腾讯和华为推出自己的网格产品,华为的产品甚至已被投入公有云进行商业应用。

02 Istio 基本介绍

2.1 什么是istio
官网地址:
https://istio.io/
​
服务网格是一个独立的基础设施层,用来处理服务之间的通信。现代的云原生应用是由各种复杂技术构建的服务体系,服务网格负责在这些组成部分之间进行可靠的请求传递。目前典型的服务网格通常提供了一组轻量级的网络代理,这些代理会在应用无感知的情况下,同应用并行部署,运行。
​
前面提到,Istio出自名门,由Google,IBM 和 Lyft 在2017年5月合作推出,他的初始设计目标是在 kubernetes 的基础上,以非侵入的方式为运行在集群中的微服务提供流量管理,安全加固,服务监控和策略管理等功能。
​
Istio有助于降低部署的复杂性,并减轻开发团队的压力,他是一个完全开放源代码的服务网格,透明地分层到现有的分布式应用程序上,他也是一个平台,包括允许它集成到任何日志平台,遥测或策略系统中的api,istio的多种功能集使我们能够成功,高效地运行分布式微服务体系结构,并提供一种统一的方式来保护,连接和监控微服务。

Istio 服务网格

Istio 解决了开发人员和运维人员在分布式或微服务架构方面面临的挑战。无论您是从头开始构建还是将现有应用程序迁移到云原生,Istio 都可以提供帮助。
官网地址:
https://istio.io/docs/concepts/what-is-istio/#yyhy-use-istio
Istio 是一个开源服务网格,它透明地分层到现有的分布式应用程序上。Istio 的强大功能提供了一种统一且更有效的方式来保护、连接和监控服务。Istio 是实现负载均衡、服务到服务身份验证和监控的途径——很少或根本没有服务代码更改。其强大的控制平面带来了重要的功能,包括:
  • 通过 TLS 加密、基于身份的强身份验证和授权,在集群中实现安全的服务到服务通信
  • HTTP、gRPC、WebSocket 和 TCP 流量的自动负载均衡
  • 通过丰富的路由规则、重试、故障转移和故障注入对流量行为进行细粒度控制
  • 支持访问控制、速率限制和配额的可插拔策略层和配置 API
  • 集群内所有流量(包括集群入口和出口)的自动指标、日志和跟踪
Istio 专为可扩展性而设计,可以处理各种部署需求。Istio 的控制平面在 Kubernetes 上运行,您可以将部署在该集群中的应用程序添加到您的网格中,将网格扩展到其他集群,甚至连接在 Kubernetes 之外运行的虚拟机或其他端点。
一个由贡献者、合作伙伴、集成和分销商组成的大型生态系统扩展和利用 Istio 用于各种场景。 您可以自己安装 Istio,或者许多供应商都有集成 Istio 的产品并为您管理它。

istio是如何工作的

Istio 有两个组件:数据平面和控制平面。

数据平面是服务之间的通信。如果没有服务网格,网络就无法理解发送的流量,也无法根据流量类型或来自或发往谁来做出任何决策。

服务网格使用代理来拦截所有网络流量,从而允许根据您设置的配置提供广泛的应用程序感知功能。

Envoy 代理与您在群集中启动的每个服务一起部署,或与在 VM 上运行的服务一起运行。

控制平面采用所需的配置及其服务视图,并动态编程代理服务器,随着规则或环境的变化更新它们。

Istio是基于 Sidecar 模式,数据平面和控制平面,是主流 Service Mesh 解决方案。

2.2 istio 的特征
官网地址:
https://istio.io/zh/
​
# 连接:对网格内部的服务之间的调用所产生的流量进行智能管理,并以此为基础,为微服务的部署,测试和升级等操作提供了有力保障。对服务之间通信进行管理,而通信又分为内部的服务通信和外部的服务通信,还有内部服务访问外部服务的通信。通信是整个微服务中用于维持服务运行的重要环节。
# 安全: 为网络内部的服务之间的调用提供认证,加密和鉴权支持,在不侵入代码的情况下,加固现有服务,提高其安全性。指的是在网格内部,服务的通信都是进行了加密。
# 策略:在控制平面定制策略,并在服务中实施。例如我们要对频率进行限制,对服务进行限制,要对服务的内容进行限制,
# 观察:对服务之间的调用进行跟踪和测量,获取服务的状态信息。说白了就是对服务进行监控。

下面对这些特征性质展开详细描述。

2.2.1 连接
微服务错综复杂,要完成其业务目标,连接问题是通信问题。连接存在于所有服务的整个生命周期中,用于维持服务的运行,算得上重中之重。
相对于传统的单体应用,微服务的端点数量会急剧增加,现代的应用系统在部分或者全部生命周期中,都存在同一服务的不同版本,为不同的客户,场景或者业务提供不同的服务。同时,同一服务的不同版本也可能有不同的访问要求,甚至产生了在生产环境中进行测试的新方法论。错综复杂的服务关系对开发者来说都是很严峻的考验。

针对目前的常见业务形态,这里画一个简单的示意图来描述 Server Mesh 的连接功能

从不同的外部用户的角度来看,他们访问的都是同一服务端口,但实际上会因为不同的用户识别,分别访问服务A的不同版本;在网格内部,服务A的版本1可能会访问服务B的两个版本,服务A的版本2则只会访问服务B的版本1;服务B的版本1需要访问外部的云服务,版本2则无此需求。
在这个简化的模型中,包含了以下诉求来:
1. 网格内部的调用(服务A->服务B);
2. 出站连接(服务B->外部云服务)
3.入站连接(用户->服务A);
4.流量分割(A服务跟B服务只负责与自己相关流量请求);
5. 按调用方的服务版本进行路由(服务A的版本1分别调用了服务B的版本1和版本2);
6. 按用户身份进行路由


这里除了这些问题,还存在一些潜在需求,如下所述。
1.在网格内部的服务之间如何根据实际需要对服务间调用进行路由,条件可能包括:
a. 调用的源和目的服务;
b. 调用内容;
c.认证身份;
2.如何应对网络故障或者服务故障。
3. 如何处理不同服务不同版本之间的关系。
4.动态流量分配,根据对流量特征的识别,在不同的服务和版本之间对流量进行引导。


连接是服务网格应用过程中从无到有的最重要的一个环节。
2.2.2 安全
安全也是一个常读常新的话题,在过去私有基础设施结合单体应用的环境下,这一问题并不突出,然而进入容器云时代之后,以下问题出现了。
1.有大量容器漂浮在容器云中,采用传统的网络策略应对这种浮动的应用是比较吃力的。
2. 在由不同的语言,平台所实现的微服务之间,实施一致的访问控制也经常会因为实现的不一致而困难重重,
3.如果是共享集群,则服务的认证和加密变得尤为重要,例如:
    a.服务之间的通信要防止被其他服务监听;
    b.只有提供有效身份的客户端才可以访问指定的服务;
    c.服务之间的相互访问应该提供更细粒度的控制功能。
    
总之,要提供网格内部的安全保障,就应具备服务通信加密,服务身份认证和服务访问控制(授权和鉴权)功能。上述功能通常需要数字证书的支持,这就是隐藏了对CA的需求,即需要完成证书的签发,传播和更新业务。
除了上述核心要求,还存在对认证失败的处理,外部证书(统一CA)的接入等相关支撑内容,

2.2.3 策略
Istio 通过可动态插拔,可扩展的策略实现访问控制,速率限制,配额管理等功能使得资源在消费者之间公平分配
​
在 Istio 中使用 Mixer 作为策略的执行者,Envoy 的每次调用,在逻辑上都会通过 Mixer进行事先预检和事后报告,这样 Mixer 就拥有了对流量的部分控制能力;在 Istio 中还有为数众多的内部适配器及进程外适配器,可以和外部软件设施一起完成策略的制定和执行。

组件简单介绍,后面会详细讲解

Mixer: Mixer 在整个服务网格中执行访问控制和策略执行,并从Envoy代理和其他服务收集遥测数据。

Envoy: 在 istio框架中使用 Envoy 作为代理,使用的是C++开发的软件,用于为服务网格中的所有服务提供所有的入站和出站流量,唯一一个与数据平面打交道的

2.2.4 观察(就是监控)
随着服务数量的增加,监控和跟踪需求自然水涨船高。在很多情况下,可观察的保障都是系统功能的重要组成部分,是系统运维功能的重要保障。
随着廉价服务器(相对于传统小型机)的数量越来越多,服务器发生故障的频率也越来越高,人们开始产生争论:我们应该将服务器视为家畜还是宠物?家畜的特点:是有功能的,无个性,可替换;而宠物的特点:是有功能的,有个性,难替换。
我们越来越倾向于将服务器视为无个性,可替换的基础设施,如果主机发生故障,那么直接将其替换即可;并且,我们更加关注的是服务的总体质量。因此,微服务系统监控,除了有传统的主机监控,还更加重视高层次的服务健康监控。
服务的健康情况往往不是非黑即白的离散值,而是一系统连续状态,例如我们经常需要关注服务的调用成功率,响应时间,调用量,传输量等表现。
而且,面对数量众多的服务,我们应该能对各种级别和层次的指标进行采样,采集级汇总,获取较为精密,详实的运行数据,最终通过一定的方法进行归纳总结和展示。
与此同时,服务网格还应提供分布式跟踪功能,对服务的调用链路进行跟踪。
观察性:动态获取服务运行数据和输出,提供强大的调用链,监控和调用日志收集输出的能力,配合可视化工具,可方便运维人员了解服务的运行状况,发现并解决问题。
​

2.3 Istio与服务治理
Istio是一个服务治理平台,治理的是服务间的访问,只要有访问就可以治理,不在乎这个服务是不是所谓的微服务,也不要求跑的代码是微服务化的。单体应用部满足微服务用 Istio 治理也是完全可以的。提起"服务治理",大家最先想到的一定是"微服务的服务治理",就让我们从微服务的服务治理说起。

2.3.1 服务治理的三种形态

服务治理的演变至少经过了以下三种形态。

第1种形态: 在应用程序中包含治理逻辑

在微服务化的过程中,将服务坼分后会发现一推麻烦事儿,连基本的业务连通都成了问题。在处理一些治理逻辑,比如怎么找到对端的服务实例,怎么选择一个对端实例发出请求,都需要自己写代码来实现。这种方式简单,对外部依赖少,但会导致存在大量的重复代码,所以,微服务越多,重复的代码越多,维护越难,而且,业务代码和治理逻辑耦合,不管是对治理逻辑的全局升级,还是对业务的升级,都要改同一段代码。

第2种形态:治理逻辑独立的代码

在解决第1种形态的问题时,我们很容易想到把治理的公共逻辑抽象成一个公共库,让所有微服务都使用这个公共库。在将这些治理能力包含在开发框架中后,只要是用这种开发框架开发的代码,就包含这种能力,非常典型的这种服务治理框架就是 spring cloud.这种形态的治理工具在过去一段时间里得到了非常广泛的应用。
SDK模式虽然在代码上解耦了业务和治理逻辑,但业务代码和 SDK 还是要一起编译的,业务代码和治理逻辑还在一个进程内。这就导致几个问题,业务代码必须和 SDK 基于同一种语言,即语言绑定。例如 Spring cloud等大部分治理框架都基于Java,因此也只适用于Java语言开发的服务。经常有客户抱怨自己基于其他语言编写的服务没有对应的治理框架;在治理逻辑升级时,还需要用户的整个服务升级,即使业务逻辑没有改变,这对用户来说是非常不方便的。

第3种形态:治理逻辑独立的进程

SDK模式仍旧侵入了用户的代码,那就再解耦一层,把治理逻辑彻底从用户的业务代码中剥离出来,这就是前面提过的 sidecar模式,显然,在这种形态下,用户的业务代码和治理逻辑都以独立的进程存在。两者的代码和运行都无耦合。这样可以做到与开发语言无关,升级也相互独立。在对已存在的系统进行微服务治理时,只需搭配 sidecar 即可。对原服务无须做任何修改,并且可以对老系统渐进式升级改造,先对部分服务进行微服务化。
2.4 istio 与 kubernetes
2.4.1 kubernetes 介绍
kubernetes 是一款用于管理容器化工作的负载和服务的可移植,可扩展的开源平台,拥有庞大,快速发展的生态系统,它面向基础设施,将计算,网络,存储等资源进行紧密整合,为容器提供最佳运行环境,并面向应用提供封装好的,易用的工作负载与服务编排接口,以及运维所需的资源规格,弹性,运行参数,调度等配置管理接口,是新一代的云原生基础设施平台。
从平台架构而言,kubernetes 的设计围绕平台化理念,强调插件化设计与易扩展性,这是它与其他同类系统的最大区别之一,保障了对各种不同客户应用场景的普遍适应性。另外,kubernetes 与其他容器编排系统的显著区别是 kubernetes 并不把无状态化,微服务化等条件作为可运行的工作负载的约束。
如今,容器技术已经进入产业落地期,而 kubernetes 作为容器平台的标准已经得到了广泛应用。
​
容器可以被kubernete管理和编排,kubernetes可以构建计算,网络,存储的云平台,为云原生提供了基础设施平台,kubernetes提供了非常强大的应用负载部署升级扩容等运行管理能力,例如kuberntes组件service 已经可以来做服务发现服务注册和负载均衡,从微服务的观点来看,kubernetes本身是支持微服务架构,也解决了微服务的互访互通问题
所以在pod中部署微服务也是非常合适的,
kubernetes是支持微服务的,解决了微服务互访互通问题,
pod是kubernetes运行的最小单位,
kubernetes 不支持服务治理功能,怎么办呢?加入 istio
istio是kubernetes的好帮手,可以帮助 kubernetes 实现治理功能,
istio 可以弥补 kubernetes 的不足。
istio 是从底层实现对上层服务访问的治理解决方案,这就是解释了istio是kubernetes的好帮手。
​
kubernetes可以帮 istio 实现什么呢?
istio需要利用 kubernetes 这个基础设施平台,来实现一些其他功能,比如:
1.数据平面
2.统一服务发现
3.基于kubernetes CRD规则,扩展自定义资源
下面我们来学习 istio如何利用 kubernetes 实现数据平面
​
​
2.4.2 Istio 是 kubernetes 的好帮手
从场景来看,kubernetes 已经提供了非常强大的应用负载的部署,升级,扩容等运行管理能力,kubernetes 中的 Service 机制也已经可以服务注册,服务发现和负载均衡,支持通过服务名访问到服务实例。
从微服务的工具集观点来看,kubernetes 本身是支持微服务的架构,在 Pod 中部署微服务很合适,也已经解决了微服务的互访互通问题,但是对服务间访问的管理如服务的熔断,限流,动态路由,调用链路追踪等都不在 kubernetes 的能力范围内,那么,如何提供一套从底层的负载部署运行到上层的服务访问治理端到端的解决方案?
目前,最完美的答案就是在 kubernetes 上叠加 Istio 这个好帮手。

2.4.3 Kubernetes 是 istio 的 好基座
  • Istio最大化利用了 kubernetes 这个基础设施,与之叠加在一起形成了一个更强大的用于进行服务运行和治理的基础设施,充分利用了 kubernetes 的优点实现 istio 的功能,例如:
    ​
    1.数据面
    数据面 sidecar 运行在 kubernetes 的 pod 里,作为一个 Proxy 和业务容器部署在一起,在服务网格的定义中要求应用程序在运行的时感知不到 sidecar 的存在,而基于 kubernetes 的一个 pod 多个容器的优秀设计使得部署运维对用户透明,用户甚至感知不到部署 sidecar 的过程,用户还是用原有的方式创建负载,通过 Istio 的自动注入服务,可以自动给指定的负载注入 Proxy,如果在另一种环境部署和使用 Proxy,则不会有这样的便利。
    2. 统一服务发现
    Istio 的服务发现机制非常完美地基于 kubernetes 的域名访问机制构建而成,省去了再搭一个类似 Eureka 的注册中心的麻烦,更避免了在 kubernetes 上运行时服务发现数据不一致的问题。
    3.基于 kubernetes CRD描述规则
    Istio 的所有的路由规则和控制策略他都要基于 kubernetes CRD原则来进行实现,因此各种规则策略对应的数据也被存储在 kube-apiserver 中,不需要另外一个单独的 APIServer 和 后端的配置管理。所以设 Istio的 PAIServer 就是 kubernetes 的 APIServer,数据也自然地被存储在了对应的 kubernetes 的 etcd 中。
    Istio非常巧妙地应用了 kubernetes 这个好基座,基于 Kubernetes 的已有能力来构建自身功能,kubernetes 里已经有的,绝不再自己搞一套,避免了数据不一致和用户使用体验的问题。
    Istio 和 kunernetes 架构的关系,可以看出,Istio 不仅数据面 Envoy 跑在 kubenetes 的 pod 里,其控制面也运行在 kubernetes 集群中,其控制面组件本身存在的形式也是以 Kubernetes Deployment 和 Service,基于 kubernetes 扩展和构建。
    ​
    ​
    ​
    回顾一下上面提到的 k8s 组件
    1.APIServer
    API Server 提供了 k8s 各类资源对象 (pod,RC,Service等)的增删改查及watch等HTTP Rest接口,是整个系统的数据总线和数据中心。
    Kubernetes API Server 的功能:
    -提供了集群管理的 REST API接口(包括认证授权,数据效验以及集群状态变更);
    -提供其他模块之间的数据交互和通信的枢纽 (其他模块通过 API Server查询或修改数据,只有API Server才直接操作 etcd);
    -是资源配额控制的入口;
    -拥有完备的集群安全机制。
    ​
    2.Deployment
    一旦运行了 kubernetes 集群,就可以在其上部署容器化应用程序。为此,需要创建 kunernetes Deployment 配置
    ​
    Deployment 负责 kubernetes 如何创建和更新应用程序的实例。
    ​
    3.Service
    Service 可以看作是一组提供相同服务的 pod 对外的访问接口。借助 Service , 应用可以方便地实现和负载均衡
    ​
    4.Ingress
    Ingress 是 kubernetes 资源的一种,可以让外部请求访问到 k8s 内部的资源上
    ​
    ​
    总结:
    kubernetes 在容器编排领域已经成为无可争辩的事实标准;微服务化的服务与容器在轻量,敏捷,快速部署运维等特征上匹配,这类服务在容器中的运行也正日益流行;随着 Istio 的成熟和服务网格技术的流行,使用 Istio 进行服务治理的实践也越来越多,正成为服务治理的趋势;而 Istio 与 Kubernetes 的天然融合且基于 kubernetes 构建,也补齐了 kubernetes 的治理能力,提供了端到端的服务运行治理平台。这都使得 Istio,微服务,容器及 kubernetes形成一个完美的闭环。
    ​
    云原生应用采用 kubernetes 构建应用编排能力,采用 Istio 构建服务治理能力,将逐渐成为企业技术转型的标准配置。
    ​
    1.数据平面
    数据平面通过 sidecar 来解决数据流量的问题 
    sidecar 是运行在kubernetes 的 pod 里面
    业务容器也是运行在 pod 里面
    业务容器是感知不到 sidecar 的存在
    pod 里面已经运行了 业务容器,为什么还可以运行 sidecar容器呢?说白了就是利用一个 pod 里面可以运行多个容器原理特点来实现数据平面(利用pod可以运行多个容器的特点来实现数据平面的功能)功能。
    pod 里面可以运行业务容器,同时可以注入代理容器(sidecar)。
    2. 统一服务发现
    istio服务发现机制是基于kubernetes域名反问机制构建而成,而kbernetes他的域名反问他是基于ingress这个资源来实现的,ingress会来配置域名的映射 ingress也是k8s里面的一个资源,我们只需要在ingress里面配置域名映射就可以了,ingress会把请求转发给 pod ingress知道请求应该转发给哪个 pod
    ​
    ingress服务发现原理:
    需要不断的从 kube-apiserver 获取 pod 信息,这样 ingress 就有了 pod 内部的服务信息,从而 ingress知道这个请求到底该发给 pod 里面哪个服务容器
    下面我们来学习 kubernetes 可以帮 istio 实现自定义资源
    ​
    3. 基于kubernetes CRD规则,kubernetes 可以帮 istio 实现扩展自定义资源
    istio 所有的路由规则和控制策略他都要基于 kubernetes CRD原则来进行实现,而这些规则都是要通过 apiserver,也就是通过调用 kube-apiserver 来对这些数据持久化,说白了,就是 istio 要通过 CRD 规则自定义资源,而资源数据要通过 apiserver 保存到 etcd 里面
    ​
    回顾 api-server 
    这个是 k8s 的资源,api-server 提供了 k8s 各类资源对象的增删改查的接口,如果说需要修改数据,那么必须要通过 api-server ,只有 api-server 他才能够直接操作 etcd,所以说 kubernetes 是 istio 的好基座。
    ​
    https://github.com/NVIDIA/TensorRT-LLM/releases

    2.5 Istio 与服务网格

    2.5.1 时代选择服务网格

    在云原生时代,随着采用各种语言开发的服务剧增,应用间的访问拓扑更加复杂,治理需求也越来越多,原来的那种嵌入式在应用中的治理功能无论是从形态,动态性还是可扩展性来说都不能满足需求,迫切需要一种具备云原生动态,弹性特点的应用治理基础设施。
    传统的 spring cloud 模式,如果服务要增加服务治理功能,那么需要来增加 spring cloud 的 jar 包依赖,注解添加,还要增加配置。
    缺点: 非业务代码会侵入到业务代码里面

    采用 sidecar 代理与应用进程的解耦带来的应用完全无侵入,也屏蔽了开发语言无关等特点,解除了开发语言的约束,从而极大降低了应用开发者的开发成本。
    这种方式也经常被称为一种应用的基础设施层,类比TCP/IP 网络协议栈,应用程序像使用 TCP/IP 一样使用这个通用代理:TCP/IP 负责将字节码可靠地在网络节点之间传递,Sidecar 则负责将请求可靠地在服务间进行传递。TCP/IP 面向的是底层的数据流,Sidecar 则可以支持多种高级协议 (HTTP,gRPC,HTTPS等),以及对服务运行时进行高级控制,使服务变得可监控,可管理。
    然后,从全局来看,在多个服务间有复杂的互相访问时才有服务治理的需求。即我们关注的是这些 sidecar组成的网络,对网络内服务间访问进行管理,应用还是按照本来的方式进行互相访问,每个应用程序的入口流量和出口流量都是要经过 sidecar 代理,并在 sidecar 上执行治理动作。
    最后,sidecar 是网格动作的执行体,全局的管理规则和网格内的元数据维护需要通过一个统一的控制面实现。
    sidecar拦截入口流量,执行治理动作,这就引入两个问题:
    缺点:
    1. 需要对 sidecar 代理进行维护
    2. 请求多了一步经过 sidecar 代理的流程
    所以,对于考虑使用服务网格的用户来说,事情就会变成一个更简单的选择题:是否愿意花费额外的资源在这些基础设施上来换取开发,运维的灵活性,业务的非侵入性和扩展性等便利。
    目前,华为,谷歌,亚马逊等云服务厂商将这种服务以与服务形态提供了出来,并和底层的基础设施相结合,提供了完整的服务治理解决方案。这对于广大应用开发者来说,更加方便和友好。

    2.5.2 服务网格选择 Istio

    在多种服务网格项目和产品中,最引人注目的是后来居上的 Istio,他有希望成为继 kubernetes 之后的又一宽重量级产品。
    Istio 解决了生产大规模集群的性能,资源利用率和可靠性问题,提供了众多生产中实际应用的新特性,已经达到企业级可用标准。
    首先,在控制面上,Istio作为一种全新的设计,在功能,形态,架构和扩展性上提供了远超服务网格的能力范围。他提供了一套标准的控制面规范,向数据面传递服务信息和治理规则。
    Istio 使用 Envoy v2版本的API,即gRPC协议,标准的控制面 API 解耦了控制面和数据面的绑定。
    最后,在大厂的支持上,Istio由谷歌和IBM 共同推出,从应用场景的分析规划到本身的定位,从自身架构的设计与周边生态的结合,都有着比较严密的论证。Istio项目在发起时已经确认了将云原生生态系统中的容器作为核心,将 kubernetes 作为管理容器的编排系统,需要一个系统管理在容器平台上运行的服务之间的交互,包括控制访问,安全,运行数据收集等,而 Istio 正是为此而生,Istio 成为架构的默认部分,就像容器和 kubernetes 已经成为云原生架构的默认部分一样。
    云原生社区的定位与多个云厂商的规划也不谋而合。华为云已经在2018年8月率先在其容器服务 CCE(Cloud Container Engine) 中内置 Istio;Google 的 GKE 也在 2018年宣布内置 Istio;越来越多的云厂商也已经选择将 Istio 作为其容器平台的一部分提供给用户,即提供一套开箱即用的容器应用运行治理的全栈服务,正因为看到了 Istio 在技术和产品上的巨大潜力,各大厂商在社区的投入也不断加大,其中包括 Google ,IBM,华为,思科,红帽等主流厂商。
    总结:
    时代选择服务网络是因为架构的发展
    服务网格选择 istio 是因为提供一套开箱即用的容器应用运行治理的全栈服务

    总结

    本节课主要是围绕 Service Mesh 来介绍,包括了架构发展历史 (包括每一种架构的优缺点),服务网格发展历史,云原生的介绍,sidecar代理模式,istio 与服务治理 /kubernetes/服务网格之间的关系,为后续深入学习 Istio 框架做了理论铺垫,没有涉及到 Istio 安装,istio组件,istio实战,这些都会在后面课程会进行介绍演示。

    01 Istio 架构

    Istio 的架构,分为控制平面和数据平面两部分。
    - 数据平面: 由一组智能代理([Envoy])组成,被部署为 sidecar, 这些代理通过一个通用的策略和遥测中心传递和控制微服务之间的所有网络通信。
    - 控制平面:管理并配置代理来进行流量路由。此外,控制平面配置 Mixer 来执行策略和收集遥测数据。

    下图展示了组件每个平面的不同组件:

    istio的组件如下:
    1. Pilot: 它提供服务发现和路由规则
    2. Mixer: 它就是一个策略控制,比如 限流 (对服务调用限速)
    3.Citadel: 起安全作用,它能够保证服务跟服务通信安全,会进行加密
    4. Envoy: 代理,处理服务的流量
    5.sidecar: 会修改应用程序的描述信息,注入 sidecar
    6.描述信息:创建 pod 的 yaml 文件
    7.iptables: 它能够对数据包进行检测和访问控制
    我们已经把 istio的组件进行了一个简单的介绍,
    下面我们来把一个请求到架构的内部流程先来描述一下:
    我们以前端服务为例:
    首先前端服务在创建 pod 的时候,会发生自动注入,会来做一个 sidecar 代理,而外部请求通过 gateway 网关,网关会把请求转发前端服务这个 pod 里面的 envoy 组件,但前端服务的 pod 收到流量的时候会发生流量的拦截,会被 Envoy 拦截,会拦截 pod 所有的进出口流量,此时 Envoy 已经有了一个流量的处理,
    Envoy已经能够进行流量拦截,此时,Envoy又如何进行流量分发:
    把流量分发给后台服务,此时它是不是要有后台服务的地址,前端服务Envoy代理会调用控制平面的 pilot 服务发现结构来获取目标服务的实例列表,此时,前端的 Envoy 代理就已经后台服务这些实例列表,由于后台服务他要多个版本,所以前端服务还需要从控制平面的 pilot 获取后台服务的负载均衡配置,如何根据 pilot 路由规则把流量分发给指定的后台服务的版本上面,此时,前端服务的Envoy 与后台 的 Envoy 他们就能够进行通信了。
    为了保证通信安全,Envoy 还是要从控制平面 Citadel 来获取服务通信的证书和密钥,因为 Citadel 组件它维护了服务代理通信的证书和密钥,那么此时,两个 Envoy 通信是安全的。而通信双方的 Envoy 他们都会连接到控制平面的 Mixer 用于来上报访问的数据,为什么要上报呢?
    就是为了控制我们的数据,来监控服务,这时我们已经把istio架构流程描述结束了。
    此时我们已经将一个请求到 istio 架构流程说完了。
    我们此时没有细化到 istio 架构里面的每一个动作,只是对 istio 架构有了一个全局的了解,并没有对架构图里面的数字编号进行详细讲解,每个数字编号他都表示一个含义,我们已经在左边已经将这些数字的含义列车来了,如上图所示。
    我们再解释数据平面时,也会来介绍控制平面如何来提供对应的支持,下面我们会详细介绍这些数字编号。
    
    
    下面我们对这些数字编号代表的功能进行详细讲解:
    前面我们已经把 istio 架构的流程简单梳理了一遍,现在我们把架构的功能详细讲解一下:
    首先我们来说第一个
    1.自动注入,
    那么什么时候会发生自动注入呢?在 kubernetes 在创建 pod 的时候,它里面有一个组件 APIServer 会来调用控制平面的 sidecar-injector 这个服务,APIServer会调用控制平面 sidecaer 服务,而我们没有在控制平面把 sidecar 服务列出来,但是我们会在后面介绍 istio 组件的时候,会详细介绍 sidecar 服务,
    sidecar: 会修改应用程序的描述信息,注入 sidecar
    什么是描述信息?创建 pod 的 yaml 文件
    自动注入:就是在外面创建 pod 的时候会来修改我们的描述信息,会在描述信息里面追加一个代理 sidecar 代理而整个过程,业务是无感知的,
    
    举例 原始的 yaml 文件 如下:
    apiVersion: app/v1
    kind: Deployment
    	spec:
    	containers:
    	- name: nginx
    	image: nginx 地址
    	...
    	
    	containers:	# 创建 pod 的时候追加的一个 sidecar 容器信息
    	- name: sidecar
    	image: sidecar 地址
    	...
    
    2.流量拦截
    下面我们来学习第二个点,流量拦截
    流量拦截:说白了就是 sidecar 代理容器拦截业务容器的出口流量和入口流量,
    那么我们来思考一下,sidecar 是如何来拦截的?
    pod1里面的代理容器会发请求给 pod2 ,由 pod2 里面的代理容器进行拦截,其实他内部的拦截流程是这样:
    首先,pod2 的网卡它会来收到通信数据,网卡收到数据包,数据包它会有一个 iptables 进行拦截,
    iptables: 它能够对数据包进行检测和访问控制
    iptables 它为什么要将请求转发给 pod 里面的代理容器呢?其实是 pod 在创建的时候会设置 iptables 路由规则,所以说基于配置的 iptables 规则来拦截业务容器的出口流量和入口流量,这样就实现了一个流量的拦截。从架构图里面我们可以看到,前端服务的流量会被前端服务的 Envoy 拦截,当流量到达后端的时候会有后端服务的两个版本的 Envoy 进行拦截,我们来对流量拦截进行总结
    
    总结:每个 pod 里面他都会有一个 sidecar 代理,来拦截我们的服务流量,不管是出口还是入口。
    
    如下图所示:
    
    3.服务发现和负载均衡
    我们来思考一下:假如说前端服务已经能够把网关服务进行拦截,那么 Envoy 它是如何进行流量的分发,它如何把流量分发到后台的服务上面,那么它是不是要进行服务发现,所以服务发起方Envoy他需要来控制平面调用 pilot 发现接口,来获取目标服务是实例列表,从架构图里面前端服务的 Envoy 需要通过控制平面的 pilot 发现接口,来得到后台服务的各个实例的地址列表,为服务的访问做好准备,下面我们来对服务发现总结一下
    
    总结:
    说白了,pilot 它提供的服务发现功能,调用方需要到 pilot 主键来获取提供者服务信息
    现在我们来学习一下第四点负载均衡
    4.负载均衡
    从架构图我们可以看到,后台服务他是有多个版本,前端服务他需要从控制平面 pilot 来获取后台服务的负载均衡配置,根据负载均衡配置特点来选择服务的实例,并连接对应的实例地址,所以前端服务需要负载均衡来指明请求对应的哪个实例地址
    总结:
    pilot它也通过了负载均衡功能,用方根据负载均衡的策略,去选择服务的实例。
    现在我们来学习第五个点,流量治理和访问安全
    
    5.流量治理
    负载均衡可以请求对应的哪个实例地址,但是,他也仅仅知道我的请求发给哪个实例地址,没有具体的流量动作,流量治理就是根据转发规则来控制流量,比如说 限流,访问的频率控制,这些都是流量治理,路由规则配置他也是来自于控制平面 pilot,下面我们通过画图来理解。
    假设我们在 pilot 这里配置了一个流量规则( 规则:一个小时只能访问3次 ), 
    首先,pod-1 容器会去 pilot 去拉取流量规则,
    然后代理容器会发起通信,给 pod-2 发起一个通信,这是第一次
    隔了一分钟以后,pod-1 的代理容器他又给 pod-2 发了一个请求, 这是第二次
    隔了一分钟以后,pod-1 的代理容器他又给 pod-2 发了一个请求, 这是第三次
    隔了一分钟以后,pod-1 的代理容器他又给 pod-2 发了一个请求, 这是第四次,第四次访问会失败,
    
    流量治理和负载均衡的区别:
    负载均衡仅仅说是找到服务地址,但是没有发起请求,而流量治理则是根据负载均衡找到服务地址,并且发起流量的动作,说白了 pod 里面的代理容器他需要根据 pilot 提供的路由规则来进行通信,
    
    下面我们来学习第六点 访问安全
    
    6.访问安全
    访问安全是指服务之间通过双方的 Envoy 来进行进行双向认证和通道加密,确保发送流量部会被劫持,这里有两个 pod ,两个 pod 通信,要保证两个 pod 之间通信不会发生流量劫持,会进行通信加密。而证书和密钥统一由控制平面 Citadel 来维护。
    通信加密的证书和密钥统一由控制平面 Citadel 来维护
    
    总结:
    Citadel 他维护了服务通信所需要的证书和密钥。
    
    现在我们来学习数字7,服务遥测(数据监控)和外部访问
    
    
    7.遥测和策略执行和外部访问
    在服务间通信时,通信双方的 Envoy 会连接到控制平面的主键 Mixer 进行数据上报,而 Mixer 会通过 Adapter 会把数据发送给监控的后端,比如说一些监控工具,我们用画图的方式来理解他们是如何上报数据。
    
    如果说 pod-1 里面的 envoy 就要把请求发给 pod-2 里面的 envoy ,
    首先,他们要进行通信,
    第二步,pod-1 他需要来进行数据上报,发送请求的数据 到 Mixer, 上报发送请求数据
    第三步,当 pod-2 里面的 envoy 收到 请求之后,他也要进行数据上报 到 Mixer, 接收请求数据上报
    第四步,
    说白了,数据平面的监控,就是通过 Mixer 来实现数据的监控
    
    总结
    Mixer 主键可以用来收集各个服务的日志数据,从而进行监控,而控制平面为什么能够数据平面实现监控呢?
    也得益 Mixer 主键。
    
    下面我们来学习第八个点 
    
    8.策略执行
    策略执行是什么意思?
    我们可以来理解成他是控制服务跟服务的访问,判断你这个请求到底是拒绝还是发送?而这个控制权限他也是来自于控制平面的 Mixer,
    举例:
    如果前端服务需要将数据请求转发给后台服务,那前端服务首先需要去调用控制平面 Mixer,来检查这个请求到底是通过还是拒绝?
    pod-1 他要发请求给 pod-2 
    首先,envoy 他需要申请,
    第1步要来进行询问 Mixer,是否可以访问,
    第2步,当 Mixer 告诉 pod-1 可以访问
    第3步, 发起请求 - 通信
    
    总结:
    策略执行主要基于 Mixer 这个主键,可以来对服务的数流进行控制
    
    下面我们来学习 第九个点 外部访问
    
    9.外部访问
    外部的所有请求都要经过 gateway ,gateway 他是一个网关,网关他把流量转发给前端服务的 envoy,
    
    现在我们已经把整个架构都讲完了
    
    总结
    服务调用双方,通过envoy代理来拦截请求,而数据平面需要的服务治理都来自于控制平面,而这就是 istio 数据平面和控制平面的配合方式。而在架构里面,我们也只介绍了一些常用的组件。
    下面我们来学习更丰富的 istio 组件
    

    02 Istio 组件介绍

    2.1 Pilot

    pilot在 istio 架构中必须要有
    思考:为什么 Envoy 能够服务发现?并且 Envoy 为什么可以流量控制?
    就是因为 Pilot 存在
    什么是 Pilot
    pilot 类似传统C/S架构中的服务端 Master,下发指令控制客户端完成业务功能。和传统的微服务架构对比,pilot 至少涵盖服务注册中心和向数据平面下发规则 等管理组件的功能。
    ​
    pilot 包含了服务注册和路由规则下发,客户端的请求由 pilot 控制,所以我们可以理解为 pilot 是服务端的 master,
    服务注册中心
    注册中心:跟传统的微服务注册中心提供的功能差不多,都是提供服务的注册和服务的发现。但是唯一的区别就是 pilot 本身不提供服务的注册,他只提供一个 API 接口,来对接已经实现注册功能的框架。就好比java 里面的 SPI他只提供一个规范。具体的实现由注册中心厂商来实现。比如 Eureka,cursor,
    ​
    如图所示,pilot 为 Envoy sidecar 提供服务发现,用于智能路由的流量管理功能 ( 例如,A/B 测试,金丝雀发布等 ) 以及弹性功能 ( 超时,重试,熔断器等 )。
    ​
    pilot 本身不做服务注册,他会提供一个 API 接口,对接已有的服务注册系统,比如 Eureka,Etcd 等。
    说白了,pilot 可以看成他是 sidecar 的一个领导
    ​
    pilot 内部包含三个模块:
    1.Platform Adapter 他是注册中心10个G 主要用来对接外部不同的注册中心厂商,比如 Eureak,Etcd 
    2.Abstract model 他是来处理 platform Adapter 对接外部不同的平台,从特定平台细节中解耦
    3. Envoy API 他主要是负责与 pod 里面的 envoy 代理进行通信,主要是用来发送服务发现信息和流量控制规则,
    举例:
    假如我们有一个 pod ,pod 里面有一个服务C,服务C 会把服务注册到 Platform Adapter 里面,如果说此时 Platform Adapter 他对接的是 eureka,那么服务C最终注册到 Eureka 里面来,而抽象模型 Abstract model 他会进行平台细节的解耦,并且来处理 Platform Adapter 对接外部的不同平台。最后通过 Envoy API 负责与其他 pod 的 envoy 代理进行通信,然后会把服务发现信息和流量控制规则发送给 envoy,这就是 pilot 注册中心的一个流程。
    ​
    下面我们来学习数据平面下方规则(路由规则转发):
    我们回到文档
    1. Platform Adapter 是 pilot 抽象模型的实现版本,用于对接外部的不同平台
    2.Pilot 定了一个抽象模型(Abstract model),处理 Platform Adapter 对接外部不同的平台,从特定平台中解耦
    3.Envoy API 负责和Envoy的通讯,主要是发送服务发现信息和流量控制规则给 Envoy
    ​
    流程总结:
    Service 服务C会注册到 pilot 注册中心平台适配器(Platform Adapter)模块上(假如对接的是 Eureka,那么 service 服务C 会注册到 Eureka 里面),然后抽象模型(Abstract model) 进行平台细节的解耦并且用于处理 Platform Adapter 对接外部的不同平台,最后通过 Envoy API 负责和 Envoy 的通讯,主要是发送服务信息和流量控制规则给 Envoy
    ​
    数据平面下发规则
    pilot 更重要的一个功能是向数据平面下发规则,pilot负责将各种规则转换成 Envoy 可识别的格式,通过标准的协议发送给 Envoy,指定 Envoy 完成动作,在通信上,Envoy 通过 gRPC 流式订阅 pilot 的配置资源。
    ​
    pilot 将表达的路由规则分发到 Envoy 上,Envoy 根据该路由规则进行流量转发,配置规则和流程图如下所示
    规则如下:
    # http请求
    http:
    - match: #匹配
      - header: # 头部
         cookie:
       # 以下 cookie 中包含 group=dev则流量转发到v2版本中
          exact: "group=dev"
        route: 路由
        - destination:
          name: v2
        - route:
          - destination:
            name: v1
        
    数据平面下发规则
    首先,前端服务 Envoy代理 到 pilot 获取服务发现,此时前端服务已经知道后台服务有 v1 版本,v2 版本
    再根据 pilot 数据平面下发规则,然后再根据规则,进行请求转发,如果说你的请求头里面包含 group=dev,前端服务会把请求转发给 v2 版本的 Envoy 代理,
    那么我们来总结一下
    pilot组件主要是提供提供了服务发现和路由转发规则,
    我们来思考一下:
    虽然说前端服务可以根据 pilot 的服务发现来对后台服务请求下发,但是,此时我希望对速率进行限制,那么该怎么办呢?
    下面我们来学习另外一个组件 Mixer

    2.2 Mixer

    Mixer 在 Istio 架构中不是必须的
    Mixer 分为 Policy 和 Telemetry 两个子模块,
    Policy 用于向 Envoy 提供准入策略控制,黑白名单控制,速率限制等相关策略,
    Telmetry 为 Envoy 提供了数据上报和日志搜集服务,以用于监控告警和日志查询。
    ​
    Envoy能否继续下发,需要通过 Policy 检查,policy说请求能够下发,那么 Envoy 他会把请求继续下发,policy说不可以,他就会把请求拒绝掉。
    ​
    首先 telemetry 主要是在 envoy 代理里面来收集数据,
    ​
    Telemetry介绍
    Mixer 是一个平台无关的组件,Mixer 的 Telemetry 在整个服务网格中执行访问控制和策略使用,并从 Envoy 代理和其他服务收集遥测数据,流程如下图所示。

    遥测报告上报,比如从 Envoy 中收集数据[请求数据,使用时间,使用协议等],通过 Adapter 上报给 Prometheus,heapster等。
    说白了,就是数据收集,然后通过 adapter 上传到监控容器里面

    policy介绍
    policy 是另外一个 Mixer 服务,和 istio-telemetry 基本上是完全相同的机制和流程,数据面在转发服务的请求前调用 istio-policy 的 Check 接口是否允许访问,Mixer 根据配置将请求转发到对应的 Adapter 做对应检查,给代理返回允许访问还是拒绝。可以对接入配额,授权,黑白名单等不同的控制后端,对服务间的访问进行可扩展的控制。
    ​
    策略控制: 检查请求释放可以运行访问

    2.3 Citadel

    Citadel 在 istio 架构中不是必须的
    Istio 的认证授权机制主要是由 Citadel 完成,同时需要和其他组件一起配合,参与到其中的组件还有 Pilot,Envoy,Mixer,他们四者在整个流程中的作用分别为:
    1. Citadel: 用于负责密钥和证书的管理,在创建服务时会将密钥及证书下发至对应的 Envoy 代理中;
    2. Pilot: 用于接收用户定义的安全策略并将其整理下发至服务傍边的 Envoy 代理中;
    3. Envoy: 用于存储 Citadel 下发的密钥和证书,保障服务间的数据传输安全;
    4. Mixer: 负责核心功能为前置条件检查和遥测报告,上报;

    流程图如下:

    流程描述:
    下面我们把这个流程梳理一下
    首先,他是一个 k8s 集群,k8s 里面会有一个 pod ,pod 里面他又部署了一个服务 service, 此时集群里面有一个 pod 被启动,pod 是由 envoy 代理容器和 service 容器构成,在启动过程中,Citadel 他会把密钥和证书下发到每个服务(pod)内的 envoy 容器中,以便保证后续服务安全通信,
    1. pod 启动时,Citadel 会下发密钥和证书给 envoy 存储,便于后续服务安全通信;
    2. 这边 rules API 有一些自定义的规则,这个规则会下发给 pilot,pilot里面的服务发现和策略规则以 envoy API 的方式暴露给 pod 里面的 envoy代理容器,
    3.envoy 里面已经存储了密钥和证书,此时 envoy 跟 envoy 之间传输是安全的,
    4.第四个 mixer 会来检查 envoy 代理的请求,并且还会来收集 envoy 的数据,用于数据上报,
    5.citadel 和 pilot 他们都是通过 API Server 来与 k8s 进行交互,
    citadel 比较适合用于支持场景,

    总结
    citadel 他主要是来负责密钥和证书的管理,在创建 pod 的时候,会将密钥和证书下发给对应的 envoy 容器,这样可以保证各个服务的 envoy 代理他们的通信是安全的,,

2.4 Galley

Calley 在 Istio 中不是必须的

Galley 在控制面上向其他组件提供支持,Galley 作为负责配置管理的组件,并将这些配置信息提供给管理面的 Pilot 和 Mixer 服务使用,这样其他管理面组件和 Galley 打交道,从而与底层平台解耦。
​
首先我们来说一下 galley 他的作用范围,galley 并不直接向数据平面提供业务能力,而是在控制平面像其他组件提供支持,他主要是负责配置管理,验证配置格式和内容的正确性,并将这些配置信息提供给控制平面的 pilot 和 mixer 这些组件,而这样的好处,控制平面的组件 只需要和 galley 打交道,从而与底层平面解耦。

如图所示

从图可以看出,上面是一个 pod ,pod 里面有一个 envoy代理 和 一个 service A,envoy 代理会将数据上报给 mixer组件, envoy 代理同时还需要从 pilot 组件来进行服务发现和路由规则,pilot 和 mixer 这两个组件他们的配置资源来自于 galley,由 galley 来配置统一管理。
这样有什么好处呢?
1,他能够把配置统一管理,方便配置问题排查;
2,他能够增加配置的复用度[如果是相同的配置,可以增加配置的复用度];
3, 配置跟配置之间相互隔离,而且组件访问配置增加了权限控制,比如说,Mixer组件他只能访问他一些私有的配置,这个就是权限控制。

分发规则: 
galley 负责控制平面的配置分发,他主要是依托于一种 MCP 协议,MCP提供了一套配置定义和分发的 API,他里面的会包含这么几个角色:
分发协议 MCP ,MCP 角色介绍:
1, source 他表示是配置的提供者,说白了就是 galley 组件
2, sink 他是配置的消费端,说白了他就是 mixer 和 pilot 
3, resource 他是配置文件,yaml 配置文件


source,resource 与 sink 三者的关系如下:
首先,galley来订阅我们的配置,
然后(sink)mixer/pilot 再从(galley[source])来获取配置,
有了 galley 统一配置之后,其他组件需要配置,就从 galley 这里来获取
我们可以把 galley 理解是微服务的配置中心

 总结
 galley 就是给控制平面的其他组件提供支持,提供了一个配置统一管理,而这些组件只需要跟 galley 打交道。从而避免了与底层平台解耦。
 下面我们来学习 sidecar-injector 组件

2.5 Sidecar-injector

Sidecar-injector 是负责自动注入的组件,只要开启了自动注入,那么在创建 pod 的时候就会自动调用 Sidecar-injector 服务
配置参数: istio-injection=enabled,我们后面会有案例演示
在 istio 中 sidecar 注入有两种方式
1.需要使用 istioctl 命令手动注入,(不需要配置参数:istio-injection=enabled)
2. 基于 kubernetes 自动注入 (配置参数:istio-injection=enabled)
​
手动注入和自动注入会在 istio 安装之后案例演示
​
两种区别:
手动注入需要每次在执行配置都需要加上 istioctl 命令
自动注入只需要做一下开启参数即可( 配置参数:istio-injection=enabled )
​
sidecar 模式具有以下优势:
1.把业务逻辑无关的功能抽取出来(比如通信),可以降低业务代码的复杂度
2.sidecar 可以独立升级,部署,与业务代码解耦
​
注入流程:
在 kubernetes 环境下,根据自动注入配置,kube-apiserver在拦截到 Pod 创建的请求时,会调用自动注入服务 istio-sidecar-injector 生成 Sidecar 容器的描述并将其插入原 Pod 的定义中,这样,在创建的 pod 内,除了包括业务容器,还包括 Sidecar 容器。这个注入过程对用户透明,用户使用原方式创建工作负载。
​
下面我们来学习 envoy 组件

2.6 Proxy(Envoy)

Proxy是Istio数据平面的轻量代理
Envoy 是用C++ 开发的非常有影响力的轻量级高性能开源服务代理。作为服务网格的数据面,Envoy提供了动态服务发现,负载均衡,TLS,HTTP/2 及 gRPC 代理,熔断器,健康检查,流量撤分,灰度发布,故障注入等功能。
Envoy 代理是唯一与数据平面流量交互的 Istio 组件。
Envoy组件解析
为了便于理解 Istio 中 Envoy与服务的关系,如图所示:

一个 pod 里面运行了一个 Envoy 容器和 service A 容器,而 Envoy 容器内部包含了两个进程,分别是 pilot-agent 和 Envoy 两个进程 pilot-agent 与 envoy 是打包在同一个docker镜像里面,我们来看看他有什么作用。

pilot-agent 的作用
1.用于生成 envoy 配置
2.负责启动 envoy 进程,
3. 负责监控 envoy 的运行状态。比如 envoy 出错时,pilot-agent负责重启 envoy,或者 envoy 配置变更之后 reload envoy

envoy 进程的作用:
1.envoy 进程是负责拦截 pod 流量
2.负责从控制平面 pilot 来获取配置和服务发现
3.能够上报数据给控制平面组件 mixer


Envoy
负责拦截 pod 流量,负责从控制平面 pilot 组件获取配置和服务发现,上报数据给 mixer 组件

下面我们来学习网关gateway

2.7 Ingressgateway

ingressgateway 就是入口处的 gateway,从网格外访问网格内的服务就是通过这个Gateway进行的。
ingressgateway  比较特别,是一个 Loadbalancer 类型的 Service, 不同于其他服务组件只有一两个端口,
ingressgateway 开放了一组端口,这些就是网格内服务的外部访问端口。
网格入口网关 ingressgateway 和 网格内的 Sidecar 是同样的执行体,也和网格内的其他 Sidecar一样从 pilot 处接收流量规则并执行。因为入口处的流量都走这个服务。
​
流程图如下:

gateway 会暴露一个 port(端口),外部的请求就可以根据这个端口把请求转发给 gateway,然后由 gateway 把请求 分发给网格内的(前端)服务
​

2.8 其他组件

总结
主要介绍了一些常见的 istio 组件,其中有一些组件是 istio 默认就已经使用了,有一些组件我们后面也会来演示。

03 Istio 安装

Istio 支持在不同的平台下安装其控制平面,例如 kubernetes,mesos和虚拟机等。
课程上以 kubernetes 为基础讲解如何在集群中安装 istio (istio-1.0.6 要求 kubernetes 的版本在1.11及以上)。
可以在本地或公有云上搭建 Istio 环境,也可以直接使用公有云平台上已经集成了 istio 的托管服务。

3.1 在本地搭建 istio 环境

3.1.1 Kubernetes 集群环境

目前有许多软件提供了在本地搭建 kubernetes 集群的能力,例如 Minikube/kubeadm 都可以搭建 kubernetes 集群,我们这边所选用的是 kubeadm 来安装 kubernetes 集群。

kubeadm 是一个工具,他提供了 kubeadm init 以及 kubeadm join 这两个命令作为快速创建 kubernetes 集群的最佳实践。

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值