一、前言¶
ServiceEntry:
- 将外部服务添加到服务网格:例如,你的应用程序需要访问位于服务网格之外的第 三方 API 或数据库。你可以使用 ServiceEntry 将这些外部服务添加到 Istio 的服务注册表中,并通过流量路由规则将请求转发到这些服务。
Sidecar:
- 流量管理:使用 Sidecar 来管理流量路由策略,例如按版本或权重进行流量分流, 实现灰度发布或 A/B 测试。
- 故障恢复:Sidecar 可以帮助实现故障恢复机制,例如超时重试、熔断和健康检查等,以提高应用程序的可靠性。
- 安全性增强:通过 Sidecar 实现服务间的安全通信,例如使用 TLS 加密保护数据传输,实施服务身份验证和授权等。
Envoy Filter:
- 请求/响应转换:使用 Envoy Filter 修改传入请求或传出响应的内容,例如添加、删 除或修改请求头、响应头、负载等。
- 流量控制:通过 Envoy Filter 实现自定义的流量控制策略,例如基于请求速率限制 或配额管理来保护服务免受滥用。
- 身份认证和授权:使用 Envoy Filter 扩展身份验证和授权机制,例如添加 JWT 验证、OAuth2 鉴权等。
小结:
通过 ServiceEntry,咱们可以将外部服务添加到 Istio 的服务注册表中,并将流量路由到 这些服务。
Sidecar 代理在每个 Pod 中协助管理流量,并与其他服务进行通信。
使用 Envoy Filter 可以定制 Sidecar 中的 Envoy 配置,以满足特定的需求。
二、ServiceEntry¶
2.1 ServiceEntry¶
ServiceEntry :将网格外的服务注册到 Istio 的服务网格中。 小伙伴可能会有个疑问,咱们pod中本来就可以访问这些外部的服务,为什么要加到istio 的网格呢?
我来说个比较常用的场景:使用 ServiceEntry,咱们可以为外部服务定义流量管理规则,例如。设置超时时间、重试策略、负载均衡、身份验证策略等。还可以使用 ServiceEntry 实现基于来源或目标的策略控制,例如限制对特定服务的访问权限或启用出站流量审计。
默认咱们对外网的一些域名做不了任何措施,那么通过 ServiceEntry 是不是就可以基 于这部分的业务场景做一些个性化的配置了吧!
在 ServiceEntry 中可以配置 hosts, vips, ports, protocols, endpoints 等。
- hosts: hosts 字段用于指定与 ServiceEntry 关联的主机名,即服务的逻辑名称。 可以使用通配符 * 以匹配多个主机名。这样,在网格内访问这些主机名时,Istio 将根据 ServiceEntry 中定义的规则来路由流量。
- vips: vips 字段用于指定虚拟 IP 地址。虚拟 IP 是对服务的逻辑名称进行解析后 的 IP 地址。通过将服务的逻辑名称绑定到虚拟 IP,Istio 可以将流量路由到 ServiceEntry 中定义的服务。
- ports: ports 字段用于指定外部服务监听的端口号。可以为每个端口指定名称和协议(如 TCP、UDP)。在定义端口时,还可以指定目标环境(如 Kubernetes), 以便 Istio 根据环境来理解端口的语义。
- protocols: protocols 字段用于指定与 ServiceEntry 关联的协议。可以设置协 议列表,例如HTTP、HTTPS、gRPC等。这将告诉 Istio 如何处理与 ServiceEntry 关联的流量,并应用相应的流量管理和安全策略。
- endpoints: endpoints 字段用于指定 ServiceEntry 关联的终端点列表。终端点 可以是具体的IP地址或主机名。通过提供这些终端点信息,Istio 将能够将流量正确 路由到 ServiceEntry 定义的目标。

假设你需要将一个外部的 RESTful API(例如 api.dropboxapi.com|www.googleapis.com|api.facebook.com)添加到服务网格中,并将流量路由到该 API:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc
spec:
hosts:
- api.dropboxapi.com
- www.googleapis.com
- api.facebook.com
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS
location: MESH_EXTERNAL
该示例中,定义了在网格内部使用 HTTPS 协议访问外部的几个服务的配置。
通过上面配置,网格内部的服务就可以把这几个外部的服务当做网格内部服务去访问。
hosts:字段可以包含多个外部 API,在这种情况下,Envoy sidecar 会根据下面的层次结构来进行检查。
MESH_EXTERNAL:表示是网格外服务,该参数会影响到服务间调用的 mTLS 认证、策略执行等。
一个特殊的情况,如果上述外部服务有问题,Envoy 会根据 Istio 的配置策略,往目的地重试转发请求或放弃该请求。
2.2 WorkloadEntry¶
WorkloadEntry:WorkloadEntry 用于定义非 Istio 管理的工作负载(如虚拟机、物理 机、其他服务网格)的网络信息。
通过 WorkloadEntry,咱们可以将这些非 Istio 管理的工作负载纳入 Istio 控制,并使 Istio 能够对其进行流量管理和安全控制,主要是使用 ServiceEntry 中的
workloadSelector 字段,使虚拟机成为 Istio 内部服务注册表的一部分。 例如,假设 customers 的工作负载正在两个虚拟机上运行。此外,我们已经有Kubernetes 中运行的 Pod,其标签为 app: customers。
让我们这样来定义 WorkloadEntry 资源:
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadEntry
metadata:
name: customers-vm-1
spec:
serviceAccount: customers
address: 192.168.0.100
endpoints:
- address: 192.168.0.100
---
apiVersion: networking.istio.io/v1alpha3
kind: WorkloadEntry
metadata:
name: customers-vm-2
spec:
address: 192.168.0.200
labels:
app: my-app
serviceAccount: customers
weight: 50
endpoints:
- address: 192.168.0.200
ports:
- number: 8080
name: http
protocol: HTTP
labels:
version: v1
在上述示例中,WorkloadEntry 对象具有以下配置选项:
- address:指定工作负载的 IP 地址为 192.168.0.100。
- labels:添加标签以标识工作负载属于哪个应用程序。这里给出了一个名为 "app" 的标签,其值为 "my-app"。
- serviceAccount:指定工作负载使用的 Service Account 为 "my-service- account"。
- weight:设置权重为 50,用于流量分流和负载均衡的目的。
- endpoints:指定工作负载的终端点信息。在这个示例中,终端点的 IP 地址为 192.168.0.100,监听 HTTP 端口 8080。可以指定多个端口及其对应的名称和协议。
- labels(在 endpoints 下):与终端点相关联的标签。在这个示例中,给出了一 个名为"version" 的标签,其值为 "v1"。
现在我们可以创建一个 ServiceEntry 资源,该资源同时跨越 Kubernetes 绑定运行的工作负载和虚拟机:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: customers-svc
spec:
hosts:
- customers.com
location: MESH_INTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: STATIC
workloadSelector:
labels:
app: customers-vm-2
在 location 字段中设置 MESH_INTERNAL ,这是说这个服务是网格的一部分。这个值通常用于包括未管理的基础设施(VM)上的工作负载的情况。
这个字段的另一个值, MESH_EXTERNAL ,用于通过 API 消费的外部服务。
MESH_INTERNAL 和 MESH_EXTERNAL 设置控制了网格中的 sidecar 如何尝试与工作负载进行通信,包括它们是否会默认使用 Istio 双向TLS。
三、Sidecar¶
官方数据:Istio / 安装 Sidecar
3.1 核心配置组成¶
默认情况下,在istio中,注入的 sidecar 代理会接收所有端口的流量,并且在转发流量 时可以到达网格中的任何服务。
在某些情况下,你可能想改变这种配置,配置代理,所以它只能使用特定的端口和访问 某些服务。要做到这一点,你可以在 Istio 中使用 Sidecar 资源。
Sidecar 资源可以被部署到 Kubernetes 集群内的一个或多个命名空间,但如果没有定 义工作负载选择器,每个命名空间只能有一个 sidecar 资源。
Sidecar 资源由三部分组成:一个工作负载选择器、一个入口(ingress)监听器和一个 出口(egress)监听器
3.2 工作负载选择器¶
工作负载选择器决定了哪些工作负载会受到 sidecar 配置的影响。 你可以决定控制一个命名空间中的所有 sidecar,而不考虑工作负载,或者提供一个工作负载选择器,将配置只应用于特定的工作负载。
例如,下面这个 YAML 适用于默认命名空间内的所有代理,该资源配置命名空间中的 sidecars以允许出口流量到 default,istio-system和staging命名空间中的公共服务。
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default-sidecar
namespace: default
spec:
egress:
- hosts:
- "default/*"
- "istio-system/*"
- "staging/*"
在 egress 部分,我们指定代理可以访问运行在default 、 is tio- system 和 staging命名空间的服务 。
要将资源仅应用于特定的工作负载,我们可以使用 workloadSelector 字段。
例如, 将选择器设置为 version: v1 将只适用于有该标签设置的工作负载 。
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: default-sidecar
namespace: default
spec:
workloadSelector:
labels:
version: v1
egress:
- hosts:
- "default/*"
- "istio-system/*"
- "staging/*"
3.3 资源入口(ingress)¶
资源的入口(ingress)监听器部分定义了哪些入站流量被接受。同样地,通过出口 (egress)监听器,你可以定义出站流量的属性。
每个入口监听器都需要一个端口设置,以便接收流量(例如,下面的例子中的 3000)和 一个默认的端点。默认端点 可以是一个回环 IP 端点或 Unix 域套接字。端点配置了流量将被转发到哪里。
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: ingress-sidecar
spec:
egress:
- hosts:
- external-service.com
http:
- timeout: 5s
retries:
attempts: 3
perTryTimeout: 2s
ingress:
- port:
number: 80
name: http
protocol: HTTP
defaultEndpoint: my-ingress-gateway
routes:
- match:
- uri:
prefix: /api
destination:
host: my-service
port:
number: 8080
解释:上述配置定义了一个名为 "ingress-sidecar" 的 Sidecar 容器,用于处理入站流 量。该 Sidecar 配置参数主要有如下几点:
- 定义了对外部服务 external-service.com 的出站规则,设置了超时时间为 5 秒,并 对请求进行了三次重试,每次重试的超时时间为 2 秒。
- 配置了入站规则,将端口号为 80 的 HTTP 流量,路由到名为 "my-ingress- gateway" 的 Gateway。
- 并使用路由规则将以 /api 作为前缀的请求转发到主机为 "my-service",端口号为 8080 的服务。
3.4 资源出口(egress)¶
apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
name: my-sidecar
spec:
workloadSelector:
labels:
app: my-app
outboundTrafficPolicy:
mode: ALLOW_ANY
egress:
- hosts:
- example.com
http:
- match:
- uri:
prefix: /api
headers:
x-version:
exact: v2
route:
- destination:
host: my-service-v2
weight: 80
- destination:
host: my-service-v1
weight: 20
解释:上述配置定义了一个 Sidecar 容器,将流量从标有 "app: my-app" 标签的工作负载路由到外部主机 example.com 的 /api 路径上。根据请求中的标头 x-version 的值,设置不同版本的服务实例的权重,比例为80:20。
3.5 总结¶

解释:
- 客户端(Client)发送的流量经过 Ingress Gateway,由 Ingress Sidecar处理。
- Ingress Sidecar 根据配置规则,对入站流量进行处理和转发。
- 外部服务(External Service)是Ingress Sidecar配置中定义的出站规则的目标。
- Ingress Sidecar将请求转发给后端服务(my-service),并将响应返回给客户端。
这个工作图简化地展示了 Ingress Sidecar 的工作流程。实际场景中,可能会存在更多的 服务和网络组件,以及更复杂的路由和策略配置。通过 Ingress Sidecar 的规则,可以实现对入站流量的控制和管理,确保流量的安全性、可靠性和高效性。
四、Envoy Filter¶
4.1 功能介绍¶
Istio 的 Envoy Filter 是一个强大的工具,它能够在服务网格中以灵活而精细的方式控制 和修改流量。它提供了自定义策略和功能增强的能力,以及对流量的监控和跟踪。通过使用 Envoy Filter,可以更好地管理和保护您的微服务架构,并满足特定的业务需求。
官方数据:Istio / Envoy Filter

EnvoyFilter 资源允许你定制由 Istio Pilot 生成的 Envoy 配置。使用该资源,咱们可以更 新数值,添加特定的过滤器,甚至添加新的监听器、集群等等。
大家在一定要小心使用这个功能,因为不正确的定制可能会破坏整个网格的稳定性。
4.2 场景案例¶
EnvoyFilter 过滤器是叠加应用的,这意味着对于特定命名空间中的特定工作负载,可以有任何数量的过滤器。
根命名空间(例如 istio- system)中的过滤器首先被应用,然后是工作负载命名空间中的所有匹配过滤器。
下面是一个 EnvoyFilter 的例子,它在请求中添加了一个名为 api-version 的头。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: api-header-filter
namespace: default
spec:
workloadSelector:
labels:
app: web-frontend
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
portNumber: 8080
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_response(response_handle)
response_handle:headers():add("api-version", "v1")
end
上述示例中,我们创建了一个名为 api-header-filter 的 Envoy Filter 对象,并将其应用于标签为app: web-frontend 的工作负载。
在配置部分,我们使用 applyTo 字段,指定要应用的 Envoy Filter 类型为HTTP_FILTER,并使用 match 字段来选择要应用 Envoy Filter 的条件。 在此示例中,我们选择了Sidecar Inbound 的流量,并匹配到了envoy.http_connection_manager过滤器和envoy.router子过滤器。
接下来,在 patch 字段中,我们使用 operation 字段指定要执行的操作为INSERT_BEFORE,然后定义了一个名为 envoy.lua 的新过滤器,并指定了它的类型为Lua。在 inlineCode 中,我们编写了一个简单的 Lua 脚本,通过该脚本可以在请求进 入时拦截并修改请求的Headers,在示例中添加了自定义的 Header。
...
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_request(request_handle)
-- 在这里可以编写自定义的请求处理逻辑
request_handle:headers():add("X-Custom-Header", "Custom Value")
end
测试验证:
如果你向 $GATEWAY_URL 发送一个请求,你可以注意到 api-version 头被添加了,如下所示:
$ curl -s -I -X HEAD http://$GATEWAY_URL
$ curl -s -I -X HEAD http://10.0.0.12
HTTP/1.1 200 OK
x-powered-by: Express
content-type: text/html; charset=utf-8
content-length: 2471
etag: W/"9a7-hEXE7lJW5CDgD+e2FypGgChcgho"
date: Tue, 17 Jul 2023 00:40:16 GMT
x-envoy-upstream-service-time: 32
api-version: v1
server: istio-envoy
## 7.5 总结
在 Istio 中,ServiceEntry、Sidecar 和 Envoy Filter 是三个重要的概念和组件,它们各 自承担着不同的角色和功能。
1、ServiceEntry(服务入口):
- 功能:ServiceEntry 允许您将外部服务引入到 Istio 的服务网格中,以便使用 Istio 提供的流量管理和策略控制功能。
- 作用:通过定义 ServiceEntry,咱们可以将外部服务的网络地址和端口信息注 册到 Istio 控制平面,使得该服务可以像内部服务一样受益于 Istio 的一系列特 性,如负载均衡、故障恢复、安全认证等。
2、Sidecar(边车代理):
- 功能:Sidecar 是将 Istio 代理(通常是 Envoy)部署到每个微服务实例旁边的 容器。Sidecar 与微服务实例一起运行,并负责处理所有进出该实例的流量。
- 作用:通过 Sidecar,Istio 可以对微服务之间的通信进行透明代理,实现流量 管理、策略控制和监控跟踪等功能。Sidecar 还负责与 Istio 控制平面通信,接 收和处理 Istio 的配置和指令。
3、Envoy Filter(Envoy 过滤器):
- 功能:Envoy Filter 是 Istio 中使用的一个组件,用于在Envoy代理中进行流量控制和修改。
- 作用:Envoy Filter 允许用户根据请求和响应的特定条件对流量进行过滤和控 制。通过自定义 Envoy Filter 的配置,大家可以实现对流量的拦截、修改、增强和监控等操作。Envoy Filter 提供了灵活、精细的流量管理能力,可以满足复 杂的流量控制和处理需求。
综上所述,ServiceEntry 允许将外部服务引入到Istio的服务网格中;Sidecar 是每个微服务实例旁边的代理容器 ,负责处理流量和Istio控制平面通信;Envoy Filter 则允许对流量进行灵活的控制和修改。这些组件共同构成了 Istio 在微服务架构中的核心功能,为服务网格提供了流量管理、安全性、可观察性等特性。