Istio Ingress Gateway
Istio 服務網格中的網關
使用網關為網格來管理入站和出站流量,可以讓用戶指定要進入或離開網格的流量。
使用網關為網格來管理入站和出站流量,可以讓用戶指定要進入或離開網格的流量。
網關配置被用於運行在網格內獨立 Envoy 代理中,而不是服務工作負載的應用 Sidecar 代理。
Gateway
用於為 HTTP / TCP 流量配置負載均衡器,並不管該負載均衡器將在哪里運行。網格中可以存在任意數量的 Gateway
,並且多個不同的 Gateway
實現可以共存。實際上,通過在配置中指定一組工作負載(Pod)標簽,可以將 Gateway 配置綁定到特定的工作負載,從而允許用戶通過編寫簡單的 Gateway Controller 來重用現成的網絡設備。
Gateway
只用於配置 L4-L6 功能(例如,對外公開的端口,TLS 配置),所有主流的 L7 代理均以統一的方式實現了這些功能。然后,通過在 Gateway
上綁定 VirtualService
的方式,可以使用標准的 Istio 規則來控制進入 Gateway
的 HTTP 和 TCP 流量。
考慮到上述因素,v1alpha3引入了以下這些新的配置資源來控制進入網格,網格內部和離開網格的流量路由。
- Gateway:gateway資源可以將網格內部的服務暴露給網格外部的服務,供網格外部的服務調用,該資源描述了需要公開的端口、端口的協議類型、以及域名等。
- VirtualService:virtualService用來與Gateway綁定,實現服務訪問路由控制、服務版本與流量的控制。
- DestinationRule:外部請求經過VirtualService的路由規則后,如果目標服務設置了dr,那么dr配置的目標服務策略會生效。
- ServiceEntry:將網格外的服務加到服務發現中,就像是網格內的服務一樣被治理(成為k8s中的一個service),如網格外的mysql、redis等服務,或是部署在物理機上未加入網格內部的服務。將ServiceEntry描述的service加到服務發現中,對這些服務的outbound流量進行攔截,從而進行治理。
當ServiceEntry描述的service有endpoint變化時,我們可以監聽其變化,利用k8s基建,創建或者刪除k8s該service的endpoint,由於istio的服務發現依賴於k8s,該變化會被istio pilot-discovery感知到,並通過xDs通知envoy。
VirtualService,DestinationRule和ServiceEntry分別替換了原API中的RouteRule,DestinationPolicy和EgressRule。 Gateway是一個獨立於平台的抽象,用於對流入專用中間設備的流量進行建模。
下圖描述了跨多個配置資源的控制流程。 不同配置資源之間的關系
gateway
Gateway也可以看作網格的負載均衡器, 提供以下功能: 1) L4-L6的負載均衡 2) 對外的mTLS Istio服務網格中, Gateway可以部署任意多個,可以共用一個,也可以每個租戶、 namespace單獨隔離
Gateway用於為HTTP / TCP流量配置負載均衡器,並不管該負載均衡器將在哪里運行。 網格中可以存在任意數量的Gateway,並且多個不同的Gateway實現可以共存。 實際上,通過在配置中指定一組工作負載(Pod)標簽,可以將Gateway配置綁定到特定的工作負載,從而允許用戶通過編寫簡單的Gateway Controller來重用現成的網絡設備。
對於入口流量管理,您可能會問: 為什么不直接使用Kubernetes Ingress API ? 原因是Ingress API無法表達Istio的路由需求。 Ingress試圖在不同的HTTP代理之間取一個公共的交集,因此只能支持最基本的HTTP路由,最終導致需要將代理的其他高級功能放入到注解(annotation)中,而注解的方式在多個代理之間是不兼容的,無法移植。
Istio Gateway 通過將L4-L6配置與L7配置分離的方式克服了Ingress的這些缺點。 Gateway只用於配置L4-L6功能(例如,對外公開的端口,TLS配置),所有主流的L7代理均以統一的方式實現了這些功能。 然后,通過在Gateway上綁定VirtualService的方式,可以使用標准的Istio規則來控制進入Gateway的HTTP和TCP流量。
例如,下面這個簡單的Gateway配置了一個Load Balancer,以允許訪問host bookinfo.com的https外部流量入mesh中:
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: bookinfo-gateway spec: servers: - port: number: 443 name: https protocol: HTTPS hosts: - bookinfo.com tls: mode: SIMPLE serverCertificate: /tmp/tls.crt privateKey: /tmp/tls.key
要為進入上面的Gateway的流量配置相應的路由,必須為同一個host定義一個VirtualService(在下一節中描述),並使用配置中的gateways字段綁定到前面定義的Gateway
VirtualService
用一種叫做“Virtual services”的東西代替路由規則可能看起來有點奇怪,但對於它配置的內容而言,這事實上是一個更好的名稱,特別是在重新設計API以解決先前模型的可擴展性問題之后。
實際上,發生的變化是:在之前的模型中,需要用一組相互獨立的配置規則來為特定的目的服務設置路由規則,並通過precedence字段來控制這些規則的順序;在新的API中,則直接對(虛擬)服務進行配置,該虛擬服務的所有規則以一個有序列表的方式配置在對應的VirtualService 資源中。
在v1alph3,可以在單個VirtualService資源中提供相同的配置:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: reviews spec: hosts: - reviews http: - match: - headers: cookie: regex: "^(.*?;)?(user=jason)(;.*)?$" route: - destination: host: reviews subset: v2 - route: - destination: host: reviews subset: v1
VirtualService描述了一個或多個用戶可尋址目標到網格內實際工作負載之間的映射。在上面的示例中,這兩個地址是相同的,但實際上用戶可尋址目標可以是任何用於定位服務的,具有可選通配符前綴或CIDR前綴的DNS名稱。 這對於應用從單體架構到微服務架構的遷移過程特別有用,單體應用被拆分為多個獨立的微服務后,采用VirtaulService可以繼續把多個微服務對外暴露為同一個目標地址,而不需要服務消費者進行修改以適應該變化。
例如,以下規則允許服務消費者訪問Bookinfo應用程序的reviews和ratings服務,就好像它們是http://bookinfo.com/(虛擬)服務的一部分:
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: bookinfo spec: hosts: - bookinfo.com http: - match: - uri: prefix: /reviews route: - destination: host: reviews - match: - uri: prefix: /ratings route: - destination: host: ratings ...
實際上在`VirtualService`中hosts部分設置只是虛擬的目的地,因此不一定是已在網格中注冊的服務。這允許用戶為在網格內沒有可路由條目的虛擬主機的流量進行建模。 通過將VirtualService綁定到同一Host的Gateway配置(如前一節所述 ),可向網格外部暴露這些Host。
除了這個重大的重構之外, VirtualService還包括其他一些重要的改變:
- 可以在VirtualService配置中表示多個匹配條件,從而減少對冗余的規則設置。
- 每個服務版本都有一個名稱(稱為服務子集)。 屬於某個子集的一組Pod/VM在DestinationRule定義,具體定義參見下節。
- 通過使用帶通配符前綴的DNS來指定VirtualService的host,可以創建單個規則以作用於所有匹配的服務。 例如,在Kubernetes中,在’VirtualService’中使用*.foo.svc.cluster.local作為host,可以對foo命名空間中的所有服務應用相同的重寫規則。
DestinationRule
DestinationRule配置將流量轉發到服務時應用的策略集。 這些策略應由由服務提供者撰寫,用於描述斷路器,負載均衡設置,TLS設置等。 除了下述改變外,DestinationRule與其前身DestinationPolicy大致相同。
DestinationRule的host可以包含通配符前綴,以允許單個規則應用於多個服務。
DestinationRule定義了目的host的子集subsets (例如:命名版本)。 這些subset用於`VirtualService`的路由規則設置中,可以將流量導向服務的某些特定版本。 通過這種方式為版本命名后,可以在不同的virtual service中明確地引用這些命名版本的ubset,簡化Istio代理發出的統計數據,並可以將subsets編碼到SNI頭中。 為reviews服務配置策略和subsets的DestinationRule可能如下所示:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: reviews spec: host: reviews trafficPolicy: loadBalancer: simple: RANDOM subsets: - name: v1 labels: version: v1 - name: v2 labels: version: v2 trafficPolicy: loadBalancer: simple: ROUND_ROBIN - name: v3 labels: version: v3
注意,與DestinationPolicy不同的是,可在單個DestinationRule中指定多個策略(例如上面實例中的缺省策略和v2版本特定的策略)。
ServiceEntry
ServiceEntry用於將附加條目添加到Istio內部維護的服務注冊表中。 它最常用於對訪問網格外部依賴的流量進行建模,例如訪問Web上的API或遺留基礎設施中的服務。
所有以前使用EgressRule進行配置的內容都可以通過ServiceEntry輕松完成。 例如,可以使用類似這樣的配置來允許從網格內部訪問一個簡單的外部服務:
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: foo-ext spec: hosts: - foo.com ports: - number: 80 name: http protocol: HTTP
也就是說,ServiceEntry比它的前身具有更多的功能。首先,ServiceEntry不限於外部服務配置,它可以有兩種類型:網格內部或網格外部。網格內部條目只是用於向網格顯式添加服務,添加的服務與其他內部服務一樣。采用網格內部條目,可以把原本未被網格管理的基礎設施也納入到網格中(例如,把虛機中的服務添加到基於Kubernetes的服務網格中)。網格外部條目則代表了網格外部的服務。對於這些外部服務來說,mTLS身份驗證是禁用的,並且策略是在客戶端執行的,而不是在像內部服務請求一樣在服務器端執行策略。
由於ServiceEntry配置只是將服務添加到網格內部的服務注冊表中,因此它可以像注冊表中的任何其他服務一樣,與VirtualService和/或DestinationRule一起使用。例如,以下DestinationRule可用於啟動外部服務的mTLS連接:
apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: foo-ext spec: name: foo.com trafficPolicy: tls: mode: MUTUAL clientCertificate: /etc/certs/myclientcert.pem privateKey: /etc/certs/client_private_key.pem caCertificates: /etc/certs/rootcacerts.pem
創建和刪除v1alpha3路由規則
由於一個特定目的地的所有路由規則現在都存儲在單個VirtualService
資源的一個有序列表中,因此為該目的地添加新的規則不需要再創建新的RouteRule
,而是通過更新該目的地的VirtualService
資源來實現。
舊的路由規則:
istioctl create -f my-second-rule-for-destination-abc.yaml
v1alpha3
路由規則:
istioctl replace -f my-updated-rules-for-destination-abc.yaml
刪除路由規則也使用istioctl replace完成,當然刪除最后一個路由規則除外(刪除最后一個路由規則需要刪除VirtualService
)。
在添加或刪除引用服務版本的路由時,需要在該服務相應的DestinationRule
更新subsets 。 正如你可能猜到的,這也是使用istioctl replace
完成的。
Gateway
配置信息
Field | Type | Description | Required |
---|---|---|---|
servers | Server[] | 開放的服務列表 | 是 |
selector | map | 通過這個Label來找到執行 Gateway 規則的 Envoy | 是 |
Server
配置信息
Field | Type | Description | Required |
---|---|---|---|
port | Port | 服務對外監聽的端口 | 是 |
hosts | string[] | Gateway 發布的服務地址,是一個 FQDN 域名,可以支持左側通配符來進行模糊查詢 | 是 |
tls | TLSOptions | TLS安全配置 | 否 |
defaultEndpoint | string | 默認情況下,應將流量轉發到的環回IP端點或Unix域套接字 | 否 |
Port
配置信息
Field | Type | Description | Required |
---|---|---|---|
number | uint32 | 一個有效的端口號 | 是 |
protocol | string | 所使用的協議,支持HTTP|HTTPS|GRPC|HTTP2|MONGO|TCP|TLS. | 是 |
name | string | 給端口分配一個名稱 | 否 |
Server.TLSOptions
配置信息
Field | Type | Description | Required |
---|---|---|---|
httpsRedirect | bool | 是否要做 HTTP 重定向 | 否 |
mode | TLSmode | 在配置的外部端口上使用 TLS 服務時,可以取 PASSTHROUGH、SIMPLE、MUTUAL、AUTO_PASSTHROUGH 這 4 種模式 | 否 |
serverCertificate | string | 服務端證書的路徑。當模式是 SIMPLE 和 MUTUAL 時必須指定 | 否 |
privateKey | string | 服務端密鑰的路徑。當模式是 SIMPLE 和 MUTUAL 時必須指定 | 否 |
caCertificates | string | CA 證書路徑。當模式是 MUTUAL 時指定 | 否 |
credentialName | string | 用於唯一標識服務端證書和秘鑰。Gateway 使用 credentialName從遠端的憑證存儲中獲取證書和秘鑰,而不是使用 Mount 的文件 | 否 |
subjectAltNames | string[] | SAN 列表,SubjectAltName 允許一個證書指定多個域名 | 否 |
verifyCertificateSpki | string[] | 授權客戶端證書的SKPI的base64編碼的SHA-256哈希值的可選列表 | 否 |
verifyCertificateHash | string[] | 授權客戶端證書的十六進制編碼SHA-256哈希值的可選列表 | 否 |
minProtocolVersion | TLSProtocol | TLS 協議的最小版本 | 否 |
maxProtocolVersion | TLSProtocol | TLS 協議的最大版本 | 否 |
cipherSuites | string[] | 指定的加密套件,默認使用 Envoy 支持的加密套件 | 否 |
Server.TLSOptions.TLSmode
配置信息
Name | Description |
---|---|
PASSTHROUGH | 客戶端提供的SNI字符串將用作VirtualService TLS路由中的匹配條件,以根據服務注冊表確定目標服務 |
SIMPLE | 使用標准TLS語義的安全連接 |
MUTUAL | 通過提供服務器證書進行身份驗證,使用雙邊TLS來保護與下游的連接 |
AUTO_PASSTHROUGH | 與直通模式相似,不同之處在於具有此TLS模式的服務器不需要關聯的VirtualService即可從SNI值映射到注冊表中的服務。目標詳細信息(例如服務/子集/端口)被編碼在SNI值中。代理將轉發到SNI值指定的上游(Envoy)群集(一組端點)。 |
ISTIO_MUTUAL | 通過提供用於身份驗證的服務器證書,使用相互TLS使用來自下游的安全連接 |
Server.TLSOptions.TLSProtocol
配置信息
Name | Description |
---|---|
TLS_AUTO | 自動選擇DLS版本 |
TLSV1_0 | TLS 1.0 |
TLSV1_1 | TLS 1.1 |
TLSV1_2 | TLS 1.2 |
TLSV1_3 | TLS 1.3 |
參考:
https://preliminary.istio.io/zh/docs/concepts/traffic-management/#gateways
https://preliminary.istio.io/zh//blog/2018/v1alpha3-routing/
https://preliminary.istio.io/zh/docs/reference/config/networking/gateway/#Gateway
https://blog.csdn.net/fly910905/article/details/103969825
https://www.cnblogs.com/haoyunlaile/p/12882622.html
https://blog.csdn.net/liyunlong41/article/details/106097892