📦 Istio 1.18

🏆 Istio基础

Istio服务网格在逻辑上分为数据平面控制平面

数据平面由一组部署为 sidecar的智能代理(Envoy)组成,这些代理与 Mixer通用策略和遥测中心协调并控制微服务之间的所有网络通信 控制平面管理并配置从代理到路由的流量。此外,控制平面配置 Mixer以执行策略和收集遥测数据

  • 控制平面采用您想要的配置及其服务视图,并动态地对代理服务器进行编程,并根据规则或环境的变化对其进行更新。
  • 数据平面是服务之间的通信。如果没有服务网格,网络就无法理解发送的流量,也无法根据流量的类型或来源或目的地做出任何决策。

⭐️ Istio是一 Sidercar容器的方式,在每一个被治理的应用 pod中运行这个代理服务,这个代理服务就可以通过配置Pod里面的 Iptables来接管整个 Pod的进出流量,这样 Istio的控制层就可以通过调用代理容器的 API来对代理进行配置,从而实现微服务治理

🌟 Istio组件

老架构图:

image-20241024221756429 image-20241024144958562

下面是最新的架构图 Pilot、Mixe、Citadel都被集成在了 istiod上:

image-20241024144903217

Envoy:

Istio 使用 Envoy 代理的扩展版本。Envoy 是用 C++ 开发的高性能代理,用于协调服务网格中所有服务的入站和出站流量。Envoy 代理是唯一与数据平面流量交互的 Istio 组件。

Envoy 代理被部署为服务的 Sidecar,在逻辑上为服务增加了 Envoy 的许多内置特性,例如:

  • 动态服务发现
  • 负载均衡
  • TLS 终止
  • HTTP/2gRPC 代理
  • 熔断器
  • 健康检查
  • 基于百分比流量分割的分阶段发布
  • 故障注入
  • 丰富的指标

这种 Sidecar 部署允许 Istio 可以执行策略决策,并提取丰富的遥测数据, 接着将这些数据发送到监视系统以提供有关整个网格行为的信息。

Sidecar 代理模型还允许您向现有的部署添加 Istio 功能,而不需要重新设计架构或重写代码。

Envoy 代理启用的一些 Istio 的功能和任务包括:

  • 流量控制功能:通过丰富的 HTTPgRPCWebSocketTCP 流量路由规则来执行细粒度的流量控制。
  • 网络弹性特性:重试设置、故障转移、熔断器和故障注入。
  • 安全性和身份认证特性:执行安全性策略,并强制实行通过配置 API 定义的访问控制和速率限制。
  • 基于 WebAssembly 的可插拔扩展模型,允许通过自定义策略执行和生成网格流量的遥测。

Istiod

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

Istiod 将控制流量行为的高级路由规则转换为 Envoy 特定的配置, 并在运行时将其传播给 Sidecar。它提取了特定平台的服务发现机制, 并将其综合为一种所有符合 Envoy APISidecar 都可以使用的标准格式。

Istio 可以支持发现 KubernetesVM 等多种环境。

  • 您可以使用 Istio 流量管理 APIIstiod 重新构造 Envoy 的配置,以便对服务网格中的流量进行更精细的控制。
  • Istiod 安全通过内置的身份和凭证管理, 实现了强大的服务对服务和终端用户认证。
  • 可以使用 Istio 来升级服务网格中未加密的流量。 使用 Istio,运营商可以基于服务身份而不是相对不稳定的第 3 层或第 4 层网络标识符来执行策略。
  • 可以使用 Istio 的鉴权功能控制谁可以访问您的服务。

Istiod 充当证书颁发机构(CA)并生成证书,以允许在数据平面中进行安全的 mTLS 通信。

🌟 Istio流量管理概念

🏢 https://istio.io/v1.18/zh/docs/concepts/traffic-management/#gateways

1️⃣ 虚拟服务

虚拟服务让您配置如何在服务网格内将请求路由传递至需要访问的服务,它提供基本的连通性和服务发现能力,每一个虚拟服务包含一组

路由规则,使用路由规则来进行匹配


IstioVirtualServiceK8sService,相比较它多了熔断,流量分割、重试、超时等,它不仅仅只是负载均衡,它可以精确匹配至某一条路由

虚拟服务可以为一个或多个主机名指定流量行为。在虚拟服务中使用路由规则, 告诉

Envoy 如何发送虚拟服务的流量到适当的目标。路由目标地址可以是同一服务的不同版本, 也可以是完全不同的服务

一个典型的用例是将流量发送到被指定为服务子集的服务的不同版本。 客户端将虚拟服务视为一个单一实体,将请求发送至虚拟服务主机, 然后 Envoy 根据虚拟服务规则把流量路由到不同的版本。例如, “20% 的调用转发到新版本”或“将这些用户的调用转发到版本 2”。 这允许您创建一个金丝雀发布,逐步增加发送到新版本服务的流量百分比。 流量路由完全独立于实例部署,这意味着实现新版本服务的实例可以根据流量的负载来伸缩, 完全不影响流量路由。相比之下,像 Kubernetes 这样的容器编排平台只支持基于实例缩放的流量分发, 这会让情况变得复杂。您可以在

使用 Istio 进行金丝雀部署的文章里阅读到更多用虚拟服务实现金丝雀部署的内容

通过单个虚拟服务处理多个应用程序服务。如果是在 k8s中能使用 istio, 可以配置一个虚拟服务处理特定命名空间中的所有服务,可以在不需要适应转换的情况下,将单体应用转换为微服务构建的复合应用系统。 路由规则可以指定为“对 monolith.com 的 URI 调用转发到 microservice Amicroservice B” 等等

虚拟服务还支持HTTP重定向、重写机制、重试、流量镜像、故障注入、跨域的解决等问题

虚拟服务配置大全https://istio.io/v1.18/zh/docs/reference/config/networking/virtual-service/

image-20241026200829265

2️⃣ 目标规则

虚拟服务一样, 目标规则也是 Istio 流量路由功能的关键部分。可以将虚拟服务视为将流量如何路由到给定目标地址,然后使用目标规则来配置该目标的流量。在评估虚拟服务路由规则之后,目标规则将应用于流量的“真实”目标地址。

image-20241026201259660
也就是一条一条规则。你可以对某些服务进行分组,可以按照版本分组,然后可以在虚拟服务的路由规则中使用这些服务子集来控制到服务不同实例的流量。
在比如存在一个视频网站服务Service管理下面有多个

pod起来的服务,这些服务里面有 v1\v2\v3的版本,那么就可以使用 DestinationRule给他们按照版本分组

image-20241026202505243

目标规则还支持服务熔断、调整负载均衡策略、TLS认证等功能

目标规则配置大全: https://istio.io/v1.18/zh/docs/reference/config/networking/destination-rule/

3️⃣ 网关

网关是用来管理入站和出站流量的,可以指定进入/离开的网格流量,网关配置被用于运行在网格边缘的独立

Envoy 代理

它和

ingress这种七层代理不同,在配置网关时,你不需要在同一个 Gateway 资源中同时配置7层(应用层)的流量路由规则,Istio 允许你将4-6层(TCP/UDP)的负载均衡规则和7层的应用层流量路由规则分开配置。你可以在 Gateway 资源中定义监听端口、TLS设置等4-6层的规则,然后通过绑定 IstioVirtualService 资源来管理7层的流量路由。这样做的好处是,你可以更灵活地管理流量,并且可以像管理网格中其他数据平面的流量一样去管理网关流量

image-20241026215806474

例如,你可以在 Gateway 资源中定义一个监听 80端口的 HTTP 流量的入口,然后在一个单独的 VirtualService 资源中定义如何将这些流量路由到网格内的服务。这样,Gateway 资源专注于处理底层的网络流量转发,而 VirtualService 资源则负责更高级的流量路由和策略管理

网关主要用于管理进入的流量,也可以配置出口网关。出口网关让您为离开网格的流量配置一个专用的出口节点, 这可以限制哪些服务可以或应该访问外部网络,或者启用

出口流量安全控制增强网格安全性。也可以使用网关配置一个纯粹的内部代理。

详细配置大全: https://istio.io/v1.18/zh/docs/reference/config/networking/

4️⃣ 服务入口

ServiceEntry 允许将额外的条目添加到 Istio 的内部服务注册表中,以便网格中自动发现的服务可以访问/路由到这些手动指定的服务。服务条目描述服务的属性(DNS 名称、VIP、端口、协议、终端节点)。这些服务可以是网格外部的(例如,Web API),也可以是不属于平台服务注册表的网格内部服务(例如,一组与 Kubernetes 中的服务通信的 VM)。此外,还可以使用 workloadSelector 字段动态选择服务条目的终端节点。这些终端节点可以是使用 WorkloadEntry 对象或 Kubernetes Pod 声明的 VM 工作负载。在单个服务下同时选择 PodVM 的功能允许将服务从 VM 迁移到 Kubernetes,而无需更改与服务关联的现有 DNS 名称

🍹 额外的知识点: Istio是如何将边车容器注入 pod内的呢?

https://kubernetes.io/blog/2019/03/21/a-guide-to-kubernetes-admission-controllers/


istio通过使用 Admission Controller来将容器无感的注入到 pod内的;Admission 是执行在 API被提交到 kube-Api-Server之前需要执行的"初始化"工作,比如自动给某些 Pod加上标签等等

但是如果是要使用

Admission Controller是有点麻烦的,它是可选择性的编译至 Api-Server中的,如果需要使用它,就要重新编译并且重启 api-server,这样就很麻烦

但是

K8S还提供了另外一种机制那就是 Dynamic Admission Controller,也被称为 Initlizer但是在1.16之后被 admission webhooK 取代但是工作原理和 istio注入机制依然相同,Istio使用的是,MutatingWebhookConfiguration的方法

https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1/

https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/extend-resources/validating-webhook-configuration-v1/

  1. 首先 istio会将 envoy这个代理容器本身的资源清单存储到 configmap
  2. istio将一个编写好的 Initalizer作为一个 pod部署在 k8s中,也就是 operator,它不获取需要注入的容器状态,如果这个pod已经被注入的代理,就放过这个pod,如果没有注入,则进行 initalizer操作

通常是在 metadata上有一个 initailizer.pending 的信息来判断

  1. 进入 initalizer操作,它会先从 Api Server中获取这个存储 envoy配置的 ConfigMap,将它添加到一个空的 pod对象里面,然后通过 TwoWayMergePatch将两个 pod结合生成一个 patch数据、
  2. 通过 patch数据向 Kubernetes Client发起 Patch请求,这样就完成了容器注入

image-20241028135427761