服務條目

ServiceEntry 允許將額外的條目新增到 Istio 的內部服務註冊表中,以便網格中自動探索的服務可以存取/路由到這些手動指定的服務。服務條目描述服務的屬性 (DNS 名稱、VIP、埠、協定、端點)。這些服務可能在網格外部(例如,Web API),或網格內部的服務,但不是平台服務註冊表的一部分(例如,一組 VM 與 Kubernetes 中的服務通訊)。此外,服務條目的端點也可以使用 workloadSelector 欄位動態選取。這些端點可以是使用 WorkloadEntry 物件宣告的 VM 工作負載或 Kubernetes Pod。在單一服務下選取 Pod 和 VM 的能力,允許將服務從 VM 遷移到 Kubernetes,而無需變更與服務關聯的現有 DNS 名稱。

以下範例宣告了一些內部應用程式透過 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

以下組態將一組在非託管虛擬機器上執行的 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

以下範例結合了服務條目 (service entry) 和虛擬服務 (virtual service) 中的 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 比對。在沒有虛擬服務的情況下,流量將會轉發到 wikipedia 網域。

以下範例示範了如何使用專用的出口閘道,所有外部服務流量都會透過該閘道轉發。「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://#/ 時,從應用程式到 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"

以下範例示範如何使用具有 workloadSelectorServiceEntry 來處理將服務 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 允許將其他條目加入 Istio 的內部服務登錄檔中。

欄位類型描述必要
hostsstring[]

與 ServiceEntry 關聯的主機。可以是帶有萬用字元前置詞的 DNS 名稱。

  1. hosts 欄位用於在 VirtualService 和 DestinationRule 中選取符合的主機。
  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 Proxy,將指定連接埠上的傳入流量轉發到指定目的地端點 IP/主機。此欄位中不支援 Unix 網域套接字位址。

portsServicePort[]

與外部服務關聯的連接埠。如果端點是 Unix 網域套接字位址,則必須只有一個連接埠。

locationLocation

指定服務應被視為網格外部還是網格的一部分。

resolutionResolution

主機的服務解析模式。當在沒有隨附 IP 位址的情況下將 TCP 連接埠的解析模式設定為 NONE 時,必須小心。在這種情況下,將允許前往該連接埠上任何 IP 的流量 (例如,0.0.0.0:<port>)。

endpointsWorkloadEntry[]

與服務關聯的一個或多個端點。只能指定 endpointsworkloadSelector 中的一個。

workloadSelectorWorkloadSelector

僅適用於 MESH_INTERNAL 服務。只能指定 endpointsworkloadSelector 中的一個。根據標籤選取一個或多個 Kubernetes Pod 或虛擬機器工作負載 (使用 WorkloadEntry 指定)。代表虛擬機器的 WorkloadEntry 物件應在與 ServiceEntry 相同的命名空間中定義。

exportTostring[]

此服務匯出的命名空間清單。匯出服務允許其他命名空間中定義的邊車、閘道和虛擬服務使用它。此功能提供了一種機制,供服務擁有者和網格管理員控制跨命名空間邊界之服務的能見度。

如果未指定任何命名空間,則預設會將服務匯出到所有命名空間。

值「.」是保留值,定義匯出到宣告服務所在的相同命名空間。同樣地,值「*」是保留值,定義匯出到所有命名空間。

對於 Kubernetes 服務,可以透過將註釋「networking.istio.io/exportTo」設定為以逗號分隔的命名空間名稱清單來達到相同的效果。

subjectAltNamesstring[]

如果指定,Proxy 將會驗證伺服器憑證的主體替代名稱是否與指定的值之一相符。

注意:當將 workloadEntry 與 workloadSelectors 搭配使用時,workloadEntry 中指定的服務帳戶也會用於衍生應驗證的其他主體替代名稱。

服務埠

ServicePort 描述服務特定連接埠的屬性。

欄位類型描述必要
numberuint32

有效的非負整數連接埠號碼。

protocolstring

連接埠上公開的協定。必須是 HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS 之一。TLS 表示連線將會根據 SNI 標頭路由到目的地,而不會終止 TLS 連線。

namestring

指派給連接埠的標籤。

targetPortuint32

端點上接收流量的連接埠號碼。如果未設定,則預設為 number

服務條目狀態

欄位類型描述必要
conditionsIstioCondition[]

ServiceEntry 的目前服務狀態。更多資訊:https://istio.dev.org.tw/docs/reference/config/config-status/

validationMessagesAnalysisMessageBase[]

包含 Istio 分析器偵測到的任何錯誤或警告。

observedGenerationint64

協調條件所指的資源產生。當此值與物件的中繼資料產生不相等時,目前產生的協調條件計算仍在進行中。請參閱 https://istio.dev.org.tw/latest/docs/reference/config/config-status/ 以取得更多資訊。

addressesServiceEntryAddress[]

已指派給此 ServiceEntry 的位址清單。

服務條目位址

較小的抽象概念,允許在相關時新增主機名稱

欄位類型描述必要
valuestring

值是位址 (192.168.0.2)

hoststring

主機是與此位址關聯的名稱

ServiceEntry.Location

位置指定服務是 Istio 網格的一部分還是位於網格外部。位置決定了多種功能的行為,例如服務對服務的 mTLS 驗證、原則強制執行等。當與網格外部的服務通訊時,Istio 的 mTLS 驗證會停用,並且原則強制執行是在用戶端執行,而不是在伺服器端執行。

名稱描述
MESH_EXTERNAL

表示服務位於網格外部。通常用於表示透過 API 取用的外部服務。

MESH_INTERNAL

表示服務是網格的一部分。通常用於表示明確加入,作為將服務網格擴展到包含非託管基礎結構的一部分的服務 (例如,新增至基於 Kubernetes 的服務網格的虛擬機器)。

ServiceEntry.Resolution

解析方式決定了代理伺服器如何解析與服務相關聯的網路端點的 IP 位址,以便將流量路由到其中一個端點。此處指定的解析模式不會影響應用程式如何解析與服務相關聯的 IP 位址。應用程式可能仍然需要使用 DNS 將服務解析為 IP,以便代理伺服器可以捕獲出站流量。或者,對於 HTTP 服務,應用程式可以直接與代理伺服器通訊(例如,通過設定 HTTP_PROXY)來與這些服務對話。

名稱描述

假設傳入的連線已經被解析(到特定的目標 IP 位址)。此類連線通常使用諸如 IP 表 REDIRECT/ eBPF 等機制通過代理伺服器路由。在執行任何與路由相關的轉換後,代理伺服器會將連線轉發到連線綁定的 IP 位址。

靜態

使用端點中指定的靜態 IP 位址(見下文)作為與服務關聯的後端實例。

DNS

嘗試通過非同步查詢環境 DNS 來解析 IP 位址。如果未指定端點,代理伺服器將解析主機欄位中指定的 DNS 位址(如果未使用萬用字元)。如果指定了端點,則將解析端點中指定的 DNS 位址以確定目標 IP 位址。DNS 解析不能與 Unix 域套接字端點一起使用。

DNS_輪循

嘗試通過非同步查詢環境 DNS 來解析 IP 位址。與 DNS 不同,DNS_輪循 僅使用在需要啟動新連線時返回的第一個 IP 位址,而無需依賴 DNS 解析的完整結果,並且即使 DNS 記錄頻繁更改,與主機建立的連線也會保留,從而消除了排空連線池和連線循環。這最適合必須通過 DNS 訪問的大型網路級服務。如果未使用萬用字元,代理伺服器將解析主機欄位中指定的 DNS 位址。DNS 解析不能與 Unix 域套接字端點一起使用。

這項資訊是否有用?
您有任何改進建議嗎?

感謝您的回饋!