Istio的工作机制

Istio的工作机制和架构,分为控制面和数据面两部分。控制面主要包括Pilot、Mixer、Citadel等服务组件;数据面由伴随每个应用程序部署的代理程序Envoy组成,执行针对应用程序的治理逻辑。

通过一个动态场景来了解工作机制,即观察frontend服务对 forecast 服务进行一次访问时,在 Istio 内部都发生了什么,以及 Istio 的各个组件是怎样参与其中的,分别做了哪些事情。

带圆圈的数字代表在数据面上执行的若干重要动作。虽然从时序上来讲,控制面的配置在前,数据面执行在后,但为了便于理解,在下面介绍这些动作时以数据面上的数据流为入口,介绍数据面的功能,然后讲解涉及的控制面如何提供对应的支持,进而理解控制面上组件的对应功能。

(1)自动注入:指在创建应用程序时自动注入 Sidecar代理。在 Kubernetes场景下创建 Pod时,Kube-apiserver调用管理面组件的 Sidecar-Injector服务,自动修改应用程序的描述信息并注入Sidecar。在真正创建Pod时,在创建业务容器的同时在Pod中创建Sidecar容器。

(2)流量拦截:在 Pod 初始化时设置 iptables 规则,当有流量到来时,基于配置的iptables规则拦截业务容器的Inbound流量和Outbound流量到Sidecar上。应用程序感知不到Sidecar的存在,还以原本的方式进行互相访问。流出frontend服务的流量会被 frontend服务侧的 Envoy拦截,而当流量到达forecast容器时,Inbound流量被forecast服务侧的Envoy拦截。

(3)服务发现:服务发起方的 Envoy 调用管理面组件 Pilot 的服务发现接口获取目标服务的实例列表。frontend 服务侧的 Envoy 通过 Pilot 的服务发现接口得到forecast服务各个实例的地址,为访问做准备。

(4)负载均衡:服务发起方的Envoy根据配置的负载均衡策略选择服务实例,并连接对应的实例地址。数据面的各个Envoy从Pilot中获取forecast服务的负载均衡配置,并执行负载均衡动作。

(5)流量治理:Envoy 从 Pilot 中获取配置的流量规则,在拦截到 Inbound 流量和Outbound 流量时执行治理逻辑。frontend 服务侧的 Envoy 从 Pilot 中获取流量治理规则,并根据该流量治理规则将不同特征的流量分发到forecast服务的v1或v2版本。当然,这只是Istio流量治理的一个场景,更丰富的流量治理能力后续讲解。

(6)访问安全:在服务间访问时通过双方的Envoy进行双向认证和通道加密,并基于服务的身份进行授权管理。Pilot下发安全相关配置,在frontend服务和forecast服务的Envoy上自动加载证书和密钥来实现双向认证,其中的证书和密钥由另一个管理面组件Citadel维护。

(7)服务遥测:在服务间通信时,通信双方的Envoy都会连接管理面组件Mixer上报访问数据,并通过Mixer将数据转发给对应的监控后端。frontend服务对forecast服务的访问监控指标、日志和调用链都可以通过这种方式收集到对应的监控后端。

(8)策略执行:在进行服务访问时,通过Mixer连接后端服务来控制服务间的访问,判断对访问是放行还是拒绝。Mixer后端可以对接一个限流服务对从frontend服务到forecast服务的访问进行速率控制。

(9)外部访问:在网格的入口处有一个Envoy扮演入口网关的角色。外部服务通过Gateway访问入口服务 frontend,对 frontend服务的负载均衡和一些流量治理策略都在这个Gateway上执行。

总结以上过程中涉及的动作和动作主体,可以将其中的每个过程都抽象成一句话:服务调用双方的Envoy代理拦截流量,并根据管理面的相关配置执行相应的治理动作,这也是Istio的数据面和控制面的配合方式。

Istio的服务模型

Istio支持将由服务、服务版本和服务实例构造的抽象模型映射到不同的平台上,这里重点关注基于Kubernetes的场景。可以认为,Istio的几个资源对象就是基于Kubernetes的相应资源对象构建的,加上部分约束来满足Istio服务模型的要求。

Istio 官方对这几个约束的描述如下:

◎ 端口命名:对 Istio 的服务端口必须进行命名,而且名称只允许是<protocol>[-<suffix>]这种格式,其中<protocol>可以是tcp、http、http2、https、grpc、tls、mongo、mysql、redis等,Istio根据在端口上定义的协议来提供对应的路由能力。例如“name:http2-forecast”和“name:http”是合法的端口名,但是“name:http2forecast”是非法的端口名。如果端口未命名或者没有基于这种格式进行命名,则端口的流量会被当作TCP流量来处理。

◎ 服务关联:Pod 需要关联到服务,如果一个 Pod 属于多个 Kubernetes 服务,则要求服务不能在同一个端口上使用不同的协议。在 Istio 0.8 之前的版本中要求一个Pod 只能属于一个 Kubernetes 服务,这种约束更简单,也更能满足绝大多数使用要求。

◎ Deployment使用app和version标签:建议Kubernetes Deployment显式地包含app和 version 标签。每个 Deployment 都需要有一个有业务意义的 app 标签和一个表示版本的version标签。在分布式追踪时可以通过app标签来补齐上下文信息,还可以通过app和version标签为遥测数据补齐上下文信息。

Istio的服务

从逻辑上看,服务是Istio主要管理的资源对象,是一个抽象概念,主要包含HostName和Ports等属性,并指定了Service的域名和端口列表。每个端口都包含端口名称、端口号和端口的协议。

在 Istio 中对不同的协议也有不同的治理规则集合,这也是Istio关于端口命名约束的机制层面的原因,具体来讲就是要求将端口的协议通过“-”连接符加在端口名称上。

从物理层面看,Istio服务的存在形式就是Kubernetes的Service,在启用了Istio的集群中创建 Kubernetes的 Service时只要满足以上约束,就可以转换为 Istio的 Service并配置规则进行流量治理。

Service是Kubernetes的一个核心资源,用户通过一个域名或者虚拟的IP就能访问到后端Pod,避免向用户暴露Pod地址的问题,特别是在Kubernetes中,Pod作为一个资源创建、调度和管理的最小部署单元的封装,本来就是动态变化的,在节点删除、资源变化等多种情况下都可能被重新调度,Pod的后端地址也会随之变化。

一个最简单的Service示例如下:

apiVersion: v1
kind: Service
metadata:
name: forecast
spec:
ports:
- port: 3002
targetPort: 3002
selector:
app: forecast

如上所示创建了一个名称为 forecast 的 Service,通过一个 ClusterIP 的地址就可以访问这个Service,指向有“app:forecast”标签的Pods。Kubernetes自动创建一个和Service同名的Endpoints对象,Service的selector会持续关注属于Service的Pod,结果会被更新到相应的Endpoints对象。

Istio的Service比较简单,可以看到差别就是要满足Istio服务的约束,并在端口名称上指定协议。例如,在以下示例中指定了forecast服务的3002端口是HTTP,对这个服务的访问就可以应用HTTP的诸多治理规则:

apiVersion: v1
kind: Service
metadata:
name: forecast
spec:
ports:
- port: 3002
targetPort: 3002
bane: http
selector:
app: forecast

Istio虽然依赖于Kubernetes的Service定义,但是除了一些约束,在定位上还有些差别。

在 Kubernetes中,一般先通过 Deploymnent创建工作负载,再通过创建 Service关联这些工作负载,从而暴露工作负载的接口。因而看上去主体是工作负载,Service只是一种访问方式,某些后台执行的负载若不需要被访问,就不用定义Service。

在Istio中,Service是治理的对象,是Istio中的核心管理实体,所以在Istio中,Service是一个提供了对外访问能力的执行体,可以将其理解为一个定义了服务的工作负载,没有访问方式的工作负载不是Istio的管理对象,Kubernetes的Service定义就是Istio服务的元数据。

Istio的服务版本

在Istio的应用场景中,灰度发布是一个重要的场景,即要求一个Service有多个不同版本的实现。而 Kubernetes在语法上不支持在一个 Deployment上定义多个版本,在 Istio中多个版本的定义是将一个Service关联到多个Deployment,每个Deployment都对应服务的一个版本。

在下面的实例中,forecast-v1 和 forecast-v2 这两个 Deployment 分别对应服务的两个版本:

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: forecast-v1
labels:
app: forecast
version: v1
spec:
replicas: 3
template:
metadata:
labels:
app: forecast
version: v1
spec:
containers:
- name: forecast
image: istioweather/forecast:v1
ports:
- containerPort: 3002
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: forecast-v2
labels:
app: forecast
version: v2
spec:
replicas: 2
template:
metadata:
labels:
app: forecast
version: v2
spec:
containers:
- name: forecast
image: istioweather/forecast:v2
ports:
- containerPort: 3002

观察和比较这两个Deployment的描述文件,可以看到:

◎ 这两个Deployment都有相同的“app:forecast”标签,正是这个标签和Service的标签选择器一致,才保证了Service能关联到两个Deployment对应的Pod。

◎ 这两个 Deployment 都有不同的镜像版本,因此各自创建的 Pod 也不同;这两个Deployment的version标签也不同,分别为v1和v2,表示这是服务的不同版本,这个不同的版本标签用来定义不同的Destination,进而执行不同的路由规则。

下面根据对Service和两个Deployment的如上定义分别创建3个Pod和两个Pod,假设5个Pod都运行在两个不同的Node上。在对Service进行访问时,根据配置的流量规则,可以将不同的流量转发到不同版本的Pod上,如下图所示:

Istio的服务实例

服务实例是真正处理服务请求的后端,就是监听在相同端口上的具有同样行为的对等后端。服务访问时由代理根据负载均衡策略将流量转发到其中一个后端处理。Istio 的ServiceInstance 主要包括 Endpoint、Service、Labels、AvailabilityZone 和 ServiceAccount等属性,Endpoint 是其中最主要的属性,表示这个实例对应的网络后端(ip:port),Service表示这个服务实例归属的服务。

Istio的服务发现基于Kubernetes构建,Istio的Service对应Kubernetes的Service,Istio的服务实例对应Kubernetes的Endpoint。

Kubernetes提供了一个 Endpoints对象,这个 Endpoints对象的名称和 Service的名称相同,它是一个<Pod IP>:<targetPort>列表,负责维护Service后端Pod的变化。如前面例子中介绍的,forecast服务对应如下Endpoints对象,包含两个后端Pod,后端地址分别是172.16.0.16和 172.16.0.19,当实例数量发生变化时,对应的Subsets列表中的后端数量会动态更新;同样,当某个Pod迁移时,Endpoints对象中的后端IP地址也会更新:

Istio的主要组件

如下所示是Istio 1.1在典型环境下的完整组件列表,本节将介绍其中每个组件的功能和机制。

Istio-pilot

服务列表中的 istio-pilot是 Istio 的控制中枢 Pilot服务。如果把数据面的 Envoy 也看作一种Agent,则Pilot类似传统C/S架构中的服务端Master,下发指令控制客户端完成业务功能。和传统的微服务架构对比,Pilot 至少涵盖服务注册中心和 Config Server 等管理组件的功能。

Pilot 直接从运行平台提取数据并将其构造和转换成 Istio 的服务发现模型,因此Pilot只有服务发现功能,无须进行服务注册。这种抽象模型解耦了Pilot和底层平台的不同实现,可支持Kubernetes、Consul等平台。Istio 0.8还支持Eureka,但随着Eureka停止维护,Istio在1.0之后的版本中也删除了对Eureka的支持。

除了服务发现,Pilot 更重要的一个功能是向数据面下发规则,包括 VirtualService、DestinationRule、Gateway、ServiceEntry 等流量治理规则,也包括认证授权等安全规则。Pilot 负责将各种规则转换成 Envoy 可识别的格式,通过标准的 xDS 协议发送给 Envoy,指导Envoy完成动作。在通信上,Envoy通过gRPC流式订阅Pilot的配置资源。如下图所示,Pilot将 VirtualService表达的路由规则分发到 Evnoy上,Envoy根据该路由规则进行流量转发。

第2篇----Istio架构概述篇的更多相关文章

  1. 解剖SQLSERVER 第七篇 OrcaMDF 特性概述(译)

    解剖SQLSERVER 第七篇  OrcaMDF 特性概述(译) http://improve.dk/orcamdf-feature-recap/ 时间过得真快,这已经过了大概四个月了自从我最初介绍我 ...

  2. Android核心分析之十六Android电话系统-概述篇

    Android电话系统之概述篇 首先抛开Android的一切概念来研究一下电话系统的最基本的描述.我们的手机首先用来打电话的,随后是需要一个电话本,随后是PIM,随后是网络应用,随后是云计算,随后是想 ...

  3. [转帖]我花了10个小时,写出了这篇K8S架构解析

    我花了10个小时,写出了这篇K8S架构解析 https://www.toutiao.com/i6759071724785893891/   每个微服务通过 Docker 进行发布,随着业务的发展,系统 ...

  4. VS2010+MVC4+Spring.NET2+NHibernate4-传统三层架构-前篇

    VS2010+MVC4+Spring.NET2+NHibernate4 - 传统三层架构 - 前篇 一直追求使用开源项目,就因一个字:懒! 一直想整理一下的,却一直懒到现在!从当初用的MVC3到现在的 ...

  5. MyBatis 源码篇-整体架构

    MyBatis 的整体架构分为三层, 分别是基础支持层.核心处理层和接口层,如下图所示. 基础支持层 反射模块 该模块对 Java 原生的反射进行了良好的封装,提供了更加简洁易用的 API ,方便上层 ...

  6. 【Istio实际操作篇】Istio入门,10分钟快速安装

    @ 目录 前言 本文说明 请大家务必查看 环境准备 详细版 入门:搭建步骤 Istio软件包下载 下载Istio 卸载 简洁版 安装 卸载 学习不走弯路,gz号「yeTechLog」 前言 上一篇讲了 ...

  7. Istio架构详解

    Istio架构及其组件概述 Istio 架构总体来说分为控制面和数据面两部分.控制面是 Istio 的核心,管理 Istio 的所有功能,主要包括Pilot.Mixer.Citadel等服务组件;数据 ...

  8. 大型互联网架构概述 关于架构的架构目标 典型实现 DNS CDN LB WEB APP SOA MQ CACHE STORAGE

    大型互联网架构概述 目录 架构目标 典型实现 DNS CDN LB WEB APP SOA MQ CACHE STORAGE 本文旨在简单介绍大型互联网的架构和核心组件实现原理. 理论上讲,从安装配置 ...

  9. PHP实现上一篇、下一篇

    //php实现上一篇.下一篇 获取当前浏览文章id $id = isset($_GET[ ? intval($_GET['id']) : ""; 下一篇文章 $query = my ...

随机推荐

  1. Lambda表达式的无参数无返回值的练习和Lambda表达式有参数有返回值的练习

    使用Lambda(无参无返回) 说明:给定一个厨师(Cook)接口,内含唯一的抽象方法makeFood,且无参数.无返回值.如下: public interface Cook{ public abst ...

  2. springboot2+jpa+oracle实例

     pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="ht ...

  3. MISC 2022/4/21 刷题记录-千字文

    1.千字文 得到名为png的无类型文件,010 Editor查看,png,改后缀,得到二维码 QR扫描,得到一句话"这里只有二维码" 思路不对,binwalk一下,发现有错误信息 ...

  4. SQLZOO练习四--SUM and COUNT(聚合函数)

    World Country Profile: Aggregate functions This tutorial is about aggregate functions such as COUNT, ...

  5. 分享|2022数字安全产业大数据白皮书(附PDF)

    内容摘要: 2021年以来,数字安全赛道的受关注程度达到一个历史新高度.<数据安全法><个人信息保护法><关键信息基础设施安全保护条例>,一个接一个重磅的法规接连出 ...

  6. Jmeter-记一次自动化造数引发的BeanShell写入excel实例

    一.前言 最近工作和生活说忙也忙,说不忙也不忙,但就是已经感觉很长时间没有get新的技术技能了,就是一丢丢的那种也没有,哈哈哈,今天就来讲一下最近get到的小技能吧. 工作中,由于某个需求需要几百条数 ...

  7. 【黄啊码】MySQL入门—3、我用select *,老板直接赶我坐火车回家去,买的还是站票

    大家好!我是黄啊码,学会了DDL语句了吗?那我们今天就来学习一下基本的查询语法,我见过很多外包机构的程序员都是万物皆可select *,然后项目跑了一段时间就基本跑不动了,问就回答:服务器配置不够,加 ...

  8. 「Python实用秘技09」更好用的函数运算缓存

    本文完整示例代码及文件已上传至我的Github仓库https://github.com/CNFeffery/PythonPracticalSkills 这是我的系列文章「Python实用秘技」的第9期 ...

  9. 关于2022年3月9日之后Typora登录不了--已解决

    p.s.今天是2022.7.27,软件版本:13.6.1 (以下所有方法,亲自尝试后整理出的) 报错信息: This beta version of typora is expired, please ...

  10. Web Worker: Shared Worker的使用

    Web Worker: Shared Worker的使用 参考资料: JavaScript高级程序第四版 https://juejin.cn/post/7064486575916187656 http ...