Service Entry允許在Istio的內部服務注冊表中添加額外的服務記錄,以便網格中自動發現的服務可以訪問或路由到這些手動指定的服務。Service Entry描述服務的屬性,例如DNS名稱、VIPs、端口、協議、端點等。這些服務是網格外部(例如Web API)或者不屬于集群服務注冊表的網格內部服務。通過使用workloadSelector字段,您還可以動態選擇Service Entry的端點。這些端點可以是使用WorkloadEntry對象聲明的工作負載或Kubernetes Pod。本文介紹Service Entry的配置示例和字段說明。
配置示例
示例一:內部應用程序通過HTTPS訪問外部API
以下示例聲明內部應用程序通過HTTPS訪問一些外部API。Sidecar檢查ClientHello消息中的SNI值以路由到適當的外部服務。
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值將流量路由至內部出口防火墻。
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
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對網格中其他命名空間的可見性。默認情況下,服務將導出到所有命名空間。以下示例將可見性限制為當前命名空間(表示為.
),使其不能被其他命名空間使用。
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定義一個網關來處理所有出口流量。
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用于將流量從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
。
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
。
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
。
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
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名稱。
該字段的注意事項如下:
|
addresses | string[] | 否 | 與服務關聯的虛擬IP地址或CIDR前綴。此字段不支持Unix域套接字地址。對于HTTP流量,生成的路由配置將包括addresses和hosts字段值的HTTP路由域,并根據HTTP Host和Authority Header標識目的地。
|
ports | 是 | 與ServiceEntry關聯的端口。如果endpoints是Unix域套接字地址,則只允許配置一個端口。 | |
location | 否 | 指定服務是否被視為網格外部的服務或網格內的一部分。 | |
resolution | 是 | 主機的服務解析模式。當將解析模式設置為NONE時,對于沒有附帶IP地址的TCP端口,將允許對該端口上的任何IP的流量(即0.0.0.0:<端口>)。 | |
endpoints | 否 | 與服務關聯的一個或多個端點。僅支持指定endpoints或workloadSelector兩者之一。 | |
workloadSelector | 否 | 僅適用于MESH_INTERNAL服務。僅支持指定endpoints或workloadSelector兩者之一。根據其標簽選擇一個或多個Kubernetes Pod。 | |
exportTo | string[] | 否 | 此服務導出到的命名空間列表。導出一個服務可以使其被其他命名空間中定義的Sidecar、網關和虛擬服務使用。此特性提供了一種機制,使服務所有者和網格管理員能夠控制跨命名空間邊界的服務可見性。
對于Kubernetes Service,您可以通過將注釋 |
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域套接字端點一起使用。 |