服务条目

ServiceEntry 允许将额外的条目添加到 Istio 的内部服务注册表中,以便网格中的自动发现服务可以访问/路由到这些手动指定的服务。服务条目描述服务的属性(DNS 名称、VIP、端口、协议、端点)。这些服务可以是外部的(例如,Web API),也可以是网格内部但不在平台服务注册表中的服务(例如,一组与 Kubernetes 中的服务通信的 VM)。此外,服务条目的端点也可以通过使用 workloadSelector 字段动态选择。这些端点可以是使用 WorkloadEntry 对象声明的 VM 工作负载,也可以是 Kubernetes pod。在单个服务下选择 pod 和 VM 的能力允许在不更改与服务关联的现有 DNS 名称的情况下,将服务从 VM 迁移到 Kubernetes。

以下示例声明了内部应用程序通过 HTTPS 访问的几个外部 API。Sidecar 检查 ClientHello 消息中的 SNI 值以路由到相应的外部服务。

apiVersion: networking.istio.io/v1
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/v1
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/v1
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

以下示例使用虚拟服务中的服务条目和 TLS 路由的组合,根据 SNI 值将流量引导到内部出口防火墙。

apiVersion: networking.istio.io/v1
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,根据 SNI 值进行路由。

apiVersion: networking.istio.io/v1
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 匹配的虚拟服务用于覆盖默认的 SNI 匹配。在没有虚拟服务的情况下,流量将转发到维基百科域。

以下示例演示了使用专用出口网关,通过该网关转发所有外部服务流量。'exportTo' 字段允许控制服务声明在网格中其他命名空间的可见性。默认情况下,服务会导出到所有命名空间。以下示例将可见性限制为当前命名空间(由“.”表示),以便其他命名空间无法使用它。

apiVersion: networking.istio.io/v1
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

定义一个网关来处理所有出口流量。

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
 name: istio-egressgateway
 namespace: istio-system
spec:
 selector:
   istio: egressgateway
 servers:
 - port:
     number: 80
     name: http
     protocol: HTTP
   hosts:
   - "*"

以及关联的 VirtualService,用于将流量从边车路由到网关服务 (istio-egressgateway.istio-system.svc.cluster.local),以及从网关路由到外部服务。请注意,虚拟服务会导出到所有命名空间,使它们能够通过网关将流量路由到外部服务。将流量强制通过这样的托管中间代理是一种常见做法。

apiVersion: networking.istio.io/v1
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

apiVersion: networking.istio.io/v1
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 域套接字可用的服务。解析必须设置为 STATIC 以使用 Unix 地址端点。

apiVersion: networking.istio.io/v1
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_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/v1
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

使用 HTTP_PROXY=https://127.0.0.1/,应用程序对 http://foo.bar.com 的调用将在上面指定的三个域之间进行负载均衡。换句话说,对 http://foo.bar.com/baz 的调用将被转换为 http://uk.foo.bar.com/baz

以下示例说明了使用包含主题备用名称的 ServiceEntry,其格式符合 SPIFFE 标准

apiVersion: networking.istio.io/v1
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.2.2
  - address: 3.3.3.3
  subjectAltNames:
  - "spiffe://cluster.local/ns/httpbin-ns/sa/httpbin-service-account"

以下示例演示了使用 ServiceEntryworkloadSelector 来处理服务 details.bookinfo.com 从虚拟机到 Kubernetes 的迁移。该服务有两个基于虚拟机的实例,具有边车,以及由标准部署对象管理的一组 Kubernetes Pod。网格中此服务的使用者将自动在虚拟机和 Kubernetes 之间进行负载均衡。

apiVersion: networking.istio.io/v1
kind: WorkloadEntry
metadata:
  name: details-vm-1
spec:
  serviceAccount: details
  address: 2.2.2.2
  labels:
    app: details
    instance-id: vm1
---
apiVersion: networking.istio.io/v1
kind: WorkloadEntry
metadata:
  name: details-vm-2
spec:
  serviceAccount: details
  address: 3.3.3.3
  labels:
    app: details
    instance-id: vm2

假设还有一个 Kubernetes 部署,其 Pod 标签为 app: details,使用相同的服务帐户 details,以下服务条目声明了跨越虚拟机和 Kubernetes 的服务

apiVersion: networking.istio.io/v1
kind: ServiceEntry
metadata:
  name: details-svc
spec:
  hosts:
  - details.bookinfo.com
  location: MESH_INTERNAL
  ports:
  - number: 80
    name: http
    protocol: HTTP
  resolution: STATIC
  workloadSelector:
    labels:
      app: details

ServiceEntry

ServiceEntry 允许将额外条目添加到 Istio 的内部服务注册表中。

字段类型描述必填
hostsstring[]

与 ServiceEntry 关联的宿主。可以是具有通配符前缀的 DNS 名称。

  1. hosts 字段用于在 VirtualServices 和 DestinationRules 中选择匹配的宿主。
  2. 对于 HTTP 流量,HTTP Host/Authority 标头将与 hosts 字段匹配。
  3. 对于包含服务器名称指示 (SNI) 的 HTTPs 或 TLS 流量,SNI 值将与 hosts 字段匹配。

注意 1:当解析设置为类型 DNS 且未指定任何端点时,host 字段将用作要将流量路由到的端点的 DNS 名称。

注意 2:如果主机名与来自其他服务注册表(例如 Kubernetes)的服务的名称匹配,该注册表也提供自己的端点集,则 ServiceEntry 将被视为现有 Kubernetes 服务的修饰器。如果适用,服务条目中的属性将添加到 Kubernetes 服务中。目前,istiod 仅考虑以下附加属性

  1. subjectAltNames:除了验证与服务 Pod 关联的服务帐户的 SAN 之外,还会验证此处指定的 SAN。
addressesstring[]

与服务关联的虚拟 IP 地址。可以是 CIDR 前缀。对于 HTTP 流量,生成的路由配置将包括 addresseshosts 字段值的 http 路由域,目标将根据 HTTP Host/Authority 标头进行识别。如果指定了一个或多个 IP 地址,则当目标 IP 与 addresses 字段中指定的 IP/CIDR 匹配时,传入流量将被识别为属于此服务。如果 Addresses 字段为空,则流量将仅根据目标端口进行识别。在这种情况下,访问服务的端口不得与网格中的任何其他服务共享。换句话说,边车将充当简单的 TCP 代理,将传入流量从指定端口转发到指定的目的地端点 IP/宿主。此字段不支持 Unix 域套接字地址。

portsServicePort[]

与外部服务关联的端口。如果端点是 Unix 域套接字地址,则必须只有一个端口。

location位置

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

resolution解析

宿主的服务解析模式。在将解析模式设置为 NONE 时,必须小心,尤其是在没有伴随 IP 地址的 TCP 端口的情况下。在这种情况下,将允许对该端口上的任何 IP 进行流量(即 0.0.0.0:<port>)。

endpointsWorkloadEntry[]

与服务关联的一个或多个端点。只能指定 endpointsworkloadSelector 中的一个。

workloadSelectorWorkloadSelector

仅适用于 MESH_INTERNAL 服务。只能指定 endpointsworkloadSelector 中的一个。根据标签选择一个或多个 Kubernetes Pod 或虚拟机工作负载(使用 WorkloadEntry 指定)。表示虚拟机的 WorkloadEntry 对象应在与 ServiceEntry 相同的命名空间中定义。

exportTostring[]

将此服务导出的命名空间列表。导出服务允许它被其他命名空间中定义的边车、网关和虚拟服务使用。此功能为服务所有者和网格管理员提供了跨命名空间边界控制服务可见性的机制。

如果没有指定任何命名空间,则默认情况下服务将导出到所有命名空间。

值“.”是保留的,用于定义对声明服务的同一命名空间的导出。类似地,值“*”是保留的,用于定义对所有命名空间的导出。

对于 Kubernetes 服务,可以通过将注释“networking.istio.io/exportTo”设置为命名空间名称的逗号分隔列表来实现相同的效果。

subjectAltNamesstring[]

如果指定,代理将验证服务器证书的主题备用名称是否与指定的值之一匹配。

注意:当使用带有 workloadSelectors 的 workloadEntry 时,workloadEntry 中指定的服务帐户也将用于推断应验证的附加主题备用名称。

ServicePort

ServicePort 描述服务特定端口的属性。

字段类型描述必填
numberuint32

有效的非负整数端口号。

protocolstring

在端口上公开的协议。必须是 HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS 之一。TLS 意味着连接将根据 SNI 标头路由到目的地,而不会终止 TLS 连接。

namestring

分配给端口的标签。

targetPortuint32

接收流量的端点上的端口号。如果未设置,则默认为 number

ServiceEntryStatus

字段类型描述必填
conditionsIstioCondition[]

ServiceEntry 的当前服务状态。更多信息:https://istio.ac.cn/docs/reference/config/config-status/

validationMessagesAnalysisMessageBase[]

包含 Istio 分析器检测到的任何错误或警告。

observedGenerationint64

已协调条件所指的资源生成。当此值不等于对象的元数据生成时,当前生成的已协调条件计算仍在进行中。有关更多信息,请参阅 https://istio.ac.cn/latest/docs/reference/config/config-status/

addressesServiceEntryAddress[]

分配给此 ServiceEntry 的地址列表。

ServiceEntryAddress

微小的抽象,允许添加主机名(如果相关)

字段类型描述必填
valuestring

Value 是地址(192.168.0.2)

hoststring

Host 是与此地址关联的名称

ServiceEntry.Location

Location 指定服务是 Istio 网格的一部分还是网格外部。Location 决定了几个功能的行为,例如服务到服务的 mTLS 身份验证、策略执行等。在与网格外部的服务通信时,Istio 的 mTLS 身份验证将被禁用,策略执行将在客户端执行,而不是在服务器端执行。

名称描述
MESH_EXTERNAL

表示服务在网格外部。通常用于表示通过 API 使用的外部服务。

MESH_INTERNAL

表示服务是网格的一部分。通常用于表示作为将服务网格扩展为包含非托管基础设施(例如,添加到基于 Kubernetes 的服务网格中的虚拟机)的一部分而明确添加的服务。

ServiceEntry.Resolution

Resolution 确定代理将如何解析与服务关联的网络端点的 IP 地址,以便它可以路由到其中之一。此处指定的解析模式不会影响应用程序如何解析与服务关联的 IP 地址。应用程序可能仍然需要使用 DNS 将服务解析为 IP,以便代理可以捕获出站流量。或者,对于 HTTP 服务,应用程序可以直接与代理通信(例如,通过设置 HTTP_PROXY)来与这些服务进行通信。

名称描述
NONE

假设传入连接已解析(到特定目标 IP 地址)。此类连接通常通过代理使用 IP 表 REDIRECT/eBPF 等机制进行路由。在执行任何与路由相关的转换后,代理将连接转发到绑定连接的 IP 地址。

STATIC

使用端点中指定的静态 IP 地址(见下文)作为与服务关联的后备实例。

DNS

尝试通过异步查询环境 DNS 来解析 IP 地址。如果没有指定端点,代理将解析 hosts 字段中指定的 DNS 地址(如果未使用通配符)。如果指定了端点,将解析端点中指定的 DNS 地址以确定目标 IP 地址。DNS 解析不能与 Unix 域套接字端点一起使用。

DNS_ROUND_ROBIN

尝试通过异步查询环境 DNS 来解析 IP 地址。与 DNS 不同,DNS_ROUND_ROBIN 仅在需要启动新连接时使用返回的第一个 IP 地址,而不依赖于 DNS 解析的完整结果,并且即使 DNS 记录频繁更改,与宿主建立的连接也将被保留,从而避免了连接池的耗尽和连接循环。这最适合必须通过 DNS 访问的大型网络规模服务。代理将解析 hosts 字段中指定的 DNS 地址(如果未使用通配符)。DNS 解析不能与 Unix 域套接字端点一起使用。

这些信息对您有帮助吗?
您对改进有什么建议吗?

感谢您的反馈!