Istio
Istio 是一个完全开源的服务网格,以透明的方式构建在现有的分布式应用中。它也是一个平台,拥有可以集成任何日志、遥测和策略系统的 API 接口。Istio 多样化的特性使你能够成功且高效地运行分布式微服务架构,并提供保护、连接和监控微服务的统一方法。
核心功能
流量控制
微服务应用最大的痛点就是处理服务间的通信,而这一问题的核心其实就是流量管理。首先我们来看看传统的微服务应用在没有 Service Mesh 介入的情况下,是如何完成诸如金丝雀发布这样的路由功能的。我们假设不借助任何现成的第三方框架,一个最简单的实现方法,就是在服务间添加一个负载均衡(比如 Nginx)做代理,通过修改配置的权重来分配流量。这种方式使得对流量的管理和基础设施绑定在了一起,难以维护。
而使用 Istio 就可以轻松的实现各种维度的流量控制。下图是典型的金丝雀发布策略:根据权重把 5% 的流量路由给新版本,如果服务正常,再逐渐转移更多的流量到新版本。
Istio 中的流量控制功能主要分为三个方面:
- 请求路由和流量转移
- 弹性功能,包括熔断、超时、重试
- 调试能力,包括故障注入和流量镜像
关于流量控制的更多内容,参考 Istio 流量控制
安全管理
安全对于微服务这样的分布式系统来说至关重要。与单体应用在进程内进行通信不同,网络成为了服务间通信的纽带,这使得它对安全有了更迫切的需求。比如为了抵御外来攻击,我们需要对流量进行加密;为保证服务间通信的可靠性,需要使用 mTLS 的方式进行交互;为控制不同身份的访问,需要设置不同粒度的授权策略。作为一个服务网格,Istio 提供了一整套完整的安全解决方案。它可以以透明的方式,为我们的微服务应用添加安全策略。
Istio 中的安全架构是由多个组件协同完成的。
- Citadel 是负责安全的主要组件,用于密钥和证书的管理;
- Pilot 会将安全策略配置分发给 Envoy 代理;
- Envoy 执行安全策略来实现访问控制。
下图展示了 Istio 的安全架构和运作流程:
关于安全管理的更多内容,参考 Istio 安全管理
可观测性
面对复杂的应用环境和不断扩展的业务需求,即使再完备的测试也难以覆盖所有场景,无法保证服务不会出现故障。正因为如此,才需要“可观察性”来对服务的运行时状态进行监控、上报、分析,以提高服务可靠性。具有可观察性的系统,可以在服务出现故障时大大降低问题定位的难度,甚至可以在出现问题之前及时发现问题以降低风险。具体来说,可观察性可以:
- 及时反馈异常或者风险使得开发人员可以及时关注、修复和解决问题(告警);
- 出现问题时,能够帮助快速定位问题根源并解决问题,以减少服务损失(减损);
- 收集并分析数据,以帮助开发人员不断调整和改善服务(持续优化)。
而在微服务治理之中,随着服务数量大大增加,服务拓扑不断复杂化,可观察性更是至关重要。Istio 自然也不可能缺少对可观察性的支持。它会为所有的服务间通信生成详细的遥测数据,使得网格中每个服务请求都可以被观察和跟踪。开发人员可以凭此定位故障,维护和优化相关服务。而且,这一特性的引入无需侵入被观察的服务。
Istio 一共提供了三种不同类型的数据从不同的角度支撑起其可观察性:
- 指标(Metrics)
- 日志(Access Logs)
- 分布式追踪(Distributed Traces)
关于可观测行的更多内容,参考 Istio 可观测性
架构解析
Istio 的架构由控制平面和数据平面两个部分组成。
- 数据平面:由整个网格内的 sidecar 代理组成,每个 sidecar 代理会接管流入和流出服务的流量,并配合控制平面完成流量控制等方面的内容。
- 控制平面:负责控制和管理数据平面的 sidecar 代理,完成配置的分发、服务发现和授权鉴权等功能。
控制平面是 Istio 在原有服务网格产品上,首次提出的架构,实现了对于数据平面的统一管理。
控制平面
Pilot
Pilot 组件的主要功能是将路由规则等配置信息转换为 sidecar 可以识别的信息,并下发给数据平面。可以把它简单的理解为是一个配置分发器(dispatcher),并辅助 sidecar 完成流量控制相关的功能。它管理 sidecar 代理之间的路由流量规则,并配置故障恢复功能,如超时、重试和熔断。
上图显示了 Pilot 的基本架构,它主要由以下几个部分组成:
Abstract Model
为了实现对不同服务注册中心 (Kubernetes、consul) 的支持,Pilot 需要对不同的输入来源的数据有一个统一的存储格式,也就是抽象模型。抽象模型中定义的关键成员包括 HostName(Service 名称)、Ports(Service 端口)、Address(Service ClusterIP)、Resolution (负载均衡策略) 等。
Platform Adapters
借助平台适配器 Pilot 可以实现服务注册中心数据到抽象模型之间的数据转换。例如 Pilot 中的 Kubernetes 适配器通过 Kubernetes API 服务器得到 Kubernetes 中 Service 和 Pod 的相关信息,然后翻译为抽象模型提供给 Pilot 使用。通过平台适配器模式,Pilot 还可以从 Consul 等平台中获取服务信息,还可以开发适配器将其他提供服务发现的组件集成到 Pilot 中。
xDS API
Pilot 使用了一套起源于 Envoy 项目的标准数据面 API 来将服务信息和流量规则下发到数据面的 sidecar 中。这套标准数据面 API,也叫 xDS。Sidecar 通过 xDS API 可以动态获取 Listener (监听器)、Route (路由)、Cluster(集群)及 Endpoint (集群成员)配置:
- LDS,Listener 发现服务:Listener 监听器控制 sidecar 启动端口监听(目前只支持 TCP 协议),并配置 L3/L4 层过滤器,当网络连接达到后,配置好的网络过滤器堆栈开始处理后续事件。
- RDS,Router 发现服务:用于 HTTP 连接管理过滤器动态获取路由配置,路由配置包含 HTTP 头部修改(增加、删除 HTTP 头部键值),virtual hosts (虚拟主机),以及 virtual hosts 定义的各个路由条目。
- CDS,Cluster 发现服务:用于动态获取 Cluster 信息。
- EDS,Endpoint 发现服务:用于动态维护端点信息,端点信息中还包括负载均衡权重、金丝雀状态等,基于这些信息,Sidecar 可以做出智能的负载均衡决策。
User API
Pilot 还定义了一套用户 API, 用户 API 提供了面向业务的高层抽象,可以被运维人员理解和使用。
运维人员使用该 API 定义流量规则并下发到 Pilot,这些规则被 Pilot 翻译成数据面的配置,再通过标准数据面 API 分发到 sidecar 实例,可以在运行期对微服务的流量进行控制和调整。
通过运用不同的流量规则,可以对网格中微服务进行精细化的流量控制,如按版本分流、断路器、故障注入、灰度发布等。
关于 Pilot 的具体实现,可以参考 Istio Pilot 模块分析
Citadel
Citadel 是 Istio 中专门负责安全的组件,内置有身份和证书管理功能,可以实现较为强大的授权和认证等操作,在 1.5 版本之后取消了独立进程,作为一个模块被整合在 istiod 中。
总体来说,Istio 在安全架构方面主要包括以下内容:
- 证书签发机构(CA)负责密钥和证书管理
- API 服务器将安全配置分发给数据平面
- 客户端、服务端通过代理安全通信
- Envoy 代理管理遥测和审计
Istio 的身份标识模型使用一级服务标识来确定请求的来源,它可以灵活的标识终端用户、工作负载等。在平台层面,Istio 可以使用类似于服务名称来标识身份,或直接使用平台提供的服务标识。比如 Kubernetes 的 ServiceAccount,AWS IAM 用户、角色账户等。
在身份和证书管理方面,Istio 使用 X.509 证书,并支持密钥和证书的自动轮换。从 1.1 版本开始,Istio 开始支持安全发现服务器(SDS),随着不断的完善和增强,1.5 版本 SDS 已经成为默认开启的组件。Citadel 以前有两个功能:将证书以 Secret 的方式挂载到命名空间里;通过 SDS gRPC 接口与 nodeagent(已废弃)通信。目前 Citadel 只需要完成与 SDS 相关的工作,其他功能被移动到了 istiod 中。
关于 Citadel 的更多内容,参考 Istio 安全管理
Galley
Galley 是 Istio 1.1 版本中新增加的组件,其目的是将 Pilot 和底层平台(如 Kubernetes)进行解耦。它分担了原本 Pilot 的一部分功能,主要负责配置的验证、提取和处理等功能。
数据平面
Istio 数据平面核心是以 sidecar 模式运行的智能代理。Sidecar 模式将数据平面核心组件部署到单独的流程或容器中,以提供隔离和封装。Sidecar 应用与父应用程序共享相同的生命周期,与父应用程序一起创建和退出。Sidecar 应用附加到父应用程序,并为应用程序提供额外的特性支持。
如下图所示,数据平面的 sidecar 代理可以调节和控制微服务之间所有的网络通信,每个服务 Pod 启动时会伴随启动 istio-init 和 proxy 容器。
istio-init容器主要功能是初始化 Pod 网络和对 Pod 设置 iptable 规则,设置完成后自动结束。- Proxy 容器会启动两个服务:
istio-agent以及网络代理组件istio-agent的作用是同步管理数据,启动并管理网络代理服务进程,上报遥测数据- 网络代理组件则根据管理策略完成流量管控、生成遥测数据。
数据平面真正触及到对网络数据包的相关操作,是上层控制平面策略的具体执行者。
Envoy 是 Istio 中默认的数据平面 Sidecar 代理,关于 Sidecar 是如何实现自动注入和流量劫持,以及 Sidecar 的流量路由机制如何实现,更多可参考 Envoy 系列文章 。
安装部署
下载安装
这里介绍在 Kubernetes 环境下安装 Istio,在开始之前,你需要有一个 Kubernetes 运行环境。
从 Istio v1.7 版本开始,Istio 官方推荐使用 istioctl 安装。下面是安装步骤:
- 在 Istio release 页面下载与操作系统匹配的安装包,并将其解压。这里可以直接用 Istio 提供的脚本:
|
|
安装目录内容:
| 目录 | 包含内容 |
|---|---|
bin |
包含 istioctl 的客户端文件 |
manifests |
包含 各种部署的 manifests |
samples |
包含示例应用程序 |
tools |
包含用于性能测试和在本地机器上进行测试的脚本 |
- 将
istioctl客户端路径加入$PATH中,从而可以使用 istioctl 命令行工具
|
|
- 安装
demo配置
|
|
- 添加一个 Namespace Label,使得之后在部署你的应用的时候,istio 会自动注入 Envoy sidecar 代理
|
|
部署 Bookinfo
Bookinfo 是 Istio 社区官方推荐的示例应用之一。它可以用来演示多种 Istio 的特性,并且它是一个异构的微服务应用。该应用由四个单独的微服务构成。 这个应用模仿了在线书店,可以展示书店中书籍的信息。例如页面上会显示一本书的描述,书籍的细节( ISBN、页数等),以及关于这本书的一些评论。
Bookinfo 应用分为四个单独的微服务, 这些服务对 Istio 并无依赖,但是构成了一个有代表性的服务网格的例子:它由多个不同语言编写的服务构成,并且其中有一个应用会包含多个版本。
productpage会调用details和reviews两个微服务,用来生成页面。details中包含了书籍的信息。reviews中包含了书籍相关的评论。它还会调用ratings微服务。ratings中包含了由书籍评价组成的评级信息。
reviews 微服务有 3 个版本,可用来展示各服务之间的不同的调用链路:
- v1 版本不会调用
ratings服务。 - v2 版本会调用
ratings服务,并使用 1 到 5 个黑色星形图标来显示评分信息。 - v3 版本会调用
ratings服务,并使用 1 到 5 个红色星形图标来显示评分信息。
下图展示了这个应用的端到端架构:
- 部署示例应用程序
|
|
- 之后应用起来,当每个 Pod 状态变为 Ready 的时候,sidecar 也部署成功。
|
|
- 查看应用是否成功运行,通过给 productpage 发送请求,查看其返回
|
|
集群外部访问应用
到现在,Bookinfo 应用已经成功部署,我们在集群内部也已经可以访问,但是在集群外部还不能够访问。为了使得外部能够访问应用程序,我们需要创建一个Istio Ingress Gateway。
- 将应用于 istio gateway 关联
|
|
- 确保配置上没有问题
|
|
- 确定 Ingress 的 IP 和 Ports
通过下面的命令来设置 INGRESS_HOST 和 INGRESS_PORT环境变量。
|
|
这里显示 EXTERNAL_IP 已经变设置,表明当前环境下有一个可以使用的外部负载均衡器。
|
|
- 设定 GATEWAY_URL
|
|
- 确认外部访问是否成功:在浏览器直接访问
http://<GATE_WAYURL>/productpage来访问 Bookinfo 应用
查看 Dashboard
Istio 集成了 一些遥测应用 ,他们可以帮助你对你的服务网格有直观的认识、展示网格的拓扑、分析网格的健康状态
- 安装 Kiali
|
|
- 访问 Kiali
官方教程指示使用 istioctl dashboard kiali 命令来打开浏览器访问 Kiali 服务,但是我的 Kubernetes 集群在服务器上,这样显然不行,不要将 Kiali 服务暴露给外部。因为之前集群已经安装了 Traefik ,所以可以使用 Ingress 来暴露。
|
|
在命令行创建 Ingress,打开浏览器访问 http://<NodeIP>:<TraefikWebNodePort>/kiali 即可访问 Kiali
在左侧导航栏点击 Graph,选择 default 的命名空间,可以看到 Bookinfo 应用中各个服务间的关系:
到此为止,你的 Istio 和相关的服务已经在集群中完好的部署,关于其具体功能演示,参照 Istio 流量控制。