集群外服务(Service Entry)CRD说明

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:8080uk.foo.bar.com:9080in.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流量,生成的路由配置将包括addresseshosts字段值的HTTP路由域,并根据HTTP Host和Authority Header标识目的地。

  • 如果指定一个或多个IP地址,若目标IP与地址字段中指定的IP或CIDR匹配,则传入流量将被识别为属于此服务。

  • 如果地址字段为空,则流量仅基于目标端口进行识别。在这种情况下,访问服务的端口不能与网格中的任何其他服务共享。Sidecar将充当一个简单的TCP代理,将指定端口上的传入流量转发到指定的目标端点IP或主机。

ports

ServicePort[]

与ServiceEntry关联的端口。如果endpoints是Unix域套接字地址,则只允许配置一个端口。

location

Location

指定服务是否被视为网格外部的服务或网格内的一部分。

resolution

Resolution

主机的服务解析模式。当将解析模式设置为NONE时,对于没有附带IP地址的TCP端口,将允许对该端口上的任何IP的流量(即0.0.0.0:<端口>)。

endpoints

WorkloadEntry[]

与服务关联的一个或多个端点。仅支持指定endpointsworkloadSelector两者之一。

workloadSelector

WorkloadSelector

仅适用于MESH_INTERNAL服务。仅支持指定endpointsworkloadSelector两者之一。根据其标签选择一个或多个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域套接字端点一起使用。

  • 如果未指定endpoints,则代理将解析hosts字段中指定的DNS地址(如果未使用通配符)。

  • 如果指定endpoints,将解析endpoints中指定的DNS地址以确定目标IP地址。

DNS_ROUND_ROBIN

尝试通过异步查询环境DNS来解析IP地址。与DNS不同,DNS_ROUND_ROBIN仅在需要发起新连接时使用返回的第一个IP地址,而不依赖于DNS解析的完整结果。即使DNS记录频繁更改,与主机的连接也会保留,从而消除耗尽连接池和连接循环的问题。该方式适用于必须通过DNS访问的大型Web规模服务。如果未使用通配符,代理将解析在hosts字段中指定的DNS地址。DNS解析不能与Unix域套接字端点一起使用。