Service Entry允许在Istio的内部服务注册表中添加额外的服务记录,以便网格中自动发现的服务可以访问或路由到这些手动指定的服务。Service Entry描述服务的属性,例如DNS名称、VIPs、端口、协议、端点等。这些服务是网格外部(例如Web API)或者不属于集群服务注册表的网格内部服务。通过使用workloadSelector字段,您还可以动态选择Service Entry的端点。这些端点可以是使用WorkloadEntry对象声明的工作负载或Kubernetes Pod。本文介绍Service Entry的配置示例和字段说明。
配置示例
示例一:内部应用程序通过HTTPS访问外部API
以下示例声明内部应用程序通过HTTPS访问一些外部API。Sidecar检查ClientHello消息中的SNI值以路由到适当的外部服务。
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
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
示例二:在虚拟服务中结合使用服务条目和TLS路由
以下示例展示如何在虚拟服务中结合使用服务条目和TLS路由,根据SNI值将流量路由至内部出口防火墙。
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
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
展开查看VirtualService YAML
apiVersion: networking.istio.io/v1beta1
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
示例三:通过专用出口网关转发所有外部服务流量
以下示例展示如何通过专用出口网关转发所有外部服务流量。exportTo
字段允许控制ServiceEntry对网格中其他命名空间的可见性。默认情况下,服务将导出到所有命名空间。以下示例将可见性限制为当前命名空间(表示为.
),使其不能被其他命名空间使用。
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: external-svc-httpbin
namespace : egress
spec:
hosts:
- example.com
exportTo:
- "."
location: MESH_EXTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
展开查看Gateway YAML
Gateway定义一个网关来处理所有出口流量。
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: istio-egressgateway
namespace: istio-system
spec:
selector:
istio: egressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
展开查看VirtualService YAML
VirtualService用于将流量从Sidecar路由到网关服务(istio-egressgateway.istio-system.svc.cluster.local
),以及从网关路由到外部服务。虚拟服务导出到所有命名空间,使它们能够通过网关将流量路由到外部服务。强制发往外部服务的流量通过此类托管中间代理是一种常见的做法,便于对流量进行控制。
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: gateway-routing
namespace: egress
spec:
hosts:
- example.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: example.com
示例四:在外部服务的主机中使用通配符
以下示例展示如何在外部服务的主机中使用通配符。如果连接必须路由到应用程序请求的IP地址(即应用程序解析了DNS并尝试连接到特定IP),必须将解析模式设置为NONE
。
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
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域套接字获得服务
以下示例展示如何通过客户端主机上的Unix域套接字获得服务。如果需要使用Unix地址端点,必须将resolution
设置为STATIC
。
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
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可寻址端点支持的VirtualService
对于基于HTTP的服务,可以创建一个由多个DNS可寻址端点支持的VirtualService。在这种情况下,应用程序可以使用HTTP_PROXY环境变量将VirtualService的API调用透明地重新路由到选择的后端。例如,以下配置创建了一个不存在的名为foo.bar.com
的外部服务,支持us.foo.bar.com:8080
、uk.foo.bar.com:9080
和in.foo.bar.com:7080
三个域名。当HTTP_PROXY=http://localhost/
时,应用程序对http://foo.bar.com
的调用将在上述三个域名中进行负载均衡,即对http://foo.bar.com/baz
的调用可能被转换为http://uk.foo.bar.com/baz
。
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
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:
http: 8080
- address: uk.foo.bar.com
ports:
http: 9080
- address: in.foo.bar.com
ports:
http: 7080
示例七:符合SPIFFE标准的服务主体备用名称(subjectAltName)的ServiceEntry
展开查看ServiceEntry YAML
apiVersion: networking.istio.io/v1beta1
kind: ServiceEntry
metadata:
name: httpbin
namespace : httpbin-ns
spec:
hosts:
- example.com
location: MESH_INTERNAL
ports:
- number: 80
name: http
protocol: HTTP
resolution: STATIC
endpoints:
- address: 2.2.X.X
- address: 3.3.X.X
subjectAltNames:
- "spiffe://cluster.local/ns/httpbin-ns/sa/httpbin-service-account"
字段说明
ServiceEntry
ServiceEntry能够将额外的服务记录添加到服务网格内部的服务注册表中。
字段
| 类型
| 是否必选 | 说明
|
hosts
| string[]
| 是
| 关联到ServiceEntry的主机。支持带有通配符前缀的DNS名称。
hosts字段用于在VirtualServices和DestinationRules中选择匹配的主机。 对于HTTP流量,HTTP Host和Authority Header将与hosts字段匹配。 对于包含服务器名称指示(SNI)的HTTPS或TLS流量,SNI值将与hosts字段匹配。
该字段的注意事项如下: 当解析设置为DNS类型且未指定端点时,hosts字段将用作要将流量路由到的端点的DNS名称。 如果主机名与另一个服务注册中心(例如Kubernetes)的服务名称匹配,并且该服务注册中心还提供了自己的一组端点,则ServiceEntry将被视为现有Kubernetes服务的补充。如果ServiceEntry提供了可以被添加到Kubernetes服务中的附加属性,则该属性将被添加。目前,仅支持添加subjectAltNames(简称SAN)。该属性表示除了验证与服务相关联的Pod的ServiceAccount的SAN之外,还将验证在此处指定的SAN。
|
addresses
| string[]
| 否
| 与服务关联的虚拟IP地址或CIDR前缀。此字段不支持Unix域套接字地址。对于HTTP流量,生成的路由配置将包括addresses和hosts字段值的HTTP路由域,并根据HTTP Host和Authority Header标识目的地。 |
ports
| ServicePort[] | 是
| 与ServiceEntry关联的端口。如果endpoints是Unix域套接字地址,则只允许配置一个端口。 |
location
| Location | 否
| 指定服务是否被视为网格外部的服务或网格内的一部分。
|
resolution
| Resolution | 是
| 主机的服务解析模式。当将解析模式设置为NONE时,对于没有附带IP地址的TCP端口,将允许对该端口上的任何IP的流量(即0.0.0.0:<端口>)。
|
endpoints
| WorkloadEntry[] | 否
| 与服务关联的一个或多个端点。仅支持指定endpoints或workloadSelector两者之一。
|
workloadSelector
| WorkloadSelector | 否
| 仅适用于MESH_INTERNAL服务。仅支持指定endpoints或workloadSelector两者之一。根据其标签选择一个或多个Kubernetes Pod。
|
exportTo
| string[]
| 否
| 此服务导出到的命名空间列表。导出一个服务可以使其被其他命名空间中定义的Sidecar、网关和虚拟服务使用。此特性提供了一种机制,使服务所有者和网格管理员能够控制跨命名空间边界的服务可见性。
对于Kubernetes Service,您可以通过将注释networking.istio.io/exportTo 设置为英文半角逗号(,)分隔的命名空间名称列表来实现相同的效果。
|
subjectAltNames
| string[]
| 否
| 如果指定,则代理将验证服务器证书的服务主体备用名称是否与指定值之一匹配。
|
ServicePort
ServicePort描述服务的特定端口的属性。
字段
| 类型
| 是否必选
| 说明
|
number
| uint32
| 是
| 一个有效的非负整数端口号。
|
protocol
| string
| 是
| 在端口上暴露的协议,取值为HTTP、HTTPS、GRPC、HTTP2、MONGO、TCP或TLS。 TLS表示连接将会基于SNI Header路由到目标,而不会终止TLS连接。
|
name
| string
| 是
| 分配给端口的标签。
|
targetPort
| uint32
| 否
| 将接收流量的端点上的端口号。如果未设置,默认为number。 |
ServiceEntry.Location
Location指定服务属于服务网格内部或外部。对于集群内部或外部的服务,服务网格的功能也有所区别,例如服务之间的mTLS身份验证、策略执行等。与网格外的服务通信时,Istio的mTLS身份验证被禁用,并且策略执行在客户端侧执行而不是服务器侧。
字段
| 说明 |
MESH_EXTERNAL
| 表示该服务在网格外部。通常用于指示通过API使用的外部服务。
|
MESH_INTERNAL
| 表示该服务是网格的一部分。通过用于指示该服务是添加到网格中但不属于Kubernetes提供的服务。 |
ServiceEntry.Resolution
Resolution决定代理将如何解析与该服务关联的网络端点的IP地址,以便将请求路由到其中之一。此处指定的解析模式不会影响应用程序如何解析与服务关联的IP地址。应用程序可能仍然需要使用DNS将服务解析为IP地址,以便出站流量可以被代理捕获。对于HTTP服务,应用程序可以通过直接与代理通信的方式(例如通过设置HTTP_PROXY),与hosts字段定义的服务进行通信。
字段
| 说明 |
NONE
| 假设传入连接已经解析(到特定的目标IP地址)。此类连接通常使用IP Table REDIRECT、eBPF等机制通过代理进行路由。在执行任何与路由相关的转换后,代理会将连接转发到连接绑定到的IP地址。
|
STATIC
| 使用端点中指定的静态IP地址作为与服务关联的后端实例。
|
DNS
| 尝试通过异步查询环境DNS来解析IP地址。DNS解析不能与Unix域套接字端点一起使用。 |
DNS_ROUND_ROBIN
| 尝试通过异步查询环境DNS来解析IP地址。与DNS不同,DNS_ROUND_ROBIN仅在需要发起新连接时使用返回的第一个IP地址,而不依赖于DNS解析的完整结果。即使DNS记录频繁更改,与主机的连接也会保留,从而消除耗尽连接池和连接循环的问题。该方式适用于必须通过DNS访问的大型Web规模服务。如果未使用通配符,代理将解析在hosts字段中指定的DNS地址。DNS解析不能与Unix域套接字端点一起使用。
|