Istio 路由管理

Istio中的路由包含以下幾種常見的對(duì)象:

  • VirtualService:Istio服務(wù)網(wǎng)格中定義的路由規(guī)則,控制流量路由到service的規(guī)則
  • DestinationRule:配置將流量轉(zhuǎn)發(fā)到實(shí)際工作負(fù)載時(shí)應(yīng)用的策略集
  • ServiceEntry:用于在 Istio 服務(wù)網(wǎng)格之外啟用的服務(wù)請(qǐng)求
  • Gateway:為 HTTP/TCP 流量配置負(fù)載均衡器,最常見的是作用于網(wǎng)格邊緣,以處理應(yīng)用程序的入口/出口流量
  • EnvoyFilter:用于定制Envoy配置
  • Sidecar:用于定義入網(wǎng)和出網(wǎng)流量的可達(dá)性

VirtualService

首先是一個(gè)例子:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews-route
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  http:
  - name: "reviews-v2-routes"
    match:
    - uri:
        prefix: "/wpcatalog"
    - uri:
        prefix: "/consumercatalog"
    rewrite:
      uri: "/newcatalog"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v2
  - name: "reviews-v1-route"
    route:
    - destination:
        host: reviews.prod.svc.cluster.local
        subset: v1

上面的例子表示對(duì)于一個(gè)service:reviews.prod.svc.cluster.local收到的http流量,將被轉(zhuǎn)發(fā)到兩個(gè)目標(biāo)service:如果這個(gè)http請(qǐng)求的路徑包含/wpcatalog或/consumercatalog,那么流量將被發(fā)送給reviews服務(wù)的v2子集(v2子集是什么將在稍后解釋,可以看成擁有特定label的reviews服務(wù));否則,流量被發(fā)送給reviews服務(wù)的v1子集。

下面是一些關(guān)鍵配置項(xiàng):

  • hosts:接收請(qǐng)求的主機(jī)。它可以是一個(gè)DNS或IP地址。這兒的reviews.prod.svc.cluster.local是reviews service在K8s中的域名。因此,所有通向reviews服務(wù)的流量都將被這個(gè)virtualService重新路由。注意,如果這兒直接使用"reviews"而非"reviews.prod.svc.cluster.local",那么Istio會(huì)根據(jù)這個(gè)virtualService所在的命名空間來解析這個(gè)reviews服務(wù)的全限定名。例如這個(gè)virtualService定義在default namespace中,那么"reviews"會(huì)被視為 reviews.default.svc.cluster.local,而不會(huì)是這個(gè) reviews 服務(wù)所在真實(shí)的命名空間。為了避免可能的錯(cuò)誤配置,建議使用服務(wù)的全限定名(FQDN)來進(jìn)行服務(wù)引用。
  • hosts 配置的服務(wù)的名字只是表示該配置是針對(duì)于reviews服務(wù)的路由規(guī)則,但是具體將對(duì)該服務(wù)的訪問的流量路由到哪些服務(wù)的哪些實(shí)例上,就是要通過 destination 進(jìn)行配置。
  • destination.host 應(yīng)該明確指向服務(wù)注冊(cè)表中的一個(gè)服務(wù)。Istio 的服務(wù)注冊(cè)表除包含平臺(tái)服務(wù)注冊(cè)表中的所有服務(wù)(例如 Kubernetes 服務(wù)、Consul 服務(wù))之外,還包含了 ServiceEntry 資源所定義的服務(wù)。subset 用于配置流量目的地的子集,這個(gè)子集具體包含了哪些服務(wù),是通過DestinationRule來定義的。
  • 另外,還可以為每個(gè)destination添加weight,來實(shí)現(xiàn)路由的權(quán)重切分。

DestinationRule

subset 是服務(wù)端點(diǎn)的集合,可以用于 A/B 測(cè)試或者分版本路由等場(chǎng)景。對(duì)于 Kubernetes 中的服務(wù),一個(gè) subset 相當(dāng)于使用 label 的匹配條件選出來的 service。下面是一個(gè)DestinationRule的定義:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
  metadata:
  name: reviews-destination
spec:
  host: reviews.prod.svc.cluster.local
  subsets:
  - name: v1
    labels:
     version: v1
  - name: v2
    labels:
      version: v2

這個(gè)例子中為reviews服務(wù)定義了兩個(gè)子集:v1和v2,因此在VirtualService中可以通過subset:v1和subset:v2來引用這兩個(gè)服務(wù)。子集v1表示所有擁有 version=v1 的label的reviews服務(wù),而子集v2表示所有擁有 version=v2的label的reviews服務(wù)。

因此,DestinationRule 定義了目標(biāo) host 的子集 subsets (或者稱之為命名版本)。 這些 subset 用于 VirtualService 的路由規(guī)則設(shè)置中,可以將流量導(dǎo)向服務(wù)的某些特定版本。

ServiceEntry

Istio 服務(wù)網(wǎng)格內(nèi)部會(huì)維護(hù)一個(gè)與平臺(tái)無關(guān)的使用通用模型表示的服務(wù)注冊(cè)表,當(dāng)你的服務(wù)網(wǎng)格需要訪問外部服務(wù)的時(shí)候,就需要使用 ServiceEntry 來添加服務(wù)注冊(cè)。類似于K8s中ExternalName類型的Service。

Gateway

Gateway描述了在網(wǎng)絡(luò)邊緣運(yùn)行的負(fù)載均衡器,用于接收傳入或傳出的HTTP / TCP連接。下面是一個(gè)例子:

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    app: my-gateway-controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - uk.bookinfo.com

這個(gè)例子表示Istio會(huì)監(jiān)聽spec.selector選中的pod的80端口,并且允許包含了uk.bookinfo.com域名的http請(qǐng)求進(jìn)入。

Gateway 為 HTTP/TCP 流量配置了一個(gè)負(fù)載均衡,多數(shù)情況下在網(wǎng)格邊緣進(jìn)行操作,用于啟用一個(gè)服務(wù)的入口(ingress)流量,相當(dāng)于前端代理。與 Kubernetes 的 Ingress 不同,Istio Gateway 只配置四層到六層的功能(例如開放端口或者 TLS 配置),而 Kubernetes 的 Ingress 是七層的。將VirtualService 綁定到 Gateway 上,用戶就可以使用標(biāo)準(zhǔn)的 Istio 規(guī)則來控制進(jìn)入的 HTTP 和 TCP 流量。

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo-rule
  namespace: bookinfo-namespace
spec:
  hosts:
  - reviews.prod.svc.cluster.local
  - uk.bookinfo.com
  - eu.bookinfo.com
  gateways:
  - some-config-namespace/my-gateway
  http:
  - match:
    - headers:
        cookie:
          exact: "user=dev-123"
    route:
    - destination:
        port:
          number: 7777
        host: reviews.qa.svc.cluster.local
  - match:
    - uri:
        prefix: /reviews/
    route:
    - destination:
        port:
          number: 9080 # can be omitted if it's the only port for reviews
        host: reviews.prod.svc.cluster.local
      weight: 80
    - destination:
        host: reviews.qa.svc.cluster.local
      weight: 20

如這個(gè)例子所示,通過VirtualService綁定一個(gè)gateway能夠?qū)ateway進(jìn)入的流量路由到目標(biāo)service中。

EnvoyFilter

EnvoyFilter用于定制由Istio Pilot自動(dòng)生成的Envoy配置。通過EnvoyFilter能夠修改Envoy中的特配置,添加新的filter,listener,cluster等等。這個(gè)功能必須小心使用,因?yàn)椴徽_的配置可能會(huì)導(dǎo)致整個(gè)mesh奔潰。下面是一個(gè)例子:

apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: custom-protocol
  namespace: istio-config # as defined in meshConfig resource.
spec:
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: SIDECAR_OUTBOUND # will match outbound listeners in all sidecars
      listener:
        portNumber: 9307
        filterChain:
          filter:
            name: "envoy.tcp_proxy"
    patch:
      operation: INSERT_BEFORE
      value:
        name: "envoy.config.filter.network.custom_protocol"
        config:
         ...
  - applyTo: NETWORK_FILTER # http connection manager is a filter in Envoy
    match:
      # context omitted so that this applies to both sidecars and gateways
      listener:
        filterChain:
          filter:
            name: "envoy.http_connection_manager"
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager"
          idle_timeout: 30s

上面的例子在istio-config命名空間下定義了一個(gè)EnvoyFilter對(duì)象,這樣這些配置會(huì)作用于整個(gè)系統(tǒng)中的sidecar。它在原有的envoy.tcp_proxy filter前增加了一些配置,配置內(nèi)容省略。另外,又在envoy.http_connection_manager fileter中融合了一個(gè)新功能,即通過 envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager 增加一個(gè)30s的延遲。這就是一個(gè)EnvoyFilter的簡(jiǎn)單的使用例子。

Sidecar

Sidecar用于控制pod能夠接收什么流量和能夠向何處發(fā)送流量。

Sidecar是具有命名空間的資源。每個(gè)Sidecar應(yīng)用到命名空間的一個(gè)和多個(gè)工作負(fù)載,工作負(fù)載的選擇通過workloadSelector進(jìn)行,如果不指定workloadSelector(每個(gè)命名空間只能有一個(gè)這樣的Sidecar)則Sidecar應(yīng)用到命名空間的所有(沒有被其它帶有workloadSelector的Sidecar匹配的)工作負(fù)載。

如果命名空間包含多個(gè)沒有workloadSelector的Sidecar,或者多個(gè)Sidecar的workloadSelector匹配同一工作負(fù)載,則網(wǎng)格的行為是未定義的。

apiVersion: networking.istio.io/v1alpha3
kind: Sidecar
metadata:
  name: default
  namespace: prod-us1
spec:
  # 入站流量規(guī)則
  ingress:
  # 對(duì)于從9080端口入站的HTTP流量,將其轉(zhuǎn)發(fā)給Sidecar關(guān)聯(lián)的工作負(fù)載監(jiān)聽的UDS
  - port:
      number: 9080
      protocol: HTTP
      name: somename
    defaultEndpoint: unix:///var/run/someuds.sock
  # 出站流量規(guī)則
  egress:
  # 允許針對(duì)istio-system命名空間的出站流量
  - hosts:
    - "istio-system/*"
  # 允許針對(duì)prod-us1命名空間的9080端口的HTTP流量
  - port:
      number: 9080
      protocol: HTTP
      name: egresshttp
    hosts:
    - "prod-us1/*"

參考文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容