什么是istio
Istio是一个开放平台,提供统一的方式来集成微服务,管理跨微服务的流量,执行策略和汇总遥测数据。Istio的控制面板在底层集群管理平台(如Kubernetes,Mesos等)上提供了一个抽象层
为什么要用istio
Istio 提供一种简单的方式来为已部署的服务建立网络,该网络具有负载均衡、服务间认证、监控等功能,只需要对服务的代码进行一点或不需要做任何改动。想要让服务支持 Istio,只需要在您的环境中部署一个特殊的 sidecar 代理,使用 Istio 控制平面功能配置和管理代理,拦截微服务之间的所有网络通信:
- HTTP、gRPC、WebSocket 和 TCP 流量的自动负载均衡。
- 通过丰富的路由规则、重试、故障转移和故障注入,可以对流量行为进行细粒度控制。
- 可插入的策略层和配置 API,支持访问控制、速率限制和配额。
- 对出入集群入口和出口中所有流量的自动度量指标、日志记录和追踪。
- 通过强大的基于身份的验证和授权,在集群中实现安全的服务间通信。 Istio 旨在实现可扩展性,满足各种部署需求。
istio架构
Istio的整体架构,从逻辑上,Istio分为数据平面和控制平面两个部分:数据平面是以 sidecar 方式部署的智能代理,Istio默认集成的是Envoy。数据平面用来控制微服务之间的网络通讯。控制平面负责管理和配置数据平面,控制数据平面的行为,如代理路由流量,实施策略,收集遥测数据,加密认证等。控制平面分为Pilot、Citadel、Galley三个组件,1.5版本以后废弃了Mixer,后面再详细介绍。
控制平面
Pilot
Pilot 为 Envoy sidecar 提供服务发现、用于智能路由的流量管理功能(例如,A/B 测试、金丝雀发布等)以及弹性功能(超时、重试、熔断器等)。
Pilot 将控制流量行为的高级路由规则转换为特定于环境的配置,并在运行时将它们传播到 sidecar。Pilot 将特定于平台的服务发现机制抽象出来,并将它们合成为任何符合 Envoy API 的 sidecar 都可以使用的标准格式。
Citadel
Citadel 通过内置的身份和证书管理,可以支持强大的服务到服务以及最终用户的身份验证。您可以使用 Citadel 来升级服务网格中的未加密流量。使用 Citadel,operator 可以执行基于服务身份的策略,而不是相对不稳定的 3 层或 4 层网络标识。从 0.5 版开始,您可以使用 Istio 的授权特性来控制谁可以访问您的服务。
Galley
Galley 是 Istio 的配置验证、提取、处理和分发组件。它负责将其余的 Istio 组件与从底层平台(例如 Kubernetes)获取用户配置的细节隔离开来。
数据平面
Envoy
Istio 使用 Envoy 代理的扩展版本,Envoy 是以 C++ 开发的高性能代理,用于调解服务网格中所有服务的所有入站和出站流量。Envoy 的许多内置功能被 Istio 发扬光大
Envoy 被部署为 sidecar,和对应服务在同一个 Kubernetes pod 中。这允许 Istio 将大量关于流量行为的信号作为属性提取出来
Sidecar 代理模型还可以将 Istio 的功能添加到现有部署中,而无需重新构建或重写代码。
这里要介绍下一个重要的概念:边车(Sidecar),下图可以形象的解释什么是边车。
边车模式是一种分布式架构的设计模式。边车模式通过给应用服务加装一个“边车”来达到控制和逻辑的分离的目的。
比如日志记录、监控、流量控制、服务注册、服务发现、服务限流、服务熔断等在业务服务中不需要实现的控制面功能,可以交给“边车”,业务服务只需要专注实现业务逻辑即可。如上图那样,应用服务你只管开好你的车,打仗的事情就交给边车上的代理就好。这与分布式和微服务架构完美契合,真正的实现了控制和逻辑的分离与解耦。
流量管理
使用 Istio 的流量管理模型,本质上是将流量与基础设施扩容解耦,让运维人员可以通过 Pilot 指定流量遵循什么规则,而不是指定哪些 pod/VM 应该接收流量——Pilot 和智能 Envoy 代理会帮我们搞定。
安装istio
1、访问 Istio release 页面下载与您操作系统对应的安装文件。
2、解压并切换到 Istio 包所在目录下。安装目录包含如下内容:
- install/kubernetes 目录下,有 Kubernetes 相关的 YAML 安装文件
- samples/ 目录下,有示例应用程序
- bin/ 目录下,包含 istioctl 的客户端文件。istioctl 工具用于手动注入 Envoy sidecar 代理。
3、将 istioctl 客户端路径增加到 path 环境变量中,macOS 或 Linux 系统的增加方式如下:
export PATH=$PWD/bin:$PATH
4、安装 demo 配置,istioctl manifest apply --set profile=demo
流量策略资源配置
Istio 中包含有四种流量管理配置资源,分别是 VirtualService、DestinationRule、ServiceEntry 以及 Gateway。下面会讲一下这几个资源的一些重点。
- VirtualService 在 Istio 服务网格中定义路由规则,控制路由如何路由到服务上。
- DestinationRule 是 VirtualService 路由生效后,配置应用与请求的策略集。
- ServiceEntry 是通常用于在 Istio 服务网格之外启用对服务的请求。
- Gateway 为 HTTP/TCP 流量配置负载均衡器,最常见的是在网格的边缘的操作,以启用应用程序的入口流量。
VirtualService使用介绍
- 规则的目标描述
路由规则对应着一或多个用 VirtualService 配置指定的请求目的主机。这些主机可以是也可以不是实际的目标负载,甚至可以不是同一网格内可路由的服务。
1
2
3
hosts:
- reviews
- bookinfo.com
- 在服务之间分拆流量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- route:
- destination:
host: reviews
subset: v1
weight: 75
- destination:
host: reviews
subset: v2
weight: 25
...
- 超时和重试
缺省情况下,HTTP 请求的超时设置为 15 秒,可以使用路由规则来覆盖这个限制
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
timeout: 10s
...
还可以用路由规则来指定某些 http 请求的重试次数。下面的代码可以用来设置最大重试次数,或者在规定时间内一直重试,时间长度同样可以进行覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- route:
- destination:
host: ratings
subset: v1
retries:
attempts: 3
perTryTimeout: 2s
...
- 错误注入
在根据路由规则向选中目标转发 http 请求的时候,可以向其中注入一或多个错误。错误可以是延迟,也可以是退出。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault:
delay:
percent: 10
fixedDelay: 5s
route:
- destination:
host: ratings
subset: v1
...
可以使用其他类型的故障,终止、提前终止请求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: ratings
spec:
hosts:
- ratings
http:
- fault:
abort:
percent: 10
httpStatus: 400
route:
- destination:
host: ratings
subset: v1
...
- 条件规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: reviews
spec:
hosts:
- reviews
http:
- match:
- headers:
end-user:
exact: jason
...
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: productpage
spec:
hosts:
- productpage
http:
- match:
- uri:
prefix: /api/v1
...
DestinationRule使用介绍
在请求被 VirtualService 路由之后,DestinationRule 配置的一系列策略就生效了。这些策略由服务属主编写,包含断路器、负载均衡以及 TLS 等的配置内容。
DestinationRule 还定义了对应目标主机的可路由 subset,VirtualService 在向特定服务版本发送请求时会用到这些子集。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
trafficPolicy:
loadBalancer:
simple: RANDOM
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
trafficPolicy:
loadBalancer:
simple: ROUND_ROBIN
- name: v3
labels:
version: v3
- 断路器
可以用一系列的标准,例如连接数和请求数限制来定义简单的断路器。例如下面的 DestinationRule 给 reviews 服务的 v1 版本设置了 100 连接的限制:
```yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: reviews
spec:
host: reviews
subsets:
- name: v1 labels: version: v1 trafficPolicy: connectionPool: tcp: maxConnections: 100 ```
Service Entry使用介绍
Istio 内部会维护一个服务注册表,可以用 ServiceEntry 向其中加入额外的条目。通常这个对象用来启用对 Istio 服务网格之外的服务发出请求。例如下面的 ServiceEntry 可以用来允许外部对 *.foo.com 域名上的服务主机的调用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: foo-ext-svc
spec:
hosts:
- "*.foo.com"
ports:
- number: 80
name: http
protocol: HTTP
- number: 443
name: https
protocol: HTTPS
Gateway
Gateway 为 HTTP/TCP 流量配置了一个负载均衡,多数情况下在网格边缘进行操作,用于启用一个服务的入口(ingress)流量。
和 Kubernetes Ingress 不同,Istio Gateway 只配置四层到六层的功能(例如开放端口或者 TLS 配置)。绑定一个 VirtualService 到 Gateway 上,用户就可以使用标准的 Istio 规则来控制进入的 HTTP 和 TCP 流量。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: bookinfo-gateway
spec:
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- bookinfo.com
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
...
要为 Gateway 配置对应的路由,必须为定义一个同样 hosts 定义的 VirtualService,其中用 gateways 字段来绑定到定义好的 Gateway 上:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo
spec:
hosts:
- bookinfo.com
gateways:
- bookinfo-gateway # <---- 绑定到 Gateway
http:
- match:
- uri:
prefix: /reviews
route:
...