1. 程式人生 > 其它 >istio-控制 Ingress 流量 (Gateway VirtualService)

istio-控制 Ingress 流量 (Gateway VirtualService)

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引入了以下這些新的配置資源來控制進入網格,網格內部和離開網格的流量路由。

  1. Gateway
  2. VirtualService
  3. DestinationRule
  4. ServiceEntry

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還包括其他一些重要的改變:

  1. 可以在VirtualService配置中表示多個匹配條件,從而減少對冗餘的規則設定。
  2. 每個服務版本都有一個名稱(稱為服務子集)。 屬於某個子集的一組Pod/VM在DestinationRule定義,具體定義參見下節。
  3. 通過使用帶萬用字元字首的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完成的。

參考:

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