ServiceEntry
ServiceEntry
允许向 Istio 的内部服务注册表中添加额外的条目,以便网格中的自动发现服务可以访问或路由到这些手动指定的服务。ServiceEntry
描述了服务的属性(DNS名称,VIP,端口,协议,endpoints
)。这些服务可以是网格外部的(如 Web APIs),也可以是不属于平台服务注册表的网格内部服务(如 一组在 Kubernetes 中与服务通信的 VM)。
下面的示例中,声明了一些内部应用程序通过 HTTPS 访问的外部 API。sidecar
检查 ClientHello
消息中的 SNI 值,以路由到关联的的外部服务。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-https
spec:
hosts:
- api.dropboxapi.com
- www.googleapis.com
- api.facebook.com
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: TLS
resolution: DNS
下面的示例中,将一组在非托管 VM 上运行的 MongoDB 实例添加到 Istio 的注册表中,这些服务就可以被视为网格中的任何其他服务。关联的 DestinationRule
用于初始化到数据库实例的 mTLS 连接。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-mongocluster
spec:
hosts:
- mymongodb.somedomain # not used
addresses:
- 192.192.192.192/24 # VIPs
ports:
- number: 27018
name: mongodb
protocol: MONGO
location: MESH_INTERNAL
resolution: STATIC
endpoints:
- address: 2.2.2.2
- address: 3.3.3.3
关联的 DestinationRule
如下:
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: mtls-mongocluster
spec:
host: mymongodb.somedomain
trafficPolicy:
tls:
mode: MUTUAL
clientCertificate: /etc/certs/myclientcert.pem
privateKey: /etc/certs/client_private_key.pem
caCertificates: /etc/certs/rootcacerts.pem
下面的示例中,在 VirtualService
中使用 ServiceEntry
和 TLS 路由的组合,根据 SNI 值将流量引导到内部 Egress 防火墙。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-redirect
spec:
hosts:
- wikipedia.org
- "*.wikipedia.org"
location: MESH_EXTERNAL
ports:
- number: 443
name: https
protocol: TLS
resolution: NONE
根据 SNI 值路由的关联 VirtualService
:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: tls-routing
spec:
hosts:
- wikipedia.org
- "*.wikipedia.org"
tls:
- match:
- sniHosts:
- wikipedia.org
- "*.wikipedia.org"
route:
- destination:
host: internal-egress-firewall.ns1.svc.cluster.local
带有 TLS 匹配的 VirtualService
将覆盖默认的 SNI 匹配。在没有 VirtualService
的情况下,流量将被转发到 wikipedia.org
。
下面的示例中,演示了出口网关的使用,通过 Gateway
可以转发所有外部服务的流量。exportTo
字段用于控制服务声明对网格中其他命名空间的可见性。默认情况下,服务会暴露到所有命名空间。.
表示将可见性限制为当前的命名空间,这样其他命名空间就无法使用它。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-httpbin
namespace: egress
spec:
hosts:
- httpbin.com
exportTo:
- "."
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
定义一个 Gateway
来处理所有出口流量:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: istio-egressgateway
namespace: istio-system
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
下面是 关联的 VirtualService
,从 Sidecar
到网关服务(istio-egressgateway.istio-system.svc.cluster.local
)的路由,以及从网关到外部服务的路由。注意,VirtualService
已暴露到所有命名空间,从而使它们能够将流量通过网关路由到外部服务。强制流量通过这样的托管中间代理比较常见。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: gateway-routing
namespace: egress
spec:
hosts:
- httpbin.com
exportTo:
- "*"
gateways:
- mesh
- istio-egressgateway
http:
- match:
- port: 80
gateways:
- mesh
route:
- destination:
host: istio-egressgateway.istio-system.svc.cluster.local
- match:
- port: 80
gateways:
- istio-egressgateway
route:
- destination:
host: httpbin.com
下面的示例中,演示了在外部服务的主机中使用通配符。如果必须将连接路由到应用程序请求的 IP 地址(即应用程序解析 DNS 并尝试连接到特定的 IP 地址),则发现模式必须设置为 NONE
。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-wildcard-example
spec:
hosts:
- "*.bar.com"
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: NONE
下面的示例中,演示了通过客户端主机上的 Unix Domain Socket
可使用的服务。必须将 resolution
设置为 STATIC
才能使用 Unix 地址的 endpoints
。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: unix-domain-socket-example
spec:
hosts:
- "example.unix.local"
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: STATIC
endpoints:
- address: unix:///var/run/example/socket
对于基于 HTTP 的服务,可以创建一个由多个 DNS 可寻址 endpoints
支持的 VirtualService
。在这种情况下,应用程序可以使用 HTTP_PROXY
环境变量透明地将 VirtualService
的 API 调用重新路由到选定的后端。
下面的示例中,创建了一个不存在的外部服务,名为 foo.bar.com
,该服务由三个域支持:us.foo.bar.com:8080, uk.foo.bar.com:9080, in.foo.bar.com:7080
。
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: external-svc-dns
spec:
hosts:
- foo.bar.com
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
endpoints:
- address: us.foo.bar.com
ports:
https: 8080
- address: uk.foo.bar.com
ports:
https: 9080
- address: in.foo.bar.com
ports:
https: 7080
使用 HTTP_PROXY=http://localhost/
,应用程序对 http://foo.bar.com
的调用将在上面指定的三个域之间实现负载均衡。换句话说,对 http://foo.bar.com/baz
的调用将转换为 http://uk.foo.bar.com/baz
。
下面的示例中,说明了 ServiceEntry
包含主题备用名称的用法,其格式符合 SPIFFE 标准:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin
namespace : httpbin-ns
spec:
hosts:
- httpbin.com
location: MESH_INTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: STATIC
endpoints:
- address: 2.2.2.2
- address: 3.3.3.3
subjectAltNames:
- "spiffe://cluster.local/ns/httpbin-ns/sa/httpbin-service-account"
ServiceEntry
ServiceEntry
允许向 Istio 的内部服务注册表中添加额外的条目。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
hosts |
string[] |
与 ServiceEntry 关联的主机,可以是带有通配符前缀的 DNS 名称。hosts 字段用于在 VirtualServices 和 DestinationRules 中选择匹配的主机。对于 HTTP 流量,HTTP Host/Authority header 将与 hosts 字段匹配。对于包含 Server Name Indication(SNI)的 HTTP 或 TLS 流量,SNI 值将根据 hosts 字段进行匹配。注意,如果将 resolution 设置为 DNS 类型且没有指定 endpoints 时,hosts 字段将被用作将流量路由到的 endpoints 的 DNS 名称 |
是 |
addresses |
string[] |
与服务关联的虚拟 IP 地址。可以是 CIDR 前缀。对于 HTTP 流量,生成的路由配置将包括 addresses 和 hosts 字段值的 HTTP 路由域,目标将基于 HTTP Host/Authority header 进行标识。如果指定了一个或多个 IP 地址,且目标 IP 与 addresses 字段中指定的 IP/CIDRs 匹配,则传入的流量将被标识为属于该服务。如果 addresses 字段为空,则流量仅根据目标端口识别。在这种情况下,服务被访问的端口不能被网格中的任何其他服务共享。换句话说,Sidecar 将充当简单的TCP代理,将指定端口上的传入流量转发到指定的目标 endpoint IP/host 。该字段不支持 Unix Domain Socket 地址 |
否 |
ports |
Port[] |
与外部服务关联的端口。如果 endpoints 是 Unix Domain Socket 地址,则必须恰好有一个端口 |
是 |
location |
Location |
指定服务是否应该视为网格的外部还是网格的一部分 | 否 |
resolution |
Resolution |
主机的服务发现模式。对于没有附带 IP 地址的 TCP 端口,将 resolution 模式设置为 NONE 时必须小心,在这种情况下,到该端口上任何 IP 的流量(即 0.0.0.0: ) 都将被允许 |
是 |
endpoints |
Resolution |
与服务关联的一个或多个 endpoints
|
否 |
exportTo |
string[] |
此服务暴露到的命名空间列表。暴露服务可以让它被其他命名空间中定义的 Sidecars ,Gateways 和 VirtualServices 使用。此功能可以用于控制跨命名空间边界的服务的可见性,如果未指定命名空间,则默认情况下会将服务暴露到所有命名空间。. 作为保留值,表示暴露到声明服务的同一命名空间;类似的,* 作为保留值,表示暴露到所有命名空间。对于 Kubernetes 服务,可以通过将注释 networking.istio.io/exportTo 设置为以 , 分隔的命名空间名称列表来实现相同的效果。注意:在当前版本中,exportTo 的值限制为 . 或 * (即当前命名空间或所有命名空间) |
否 |
subjectAltNames |
string[] |
实现此服务的工作负载实例允许使用的主题备用名称列表。此信息用于强制启用 安全命名。如果指定,则代理将会验证服务器证书的主题备用名称是否与指定值之一匹配 | 否 |
ServiceEntry.Endpoint
Endpoint
定义了与网格服务相关联的网络地址(IP 或主机名)。
字段 | 类型 | 描述 | 是否必需 |
---|---|---|---|
address |
string |
与没有端口的网络 endpoint 相关联的地址。当且仅当 resolution 设置为 DNS 时,可以使用域名,域名必须是完全限定的,不能使用通配符。Unix Domain Socket endpoints 格式为 unix:///absolute/path/to/socket
|
是 |
ports |
map<string, uint32> |
与 endpoint 相关联的端口集合。端口必须与声明为服务一部分的端口名称相关联,不能使用 unix:// 地址 |
否 |
labels |
map<string, string> |
与 endpoint 相关联的标签 |
否 |
network |
string |
network 使 Istio 能够将驻留在同一 L3 域/网络 中的 endpoints 分组。假定同一网络中的所有 endpoints 彼此之间都是直接可达的,当不同网络中的 endpoints 不能直接到达对方时,可以使用 Istio Gateway 建立连接(通常使用网关服务器中的 AUTO_PASSTHROUGH 模式)。通常用于跨多个集群跨 Istio 网格 |
否 |
locality |
string |
与 endpoint 关联的位置。locality 对应于故障域(如 国家/地区/区域)。可以通过用 / 分隔每个封装故障域来表示任意故障域层次结构。例如,数据中心机架 r11 中可用性区域 az-1 中 US-East-1 区域中 US 端点的位置可以表示为 us/us-east-1/az-1/r11 。Istio 将配置 Sidecar 以路由到与 Sidecar 位于相同位置的 endpoint 。如果本地中没有 endpoint 可用,则将选择 endpoint 父级本地(但在同一网络 ID 内)。例如,如果在同一网络中有两个 endpoint (网络 ID 为 n1),则将 e1 的位置设置为 us/us-east-1/az-1/r11 ,将 e2 的位置设置为 us/us-east-1/az-2/r12 ,来自 us/us-east-1/az-1/r11 位置的 Sidecar 将首选来自相同位置的 e1 而不是来自不同位置的 e2。endpoint e2 可以是与网关(桥接网络 n1 和 n2)关联的 IP,也可以是与标准服务 endpoint 关联的 IP |
否 |
weight |
uint32 |
与端点关联的负载平衡权重。权重较高的端点将按比例接收较高的流量 | 否 |
ServiceEntry.Location
Location
指定服务是网格的一部分还是在网格之外。Location
决定了几种功能的行为,如服务到服务的 mTLS 身份验证,策略实施等。与网格外部的服务进行通信时,Istio 的 mTLS 身份验证被禁用,并且策略实施在客户端执行,而不是在服务器端执行。
名称 | 描述 |
---|---|
MESH_EXTERNAL |
表示服务在网格的外部。通常用于指示通过 API 使用的外部服务 |
MESH_INTERNAL |
表示服务是网格的一部分。通常用于指示在扩展服务网格以包括非托管基础架构的一部分而显式添加的服务(如 VM 添加到基于 Kubernetes 的服务网格中) |
ServiceEntry.Resolution
Resolution
确定代理如何解析与服务关联的网络 endpoints
的 IP地址,以便它可以路由到其中一个 endpoint
。这里指定的解析模式对应用程序解析与服务关联的 IP 地址的方式没有影响。应用程序可能仍需要使用 DNS 将服务解析为 IP,以便代理可以捕获出站流量。另外,对于 HTTP 服务,应用程序可以直接与代理进行通信(如 通过设置 HTTP_PROXY
)来与这些服务进行通信。
名称 | 描述 |
---|---|
NONE |
假定传入连接已经解析(到特定的目标 IP 地址)。这种连接通常通过代理使用 IP表 REDIRECT/eBPF 等机制进行路由。在执行任何与路由相关的转换之后,代理将把连接转发到该连接绑定到的 IP 地址 |
STATIC |
使用在 endpoints 中指定的静态 IP 地址作为与服务关联的后备实例 |
DNS |
在处理请求时,尝试通过查询环境 DNS 来解析 IP 地址。如果未指定 endpoints ,则代理将解析在 hosts 字段中指定的 DNS 地址(如果未使用通配符)。如果指定了 endpoints ,则将解析 endpoints 中指定的 DNS 地址,以确定目标 IP 地址。DNS 解析不能与 Unix Domain Socket endpoints 一起使用 |