服务网格(Service Mesh):概念、功能与 Istio 实践
1. 什么是服务网格(Service Mesh)
服务网格是一种服务间通信基础设施。在服务网格架构下,微服务之间不会直接通信,所有服务间的通信都通过名为服务网格代理(或边车代理)的软件组件进行。边车代理与服务位于同一虚拟机(VM)或 Kubernetes 中的 Pod 内,边车代理层被称为数据平面,所有这些边车代理由控制平面进行管理,控制平面负责应用所有与服务间通信相关的配置。
边车模式是指边车作为一个软件组件,与主应用共置,但在自己的进程或容器中运行,提供网络接口以进行连接,具有语言无关性。核心应用功能在主应用逻辑中实现,而与业务逻辑无关的通用横切特性则由边车提供。通常,应用的所有入站和出站通信都通过边车代理进行。
服务网格为一些网络功能提供内置支持,如弹性、服务发现等。这使得服务开发人员可以更专注于业务逻辑,而将大部分与网络通信相关的工作卸载到服务网格中。例如,微服务调用其他服务时,无需再担心熔断机制,因为这是服务网格的一部分功能。
服务网格具有语言无关性,微服务与服务网格代理之间的通信始终通过标准协议进行,如 HTTP1.x/2.x、gRPC 等。无论使用何种技术编写微服务,都能与服务网格协同工作。
2. 服务与边车代理的边界和职责
明确服务和边车代理之间的边界和职责非常重要。以下是不同层面的职责划分:
- 业务逻辑 :服务实现应包含特定服务的业务功能实现,包括与业务功能相关的逻辑、计算、与其他服务/系统(包括遗留系统、专有系统和 SaaS)的集成、服务组合、复杂路由逻辑以及不同业务实体之间的类型映射逻辑等。
- 基本网络功能 :尽管大部分网络功能被卸载到服务网格,但服务必须包含与服务网格边车代理进行连接的基本高级网络交互。因此,服务实现需要使用某种网络库来发起网络调用(仅针对服务网格代理)。在大多数情况下,微服务开发框架会嵌入这些功能所需的网络库,如基本的 HTTP 传输。
- 应用网络功能 :与网络紧密耦合的应用功能,如熔断、超时、服务发现等,与服务代码/业务逻辑明确分离,服务网格会直接提供这些功能。最初的微服务实现往往忽视了集中式 ESB 层提供的网络功能的重要性,在每个微服务级别从头实现这些功能。现在,他们开始认识到将类似的共享功能作为分布式网格的重要性。
3. 控制平面
所有服务网格代理由控制平面进行集中管理,这在支持服务网格功能(如访问控制、可观测性、服务发现等)时非常有用。在控制平面所做的所有更改都会推送到边车代理。
4. 服务网格的功能
服务网格提供一系列应用网络功能,而基本网络功能(如通过本地网络调用边车)仍在微服务级别实现。以下是服务网格常见的功能:
| 功能 | 描述 |
| ---- | ---- |
| 服务间通信弹性 | 支持熔断、重试、超时、故障注入、故障处理、负载均衡和故障转移等网络通信能力。使用服务网格后,无需在服务代码中构建这些网络功能。 |
| 服务发现 | 运行在服务网格中的服务需要通过逻辑命名方案进行发现(无硬编码的主机或端口)。服务网格与特定的服务发现工具协作,支持服务注册和发现。大多数服务网格实现都具备开箱即用的服务发现功能,例如 Istio 利用底层的 Kubernetes 和 etcd 提供内置的服务发现支持。如果已有服务发现解决方案(如 Consul),也可与服务网格集成。 |
| 路由 | 支持一些基本的路由功能,如基于特定标头、版本等进行路由。在服务网格路由层实现功能时,需谨慎避免将业务逻辑包含在路由逻辑中。 |
| 可观测性 | 使用服务网格时,无需对代码进行任何更改,所有服务都能自动实现可观测性。可提供指标、监控、分布式日志记录、分布式追踪和服务可视化等功能。由于所有流量数据在边车代理级别捕获,边车代理可将这些数据发布到负责分析的相关控制平面组件,并将其发布到相应的可观测性工具。 |
| 安全 | 支持服务间通信的传输层安全(TLS)和基于角色的访问控制(RBAC)。一些现有的服务网格实现也在不断添加更多与安全相关的功能。 |
| 部署 | 几乎所有服务网格实现都与容器和容器管理系统紧密集成。Docker 和 Kubernetes 是服务网格部署的事实上的标准,但也可以在虚拟机中运行。 |
| 服务间通信协议 | 支持不同的通信协议,如 HTTP1.x、HTTP2 和 gRPC。服务必须使用与要代理的服务相同的协议与边车进行通信。服务网格负责处理大部分底层通信细节,而服务代码使用基本网络功能调用边车。 |
5. Istio 介绍
Istio 是一个用于连接、管理和保护微服务的开放平台。它为微服务间的通信提供基础设施,具备弹性、路由、负载均衡、服务间认证、可观测性等功能,无需对服务代码进行任何更改。
要将服务添加到 Istio 服务网格,只需将 Istio 边车代理与服务一起部署。如前文所述,Istio 边车代理负责微服务之间的所有网络通信,通过 Istio 控制平面进行配置和管理。Istio 部署与 Kubernetes 深度集成,但也可部署在其他系统上。
Istio 架构包含两个逻辑组件:
- 数据平面 :由一组边车代理组成,负责路由和控制微服务之间的所有网络通信。Istio 的数据平面主要由 Envoy 代理(由 Lyft 开发)构成。
- 控制平面 :负责管理和配置边车代理,以改变其网络通信行为。控制平面由 Pilot、Mixer 和 Citadel 组件组成。
以下是 Istio 架构的 mermaid 流程图:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
subgraph 控制平面
Pilot([Pilot]):::process
Mixer([Mixer]):::process
Citadel([Citadel]):::process
end
subgraph 数据平面
Envoy1([Envoy 代理 1]):::process
Envoy2([Envoy 代理 2]):::process
end
Pilot --> Envoy1
Pilot --> Envoy2
Mixer --> Envoy1
Mixer --> Envoy2
Citadel --> Envoy1
Citadel --> Envoy2
Envoy1 <--> Envoy2
6. Istio 组件功能
- Istio 代理 :在数据平面中,Istio 使用增强版的 Envoy 代理(用 C++ 开发的高性能代理)来调解服务网格中所有服务的入站和出站流量。Istio 利用 Envoy 的许多内置功能,如动态服务发现、负载均衡、TLS 终止、HTTP/2 和 gRPC 代理、熔断、健康检查、基于百分比的流量拆分的分阶段推出、故障注入和丰富的指标。Envoy 作为边车与微服务一起部署,负责微服务的所有入站和出站网络通信。
- Mixer :负责在服务网格中实施访问控制和使用策略,并从 Istio 代理和其他服务收集遥测数据。Istio 代理提取请求级别的属性,并将其发送到 Mixer 进行评估。Mixer 允许将服务/应用代码与策略决策完全解耦,将策略决策从应用层转移到配置中,由操作员进行控制。应用代码只需与 Mixer 进行简单集成,Mixer 负责与后端系统进行交互。Mixer 在 Istio 生态系统中提供三个主要功能:Istio 代理边车在每个请求前逻辑上调用 Mixer 进行前置条件检查,在每个请求后报告遥测数据。边车具有本地缓存,可在缓存中执行大部分前置条件检查。此外,边车缓冲出站遥测数据,减少对 Mixer 的调用频率。
- Pilot :Istio 中用于流量管理的核心组件是 Pilot,它管理和配置特定 Istio 服务网格中部署的所有 Istio 代理实例。Pilot 允许指定流量在 Istio 代理之间路由的规则,并配置故障恢复功能,如超时、重试和熔断。它还维护网格中所有服务的规范模型,并通过其发现服务让 Istio 代理实例了解网格中的其他 Istio 代理实例。Pilot 维护的服务规范表示独立于底层平台,它抽象了特定于平台的服务发现机制,并将其综合成任何符合 Envoy 数据平面 API 的边车都能使用的标准格式。
- Citadel :使用相互 TLS 提供强大的服务间和最终用户认证,具备内置的身份和凭证管理功能。它可用于升级服务网格中的未加密流量,并使操作员能够基于服务身份而非网络控制来实施策略。
7. 使用 Istio 运行服务
如果在 Kubernetes 上运行微服务,使用 Istio 运行服务的步骤如下:
1. 创建 Docker 镜像 :为服务创建 Docker 镜像。
2. 创建 Kubernetes 工件 :创建用于部署服务的 Kubernetes 工件。例如,开发一个简单的 hello 服务,以下是通用的 Kubernetes 部署描述符:
apiVersion: v1
kind: Service
metadata:
name: helloworld
labels:
app: helloworld
spec:
type: NodePort
ports:
- port: 5000
name: http
selector:
app: helloworld
---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: helloworld-v1
spec:
replicas: 1
template:
metadata:
labels:
app: helloworld
version: v1
spec:
containers:
- name: helloworld
image: kasunindrasiri/examples-helloworld-v1
resources:
requests:
cpu: "100m"
imagePullPolicy: IfNotPresent #Always
ports:
- containerPort: 5000
---
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: helloworld-gateway
spec:
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: helloworld
spec:
hosts:
- "*"
gateways:
- helloworld-gateway
http:
- match:
- uri:
exact: /hello
route:
- destination:
host: helloworld
port:
number: 5000
- 注入 Istio 边车 :可以通过 Istio 安装的自动功能或手动过程将 Istio 边车注入到部署中。为了更好地理解其行为,这里使用手动边车注入:
istioctl kube-inject -f helloworld.yaml -o helloworld-istio.yaml
此命令会修改部署描述符,并将 Istio 代理添加到要创建的 Pod 中,使 Istio 代理在该场景中充当边车。
4. 部署服务 :完成边车注入后,部署修改后的部署描述符:
kubectl create -f helloworld-istio.yaml
现在,你可以通过节点端口或入口(如果有)访问服务,流量将通过 Istio 服务网格流动。(如有需要,可以通过在 Istio 级别启用追踪来验证这一点。)
8. Istio 的流量管理
当一个服务调用另一个服务或特定服务暴露给外部客户端时,可以应用 Istio 的流量管理功能,根据不同机制对流量进行路由。这将流量流与基础设施扩展解耦,允许通过 Pilot 指定流量应遵循的规则,而不是指定哪些特定的 Pod/VM 应接收流量。流量管理功能还包括用于 A/B 测试、渐进式推出、金丝雀发布、使用超时、重试、熔断和故障注入进行故障恢复的动态请求路由。
Istio 定义了四种流量管理配置资源:
- VirtualService :定义了在访问主机时应用的一组流量路由规则。每个路由规则定义了特定协议流量的匹配标准。如果流量匹配,则将其发送到注册表中定义的命名目标服务(或其子集/版本)。路由规则中还可以匹配流量的来源,这允许针对特定客户端上下文定制路由。
- DestinationRule :配置在 VirtualService 路由发生后应用于请求的一组策略。这些规则指定了负载均衡、边车的连接池大小以及用于检测和从负载均衡池中排除不健康主机的异常检测设置的配置。
以下是一个简单的请求流程 mermaid 流程图:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
ExternalClient([外部客户端]):::process --> IstioGateway([Istio 入口网关]):::process
IstioGateway --> VirtualServiceA([VirtualService A]):::process
VirtualServiceA --> MicroserviceA([微服务 A]):::process
MicroserviceA --> VirtualServiceB([VirtualService B]):::process
VirtualServiceB --> MicroserviceB([微服务 B]):::process
通过以上内容,我们了解了服务网格的基本概念、功能,以及 Istio 作为服务网格实现的架构、组件和使用方法。在实际应用中,可以根据具体需求利用服务网格和 Istio 的功能来优化微服务架构。
服务网格(Service Mesh):概念、功能与 Istio 实践
9. Istio 流量管理配置示例
为了更清晰地展示 Istio 流量管理配置资源的使用,下面通过具体示例进一步说明。
假设我们有一个微服务系统,其中包含 productpage 、 reviews 、 details 和 ratings 四个服务,我们要对 reviews 服务的不同版本进行流量管理。
首先,定义 VirtualService 来控制流量路由:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
route:
- destination:
host: reviews
subset: v2
- route:
- destination:
host: reviews
subset: v1
在这个 VirtualService 中,当请求的 end-user 头为 jason 时,流量将被路由到 reviews 服务的 v2 版本;否则,流量将被路由到 v1 版本。
接着,定义 DestinationRule 来配置服务的策略:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
DestinationRule 为 reviews 服务定义了两个子集 v1 和 v2 ,并通过标签来区分不同版本的服务实例。
10. Istio 的可观测性实践
Istio 提供了强大的可观测性能力,包括指标、监控、分布式日志记录和分布式追踪等。以下是如何利用 Istio 实现可观测性的步骤:
指标和监控
Istio 默认会收集服务之间的请求指标,如请求计数、响应时间等。可以通过 Prometheus 和 Grafana 来查看这些指标。
1. 安装 Prometheus 和 Grafana :使用 Helm 或其他方式在 Kubernetes 集群中安装 Prometheus 和 Grafana。
2. 配置 Istio 与 Prometheus 集成 :确保 Istio 配置中开启了 Prometheus 集成,这样 Istio 会将指标数据发送到 Prometheus。
3. 在 Grafana 中配置数据源和仪表盘 :将 Prometheus 作为数据源添加到 Grafana,并导入 Istio 官方提供的仪表盘模板,即可查看各种指标图表。
分布式日志记录
Istio 可以与 Fluentd 等日志收集工具集成,将服务的日志集中收集和管理。
1. 安装 Fluentd :在 Kubernetes 集群中部署 Fluentd 作为日志收集器。
2. 配置 Istio 与 Fluentd 集成 :修改 Istio 配置,将日志输出到 Fluentd。
3. 使用 Elasticsearch 和 Kibana 查看日志 :将 Fluentd 收集的日志发送到 Elasticsearch,并通过 Kibana 进行可视化查看。
分布式追踪
Istio 支持使用 Jaeger 进行分布式追踪,帮助我们了解请求在微服务之间的调用路径和性能。
1. 安装 Jaeger :在 Kubernetes 集群中部署 Jaeger。
2. 配置 Istio 与 Jaeger 集成 :确保 Istio 配置中开启了 Jaeger 追踪功能。
3. 查看追踪信息 :通过 Jaeger UI 查看请求的追踪信息,分析每个服务的处理时间和调用关系。
11. Istio 的安全功能应用
Istio 提供了多种安全功能,如传输层安全(TLS)和基于角色的访问控制(RBAC)。以下是如何应用这些安全功能的步骤:
传输层安全(TLS)
1. 生成证书和密钥 :使用工具(如 OpenSSL)为服务生成 TLS 证书和密钥。
2. 配置 Istio 启用 TLS :在 Istio 配置中指定证书和密钥的位置,开启服务间的 TLS 通信。例如:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
tls:
mode: ISTIO_MUTUAL
上述配置表示 reviews 服务使用 Istio 提供的相互 TLS 模式进行通信。
基于角色的访问控制(RBAC)
1. 定义角色和权限 :在 Istio 中定义不同的角色和对应的权限,如哪些服务可以访问哪些资源。
2. 绑定角色和用户/服务 :将定义好的角色绑定到具体的用户或服务上。例如:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
name: productpage-viewer
spec:
selector:
matchLabels:
app: productpage
rules:
- to:
- operation:
methods: ["GET"]
when:
- key: request.auth.claims[sub]
values: ["jason"]
上述配置表示只有用户 jason 可以对 productpage 服务进行 GET 请求。
12. Istio 与其他技术的集成
Istio 可以与多种技术集成,以扩展其功能。以下是一些常见的集成场景:
| 集成技术 | 集成方式 | 作用 |
|---|---|---|
| Kubernetes | 深度集成,Istio 可利用 Kubernetes 的资源管理和调度功能 | 简化服务部署和管理 |
| Consul | 可与 Istio 集成,作为服务发现工具 | 提供更灵活的服务发现机制 |
| Prometheus | 集成用于收集和存储 Istio 生成的指标数据 | 实现服务的监控和分析 |
| Grafana | 与 Prometheus 结合,用于可视化指标数据 | 提供直观的监控界面 |
| Jaeger | 集成用于分布式追踪 | 帮助分析请求在微服务间的调用路径和性能 |
| Fluentd | 集成用于收集和管理服务日志 | 实现日志的集中化处理 |
13. 总结
服务网格(Service Mesh)作为一种服务间通信基础设施,为微服务架构带来了诸多优势。它通过边车代理实现服务间的通信,将网络功能与业务逻辑分离,使开发人员能够更专注于业务开发。
Istio 作为服务网格的典型实现,提供了丰富的功能,包括弹性、服务发现、路由、可观测性、安全等。通过合理配置 Istio 的组件和资源,如 VirtualService、DestinationRule 等,可以实现灵活的流量管理和故障恢复。同时,Istio 与多种技术的集成能力,进一步扩展了其应用场景和功能。
在实际应用中,我们可以根据具体需求选择合适的服务网格和相关技术,利用它们的功能来优化微服务架构,提高系统的可靠性、可维护性和性能。例如,在复杂的微服务系统中,利用 Istio 的流量管理功能进行 A/B 测试和金丝雀发布;通过可观测性工具及时发现和解决服务故障;使用安全功能保障服务间通信的安全性。
总之,服务网格和 Istio 为微服务架构的发展提供了有力的支持,值得我们深入研究和应用。
超级会员免费看
:概念、功能与 Istio 实践&spm=1001.2101.3001.5002&articleId=154721310&d=1&t=3&u=28f08c2190ac4d7b9116ed55ce40d470)
1431

被折叠的 条评论
为什么被折叠?



