成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Istio 使用 Gateway API 實現(xiàn)流量管理

開源
Gateway API 最初設(shè)計用于管理從集群外部客戶端到集群內(nèi)部服務(wù)的流量(入口或北/南情況)。隨著時間的推移,服務(wù)網(wǎng)格用戶的興趣促使 GAMMA(Gateway API for Service Mesh)計劃的創(chuàng)建,以定義 Gateway API 如何用于同一集群內(nèi)的服務(wù)間或東/西流量。

Gateway API 是由 SIG-NETWORK 社區(qū)管理的開源項目,項目地址:https://gateway-api.sigs.k8s.io/。主要原因是 Ingress 資源對象不能很好的滿足網(wǎng)絡(luò)需求,很多場景下 Ingress 控制器都需要通過定義 annotations 或者 crd 來進行功能擴展,這對于使用標準和支持是非常不利的,新推出的 Gateway API 旨在通過可擴展的面向角色的接口來增強服務(wù)網(wǎng)絡(luò)。

Gateway API 是 Kubernetes 中的一個 API 資源集合,包括 GatewayClass、Gateway、HTTPRoute、TCPRoute、Service 等,這些資源共同為各種網(wǎng)絡(luò)用例構(gòu)建模型。

Gateway API

Gateway API 最初設(shè)計用于管理從集群外部客戶端到集群內(nèi)部服務(wù)的流量(入口或北/南情況)。隨著時間的推移,服務(wù)網(wǎng)格用戶的興趣促使 GAMMA(Gateway API for Service Mesh)計劃的創(chuàng)建,以定義 Gateway API 如何用于同一集群內(nèi)的服務(wù)間或東/西流量。

Gateway API 的改進比當前的 Ingress 資源對象有很多更好的設(shè)計:

  • 面向角色 - Gateway 由各種 API 資源組成,這些資源根據(jù)使用和配置 Kubernetes 服務(wù)網(wǎng)絡(luò)的角色進行建模。
  • 通用性 - 和 Ingress 一樣是一個具有眾多實現(xiàn)的通用規(guī)范,Gateway API 是一個被設(shè)計成由許多實現(xiàn)支持的規(guī)范標準。
  • 更具表現(xiàn)力 - Gateway API 資源支持基于 Header 頭的匹配、流量權(quán)重等核心功能,這些功能在 Ingress 中只能通過自定義注解才能實現(xiàn)。
  • 可擴展性 - Gateway API 允許自定義資源鏈接到 API 的各個層,這就允許在 API 結(jié)構(gòu)的適當位置進行更精細的定制。

還有一些其他值得關(guān)注的功能:

  • GatewayClasses - GatewayClasses 將負載均衡實現(xiàn)的類型形式化,這些類使用戶可以很容易了解到通過 Kubernetes 資源可以獲得什么樣的能力。
  • 共享網(wǎng)關(guān)和跨命名空間支持 - 它們允許共享負載均衡器和 VIP,允許獨立的路由資源綁定到同一個網(wǎng)關(guān),這使得團隊可以安全地共享(包括跨命名空間)基礎(chǔ)設(shè)施,而不需要直接協(xié)調(diào)。
  • 規(guī)范化路由和后端 - Gateway API 支持類型化的路由資源和不同類型的后端,這使得 API 可以靈活地支持各種協(xié)議(如 HTTP 和 gRPC)和各種后端服務(wù)(如 Kubernetes Service、存儲桶或函數(shù))。
  • 服務(wù)網(wǎng)格支持 - Gateway API 支持將路由資源與服務(wù)資源關(guān)聯(lián),以配置服務(wù)網(wǎng)格以及入口控制器。

面向角色設(shè)計

無論是道路、電力、數(shù)據(jù)中心還是 Kubernetes 集群,基礎(chǔ)設(shè)施都是為了共享而建的,然而共享基礎(chǔ)設(shè)施提供了一個共同的挑戰(zhàn),那就是如何為基礎(chǔ)設(shè)施用戶提供靈活性的同時還能被所有者控制。

Gateway API 通過對 Kubernetes 服務(wù)網(wǎng)絡(luò)進行面向角色的設(shè)計來實現(xiàn)這一目標,平衡了靈活性和集中控制。它允許共享的網(wǎng)絡(luò)基礎(chǔ)設(shè)施(硬件負載均衡器、云網(wǎng)絡(luò)、集群托管的代理等)被許多不同的團隊使用,所有這些都受到集群運維設(shè)置的各種策略和約束。

gateway api demo

一個集群運維人員創(chuàng)建了一個基于 GatewayClass 的 Gateway 資源,這個 Gateway 配置了它所代表的基礎(chǔ)網(wǎng)絡(luò)資源,集群運維和特定的團隊必須溝通什么可以附加到這個 Gateway 上來暴露他們的應(yīng)用。 集中的策略,如 TLS,可以由集群運維在 Gateway 上強制執(zhí)行,同時,Store 和 Site 應(yīng)用在他們自己的命名空間中運行,但將他們的路由附加到相同的共享網(wǎng)關(guān)上,允許他們獨立控制他們的路由邏輯。

這種關(guān)注點分離的設(shè)計可以使不同的團隊能夠管理他們自己的流量,同時將集中的策略和控制留給集群運維。

概念

在整個 Gateway API 中涉及到 3 個角色:基礎(chǔ)設(shè)施提供商、集群管理員、應(yīng)用開發(fā)人員,在某些場景下可能還會涉及到應(yīng)用管理員等角色。Gateway API 中定義了 3 種主要的資源模型:GatewayClass、Gateway、Route。

GatewayClass

GatewayClass 定義了一組共享相同配置和動作的網(wǎng)關(guān)。每個 GatewayClass 由一個控制器處理,是一個集群范圍的資源,必須至少有一個 GatewayClass 被定義。

這與 Ingress 的 IngressClass 類似,在 Ingress v1beta1 版本中,與 GatewayClass 類似的是 ingress-class 注解,而在 Ingress V1 版本中,最接近的就是 IngressClass 資源對象。

Gateway

Gateway 網(wǎng)關(guān)描述了如何將流量轉(zhuǎn)化為集群內(nèi)的服務(wù),也就是說,它定義了一個請求,要求將流量從不了解 Kubernetes 的地方轉(zhuǎn)換到集群內(nèi)的服務(wù)。例如,由云端負載均衡器、集群內(nèi)代理或外部硬件負載均衡器發(fā)送到 Kubernetes 服務(wù)的流量。

它定義了對特定負載均衡器配置的請求,該配置實現(xiàn)了 GatewayClass 的配置和行為規(guī)范,該資源可以由管理員直接創(chuàng)建,也可以由處理 GatewayClass 的控制器創(chuàng)建。

Gateway 可以附加到一個或多個路由引用上,這些路由引用的作用是將流量的一個子集導(dǎo)向特定的服務(wù)。

Route 資源

路由資源定義了特定的規(guī)則,用于將請求從網(wǎng)關(guān)映射到 Kubernetes 服務(wù)。從 v1alpha2 版本開始,API 中包含四種 Route 路由資源類型。

HTTPRoute

HTTPRoute 是用于 HTTP 或 HTTPS 連接,適用于我們想要檢查 HTTP 請求并使用 HTTP 請求進行路由或修改的場景,比如使用 HTTP Headers 頭進行路由,或在請求過程中對它們進行修改。

TLSRoute

TLSRoute 用于 TLS 連接,通過 SNI 進行區(qū)分,它適用于希望使用 SNI 作為主要路由方法的地方,并且對 HTTP 等更高級別協(xié)議的屬性不感興趣,連接的字節(jié)流不經(jīng)任何檢查就被代理到后端。

TCPRoute 和 UDPRoute

TCPRoute(和 UDPRoute)旨在用于將一個或多個端口映射到單個后端。在這種情況下,沒有可以用來選擇同一端口的不同后端的判別器,所以每個 TCPRoute 在監(jiān)聽器上需要一個不同的端口。你可以使用 TLS,在這種情況下,未加密的字節(jié)流會被傳遞到后端,當然也可以不使用 TLS,這樣加密的字節(jié)流將傳遞到后端。

GRPCRoute

GRPCRoute 用于路由 gRPC 流量,支持 GRPCRoute 的網(wǎng)關(guān)必須支持 HTTP/2,無需從 HTTP/1 進行初始升級,因此可以確保 gRPC 流量正常進行。

組合

GatewayClass、Gateway、xRoute 和 Service 的組合定義了一個可實施的負載均衡器,下圖說明了不同資源之間的關(guān)系:

組合關(guān)系

使用反向代理實現(xiàn)的網(wǎng)關(guān)的典型客戶端/網(wǎng)關(guān) API 請求流程如下所示:

  • 客戶端向 http://foo.example.com 發(fā)出請求。
  • DNS 將域名解析為 Gateway 網(wǎng)關(guān)地址。
  • 反向代理在監(jiān)聽器上接收請求,并使用 Host Header 來匹配 HTTPRoute。
  • (可選)反向代理可以根據(jù) HTTPRoute 的匹配規(guī)則進行路由。
  • (可選)反向代理可以根據(jù) HTTPRoute 的過濾規(guī)則修改請求,即添加或刪除 headers。
  • 最后,反向代理根據(jù) HTTPRoute 的 forwardTo 規(guī)則,將請求轉(zhuǎn)發(fā)給集群中的一個或多個對象,即服務(wù)。

與 Istio API 的區(qū)別

我們這里主要是講解 Gateway API 在服務(wù)網(wǎng)格中的使用,首先我們先了解下 Gateway API 與 Istio API 的區(qū)別。

Gateway API 與 Istio API(如 Gateway 和 VirtualService)有很多相似之處。主資源使用相同的 Gateway 名稱,并且這些資源服務(wù)于相類似的目標。

新的 Gateway API 致力于從 Kubernetes 的各種 Ingress 實現(xiàn)(包括 Istio)中吸取經(jīng)驗,以構(gòu)建標準化的,獨立于供應(yīng)商的 API。這些 API 通常與 Istio Gateway 和 VirtualService 具有相同的用途,但依然有一些不同的地方:

  • Istio API 中的 Gateway 僅配置已部署的現(xiàn)有網(wǎng)關(guān) Deployment/Service,而在 Gateway API 中的 Gateway 資源不僅配置也會部署網(wǎng)關(guān)。
  • 在 Istio VirtualService 中,所有協(xié)議都在單一的資源中配置,而在 Gateway API 中,每種協(xié)議類型都有自己的資源,例如 HTTPRoute 和 TCPRoute。
  • 雖然 Gateway API 提供了大量豐富的路由功能,但它還沒有全部涵蓋 Istio 的全部特性。

實現(xiàn)

接下來我們就來了解下如何在 Istio z 中使用 Gateway API。默認情況下 Kubernetes 集群中不會安裝 Gateway API,首先我們需要安裝 Gateway API CRD:

$ kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.0.0/standard-install.yaml
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created

standard-install.yaml 包括所有已升級為 GA 或 Beta 的資源,包括 GatewayClass、Gateway、HTTPRoute 和 ReferenceGrant,由于 Istio 已經(jīng)對 Gateway API 提供了支持,所以現(xiàn)在我們就可以直接使用了。比如現(xiàn)在就會自動創(chuàng)建一個 istio 的 GatewayClass 資源對象,如下所示(另外還有一個名為 istio-remote):

$ kubectl get gatewayclass
NAME           CONTROLLER                    ACCEPTED   AGE
istio          istio.io/gateway-controller   True       106s
istio-remote   istio.io/unmanaged-gateway    True       106s
$ kubectl get gatewayclass istio -oyaml
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: istio
spec:
  controllerName: istio.io/gateway-controller
  description: The default Istio GatewayClass

因為大部分場景下在一個 Kubernetes 集群中只會有一個 Istio 集群,所以我們可以直接使用默認的 istio 這個 GatewayClass,如果你有多個 Istio 集群,那么你可以創(chuàng)建多個 GatewayClass 來區(qū)分不同的集群。

比如接下來我們來嘗試將 httpbin 應(yīng)用使用 Gateway API 暴露到外部,首先我們需要部署一個 httpbin 應(yīng)用:

kubectl apply -f samples/httpbin/httpbin.yaml

然后接下來同樣我們需要部署一個 Gateway 資源對象,用于將流量從外部負載均衡器轉(zhuǎn)發(fā)到集群內(nèi)的服務(wù),如下所示:

# default-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: gateway
  namespace: istio-ingress # 網(wǎng)關(guān)資源對象所在的命名空間
spec:
  gatewayClassName: istio # 使用默認的 istio GatewayClass
  listeners: # 監(jiān)聽器
    - name: default
      hostname: "*.example.com"
      port: 80
      protocol: HTTP
      allowedRoutes: # 允許的路由
        namespaces:
          from: All # 允許所有命名空間

Gateway 代表了邏輯負載均衡器的實例化,它是根據(jù)一個 istio 這個 GatewayClass 進行模板化的,網(wǎng)關(guān)在 80 端口上監(jiān)聽 HTTP 流量,這個特定的 GatewayClass 在部署后會自動分配一個 IP 地址,該地址會顯示在 Gateway.status 中。

需要注意的是這里我們聲明使用的命名空間為 istio-ingress, 這是因為 Istio Gateway 可以直接使用 istio ingressgateway 的 Deployment,而這個 Deployment 默認是部署在 istio-system 命名空間中的,我們這里單獨將 Gateway 資源對象創(chuàng)建在 istio-ingress 命名空間中,那么就會自動在這個命名空間中部署一個網(wǎng)關(guān)控制器,用于區(qū)分默認的 istio ingressgateway。

所以我們需要在 istio-ingress 命名空間中創(chuàng)建這個 Gateway 資源對象,這樣才能讓 istio ingressgateway 通過 Gateway 資源對象來獲取配置。

kubectl create namespace istio-ingress

然后直接應(yīng)用這個資源對象即可:

$ kubectl apply -f default-gateway.yaml
$ kubectl get gateway -n istio-ingress
NAME      CLASS   ADDRESS   PROGRAMMED   AGE
gateway   istio             False        8m23s
$ kubectl get deploy -n istio-ingress
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
gateway-istio   1/1     1            1           8m35s
$ kubectl get svc -n istio-ingress
NAME            TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE
gateway-istio   LoadBalancer   10.100.103.86   <pending>     15021:31509/TCP,80:32530/TCP   9m38s

我們也可以去對比下上面生成的 gateway-istio 和 Istio 默認的 istio-ingressgateway 的 Deployment,他們的配置幾乎是一樣的。

接下來我們就需要去創(chuàng)建一個路由規(guī)則了,也就是想要如何訪問我們的 httpbin 應(yīng)用,類似于 VirtualService,我們可以使用 HTTPRoute 資源對象來定義這個路由規(guī)則,如下所示:

# httpbin-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: httpbin
  namespace: default
spec:
  parentRefs: # 引用定義的 Gateway 對象
    - name: gateway
      namespace: istio-ingress
  hostnames: ["httpbin.example.com"] # 域名
  rules: # 具體的路由規(guī)則
    - matches:
        - path:
            type: PathPrefix
            value: /get # 匹配 /get 的請求
      backendRefs: # 引用的后端服務(wù)
        - name: httpbin
          port: 8000

在上面的 HTTPRoute 對象中我們通過 parentRefs 字段指定要連接到的網(wǎng)關(guān),只要網(wǎng)關(guān)允許這種連接,這將允許路由接收來自父網(wǎng)關(guān)的流量,在 backendRefs 中定義將要發(fā)送流量的后端。但是需要注意我們這里只定義了匹配 /get 這個路徑的請求,然后將要訪問的域名通過 hostnames 來定義。

同樣直接應(yīng)用該資源對象即可:

$ kubectl apply -f httpbin-route.yaml
$ kubectl get httproute
NAME      HOSTNAMES                 AGE
httpbin   ["httpbin.example.com"]   5s

然后我們就可以通過 httpbin.example.com 來訪問 httpbin 應(yīng)用了:

# $ export INGRESS_HOST=$(kubectl get gateways.gateway.networking.k8s.io gateway -n istio-ingress -ojsnotallow='{.status.addresses[0].value}')
export GATEWAY_URL=$(kubectl get po -l istio.io/gateway-name=gateway -n istio-ingress -o 'jsnotallow={.items[0].status.hostIP}'):$(kubectl get svc gateway-istio -n istio-ingress -o 'jsnotallow={.spec.ports[?(@.name=="default")].nodePort}')

如果你的集群可以正常使用 LoadBalancer,那么 Gateway 控制器在部署后會自動分配一個 IP 地址,該地址會顯示在 Gateway.status 中。我們這里暫不支持,所以還是可以通過 NodePort 方式來進行訪問。然后可以使用 curl 訪問 httpbin 服務(wù):

$ curl -s -HHost:httpbin.example.com "http://$GATEWAY_URL/get"
HTTP/1.1 200 OK
server: istio-envoy
date: Mon, 18 Dec 2023 07:29:11 GMT
content-type: application/json
content-length: 494
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 2

請注意,使用 -H 標志可以將 Host HTTP 標頭設(shè)置為 httpbin.example.com。這一步是必需的,因為 HTTPRoute 已配置為處理 httpbin.example.com 的請求,但是在測試環(huán)境中,該主機沒有 DNS 綁定,只是將請求發(fā)送到入口 IP。

訪問其他沒有被顯式暴露的 URL 時,正常就會看到 HTTP 404 錯誤:

$ curl -s -I -HHost:httpbin.example.com "http://$INGRESS_HOST/headers"
HTTP/1.1 404 Not Found
date: Mon, 18 Dec 2023 07:31:51 GMT
server: istio-envoy
transfer-encoding: chunked

同樣我們也可以查看下 gateway-istio 的日志,可以看到類似于下面的日志:

$ kubectl -n istio-ingress logs -f gateway-istio-7474cd4d9b-8dw2k
# ......
2023-12-18T07:04:33.164968Z     info    cache   returned workload trust anchor from cache       ttl=23h59m59.835033638s
2023-12-18T07:04:33.621616Z     info    Readiness succeeded in 813.201909ms
2023-12-18T07:04:33.621946Z     info    Envoy proxy is ready
[2023-12-18T07:29:11.177Z] "HEAD /get HTTP/1.1" 200 - via_upstream - "-" 0 0 2 2 "10.244.1.1" "curl/7.29.0" "68f51e89-8125-4d9e-be36-e0cdc6e6ead8" "httpbin.example.com" "10.244.1.131:80" outbound|8000||httpbin.default.svc.cluster.local 10.244.1.132:46066 10.244.1.132:80 10.244.1.1:55626 - default.httpbin.0
[2023-12-18T07:31:52.051Z] "HEAD /headers HTTP/1.1" 404 NR route_not_found - "-" 0 0 0 - "10.244.1.1" "curl/7.29.0" "a9a1002f-d65c-40d8-861d-ec99d4a4a442" "httpbin.example.com" "-" - - 10.244.1.132:80 10.244.1.1:53583 - -

證明我們的路由規(guī)則已經(jīng)生效了。

同樣如果我們想要能夠正常訪問刀 /headers 路由,那么我們可以更新下 HTTPRoute 對象:

# httpbin-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: httpbin
  namespace: default
spec:
  parentRefs: # 引用定義的 Gateway 對象
    - name: gateway
      namespace: istio-ingress
  hostnames: ["httpbin.example.com"] # 域名
  rules: # 具體的路由規(guī)則
    - matches:
        - path:
            type: PathPrefix
            value: /get # 匹配 /get 的請求
        - path:
            type: PathPrefix
            value: /headers # 匹配 /headers 的請求
      filters:
        - type: RequestHeaderModifier # 添加一個修改請求頭的過濾器
          requestHeaderModifier:
            add: # 添加一個標頭
              - name: my-added-header
                value: added-value
      backendRefs: # 引用的后端服務(wù)
        - name: httpbin
          port: 8000

我們除了在 rules 中添加了一個匹配 /headers 的規(guī)則外,還添加了一個 RequestHeaderModifier 過濾器,用于添加一個 Header 頭信息,更新這個資源對象后再次訪問 /headers,注意到 My-Added-Header 標頭已被添加到請求中了:

$ curl -s -HHost:httpbin.example.com "http://$GATEWAY_URL/headers"
{
  "headers": {
    "Accept": "*/*",
    "Host": "httpbin.example.com",
    "My-Added-Header": "added-value",  # 添加了一個Header頭
    "User-Agent": "curl/7.29.0",
    "X-Envoy-Attempt-Count": "1",
    "X-Envoy-Internal": "true",
    "X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=11fc66a1c6c9fc44e65ec67f7f8b16d06fbaa73d9729e141e0bd91134dc59db3;Subject=\"\";URI=spiffe://cluster.local/ns/istio-ingress/sa/gateway-istio"
  }
}

在上面的示例中,在配置網(wǎng)關(guān)之前,我們并沒有去安裝 Ingress 網(wǎng)關(guān)的 Deployment,因為在默認配置中會根據(jù) Gateway 配置自動分發(fā)網(wǎng)關(guān) Deployment 和 Service。但是對于高級別的場景可能還是需要去手動部署。

自動部署

默認情況下,每個 Gateway 將自動提供相同名稱的 Service 和 Deployment。如果 Gateway 發(fā)生變化(例如添加了一個新端口),這些配置將會自動更新。這些資源可以通過以下幾種方式進行定義:

  • 將 Gateway 上的注解和標簽復(fù)制到 Service 和 Deployment。這就允許配置從上述字段中讀取到的內(nèi)容,如配置內(nèi)部負載均衡器等。Istio 提供了一個額外的注解來配置生成的資源:
  • networking.istio.io/service-type:控制 Service.spec.type 字段。例如設(shè)置 ClusterIP 為不對外暴露服務(wù),將會默認為 LoadBalancer。
  • 通過配置addresses字段可以顯式設(shè)置Service.spec.loadBalancerIP字段:
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: gateway
spec:
addresses:
    - value: 192.0.2.0 # 僅能指定一個地址
    type: IPAddress

手動部署

如果您不希望使用自動部署,可以進行手動配置 Deployment 和 Service。完成此選項后,您將需要手動將 Gateway 鏈接到 Service,并保持它們的端口配置同步。

要將 Gateway 鏈接到 Service,需要將 addresses 字段配置為指向單個 Hostname。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
  name: gateway
spec:
  addresses:
    - value: ingress.istio-gateways.svc.cluster.local
      type: Hostname

當然我們這里只是一個最簡單的示例,我們將在后面的課程中繼續(xù)介紹 Gateway API 的更多功能。

配置請求路由

接下來我們來了解下如果通過 Gateway API 將請求動態(tài)路由到微服務(wù)的多個版本。

同樣我們這里以 Bookinfo 示例為例(首先要部署 Bookinfo 應(yīng)用),我們首先將所有流量路由到微服務(wù)的 v1 (版本 1),然后將應(yīng)用規(guī)則根據(jù) HTTP 請求 header 的值路由流量。

首先專門為 Bookinfo 應(yīng)用創(chuàng)建一個 Gateway 資源對象,如下所示:

# bookinfo-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  gatewayClassName: istio
  listeners:
    - name: http
      port: 80
      protocol: HTTP
      allowedRoutes:
        namespaces:
          from: Same

上面的 Gateway 資源對象與之前的示例類似,只是這里我們將 allowedRoutes 設(shè)置為 Same,表示允許同一命名空間中的所有路由資源對象都可以連接到這個網(wǎng)關(guān)。

然后為 Productpage 應(yīng)用創(chuàng)建一個 HTTPRoute 資源對象,如下所示:

# productpage-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: bookinfo
spec:
  parentRefs:
    - name: bookinfo-gateway # 引用上面定義的 Gateway 對象
  rules:
    - matches:
        - path:
            type: Exact
            value: /productpage
        - path:
            type: PathPrefix
            value: /static
        - path:
            type: Exact
            value: /login
        - path:
            type: Exact
            value: /logout
        - path:
            type: PathPrefix
            value: /api/v1/products
      backendRefs:
        - name: productpage # 引用的后端服務(wù)
          port: 9080

和以前 VirtualService 的類似,我們?yōu)?Productpage 應(yīng)用配置了幾個路由規(guī)則,這樣我們就可以在頁面上正常訪問應(yīng)用了。直接應(yīng)用上面的兩個資源清單文件即可:

kubectl apply -f bookinfo-gateway.yaml
kubectl apply -f productpage-route.yaml

同樣當我們創(chuàng)建了 Gateway 對象后,會自動在 default 命名空間中部署一個 gateway-istio 的 Deployment 和 對應(yīng)的 Service:

$ kubectl get pods -l istio.io/gateway-name=bookinfo-gateway
NAME                                      READY   STATUS    RESTARTS   AGE
bookinfo-gateway-istio-548556df95-kggs2   1/1     Running   0          112s
$ kubectl get svc bookinfo-gateway-istio
NAME                     TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                        AGE
bookinfo-gateway-istio   LoadBalancer   10.111.86.147   <pending>     15021:30357/TCP,80:30749/TCP   2m19s

正常我們就可以通過上面的 30749 這個 NodePort 端口來訪問 Productpage 應(yīng)用了:

bookinfo

路由到版本 1

同樣的頁面上的評論區(qū)域會出現(xiàn) 3 種不同的狀態(tài),因為我們背后有 3 個不同的版本的評論服務(wù),我們可以創(chuàng)建一個如下所示的 HTTPRoute 資源對象,首先將流量路由到 v1 版本:

# route-reviews-v1.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs: # 這里我們引用的是 reviews 這個 Service 對象
    - group: ""
      kind: Service
      name: reviews
      port: 9080
  rules:
    - backendRefs:
        - name: reviews-v1
          port: 9080

注意上面的資源對象中我們是通過 parentRefs 字段引用的是 reviews 這個 Service 對象,而不是 Gateway 對象了,因為我們流量并不是從 Gateway 直接過來的,而是通過 Productpage 訪問 reviews 服務(wù),也就是 Service 對象。然后背后的我們會將流量全部路由到 v1 版本的 reviews 服務(wù) reviews-v1。

現(xiàn)在我們再應(yīng)用上面的這個資源對象:

kubectl apply -f route-reviews-v1.yaml

不過這里需要注意不同于 Istio API 使用 DestinationRule 子集來定義服務(wù)的版本, Kubernetes Gateway API 將為此使用后端 Service 服務(wù)來進行定義。所以我們還需要運行以下命令為三個版本的 reviews 服務(wù)創(chuàng)建后端服務(wù)定義:

kubectl apply -f samples/bookinfo/platform/kube/bookinfo-versions.yaml

然后我們可以通過再次刷新 Bookinfo 應(yīng)用程序,現(xiàn)在我們無論刷新多少次,頁面的評論部分都不會顯示評級星標,這是因為我們將 Istio 配置為將評論服務(wù)的所有流量路由到版本 reviews:v1,而此版本的服務(wù)不訪問星級評分服務(wù)。

reviews v1

基于用戶身份路由

接下來我們來更改路由配置,將來自特定用戶的所有流量路由到特定服務(wù)版本,比如將來自名為 Jason 的用戶的所有流量被路由到服務(wù) reviews:v2(包含星級評分功能的版本)。

創(chuàng)建一個如下所示的 HTTPRoute 資源對象:

# route-reviews-jason-v2.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
    - group: ""
      kind: Service
      name: reviews
      port: 9080
  rules:
    - matches:
        - headers: # 匹配請求頭 end-user: jason
            - name: end-user
              value: jason
      backendRefs:
        - name: reviews-v2
          port: 9080
    - backendRefs:
        - name: reviews-v1
          port: 9080

在上面的 HTTPRoute 資源對象中,我們將訪問 reviews 的流量分為兩個規(guī)則,第一個規(guī)則匹配請求頭 end-user: jason,然后將流量路由到 reviews-v2 服務(wù),第二個則是如果不匹配將流量路由到 reviews-v1 服務(wù)。

然后我們再次應(yīng)用這個資源對象:

kubectl apply -f route-reviews-jason-v2.yaml

然后我們在 Bookinfo 頁面上面,可以以用戶 jason 身份進行登錄,登錄后無論如何刷新瀏覽器,我們將始終在頁面上看到黑色的星級評分,也就是 reviews 的 v2 版本。

jason 用于

我們也可以切換成其他用戶,或者不登錄,刷新瀏覽器,那么就不會顯示星級評分了。

基于權(quán)重的路由

接下來我們再來測試下基于權(quán)重的路由,常常我們有將流量從微服務(wù)的一個版本逐步遷移到另一個版本的需求,同樣使用 Gateway API 來實現(xiàn)也非常簡單。

下面我們將會把 50% 的流量發(fā)送到 reviews:v1,另外,50% 的流量發(fā)送到 reviews:v3。接著,再把 100% 的流量發(fā)送到 reviews:v3 來完成遷移。

首先重新運行下面的命令將所有流量路由到 review 服務(wù)的 v1 版本。

kubectl apply -f route-reviews-v1.yaml

接下來創(chuàng)建如下所示的資源對象,把 50% 的流量從 reviews:v1 轉(zhuǎn)移到 reviews:v3:

# route-reviews-50-v3.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
    - group: ""
      kind: Service
      name: reviews
      port: 9080
  rules:
    - backendRefs:
        - name: reviews-v1
          port: 9080
          weight: 50
        - name: reviews-v3
          port: 9080
          weight: 50

上面的對象中在 backendRefs 中我們使用了一個 weight 字段,用于設(shè)置權(quán)重,這里我們將 reviews-v1 和 reviews-v3 的權(quán)重都設(shè)置為 50,也就是說將流量平均分配到這兩個版本的服務(wù)上。

然后我們應(yīng)用這個資源對象即可:

kubectl apply -f route-reviews-50-v3.yaml

等待幾秒鐘,等待新的規(guī)則傳播到代理中生效,然后我們再次刷新瀏覽器中的 productpage 頁面,大約有 50% 的幾率會看到頁面中帶紅色星級的評價內(nèi)容。 這是因為 reviews 的 v3 版本可以訪問帶星級評價,但 v1 版本不能。

如果你認為 reviews:v3 微服務(wù)已經(jīng)穩(wěn)定,那么接下來我們就可以將 100% 的流量路由 reviews:v3:

# route-reviews-v3.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
    - group: ""
      kind: Service
      name: reviews
      port: 9080
  rules:
    - backendRefs:
        - name: reviews-v3
          port: 9080

然后我們再次應(yīng)用這個資源對象:

kubectl apply -f route-reviews-v3.yaml

現(xiàn)在,當我們訪問 Bookinfo 應(yīng)用時,將始終看到帶有紅色星級評分的書評。

使用 TLS 暴露服務(wù)

接下來我們來看下如何通過 TLS 來暴露服務(wù),這里我們以 httpbin 示例進行說明。

首先要部署 httpbin 示例:

kubectl apply -f samples/httpbin/httpbin.yaml

然后接下來生成客戶端和服務(wù)器證書和密鑰,這里我們使用 openssl 工具來生成。

首先創(chuàng)建用于服務(wù)簽名的根證書和私鑰:

$ mkdir example_certs1
$ openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -subj '/O=example Inc./CN=example.com' -keyout example_certs1/example.com.key -out example_certs1/example.com.crt

為 httpbin.example.com 創(chuàng)建證書和私鑰:

$ openssl req -out example_certs1/httpbin.example.com.csr -newkey rsa:2048 -nodes -keyout example_certs1/httpbin.example.com.key -subj "/CN=httpbin.example.com/O=httpbin organization"
$ openssl x509 -req -sha256 -days 365 -CA example_certs1/example.com.crt -CAkey example_certs1/example.com.key -set_serial 0 -in example_certs1/httpbin.example.com.csr -out example_certs1/httpbin.example.com.crt

然后接下來需要為入口網(wǎng)關(guān)創(chuàng)建 Secret:

kubectl create -n istio-system secret tls httpbin-credential \
  --key=example_certs1/httpbin.example.com.key \
  --cert=example_certs1/httpbin.example.com.crt

這里我們創(chuàng)建一個獨立的 Kubernetes Gateway:

# httpbin-gateway.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: mygateway
  namespace: istio-system
spec:
  gatewayClassName: istio
  listeners:
    - name: https
      hostname: "httpbin.example.com"
      port: 443
      protocol: HTTPS
      tls:
        mode: Terminate
        certificateRefs:
          - name: httpbin-credential
      allowedRoutes:
        namespaces:
          from: Selector
          selector:
            matchLabels:
              kubernetes.io/metadata.name: default

在上面的對象中我們配置了 HTTPS 協(xié)議,并在 tls 中配置使用 Terminate 模式,也就是說我們將在網(wǎng)關(guān)上終止 TLS 連接,然后在 certificateRefs 中引用了之前創(chuàng)建的 Secret 對象,用于配置網(wǎng)關(guān)的憑據(jù)。最后通過 allowedRoutes 字段配置了允許的路由,這里我們配置的是將流量路由到 default 命名空間中的所有路由資源對象。

接下來,通過定義相應(yīng)的 HTTPRoute 配置網(wǎng)關(guān)的入口流量路由:

# httpbin-route.yaml
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: httpbin
spec:
  parentRefs:
    - name: mygateway
      namespace: istio-system
  hostnames: ["httpbin.example.com"]
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /status
        - path:
            type: PathPrefix
            value: /delay
      backendRefs:
        - name: httpbin
          port: 8000

這里最重要的就是在 parentRefs 字段中引用了之前創(chuàng)建的 Gateway 對象。

然后我們直接應(yīng)用上面的兩個資源對象即可:

kubectl apply -f httpbin-gateway.yaml
kubectl apply -f httpbin-route.yaml

同樣應(yīng)用后會自動在 istio-system 命名空間中部署一個 gateway-istio 的 Deployment 和對應(yīng)的 Service:

$ kubectl get pods -n istio-system
NAME                                       READY   STATUS    RESTARTS         AGE
mygateway-istio-64676bfc88-q8nft           1/1     Running   0                32s
$ kubectl get svc -n istio-system
NAME                      TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                                      AGE
mygateway-istio           LoadBalancer   10.111.175.36    <pending>     15021:31206/TCP,443:32597/TCP                                                74s

然后我們可以通過 32597 這個 NodePort 端口向 httpbin 服務(wù)發(fā)送 HTTPS 請求:

$ curl -v -HHost:httpbin.example.com --resolve "httpbin.example.com:32597:192.168.0.100" --cacert example_certs1/example.com.crt "https://httpbin.example.com:32597/status/418"

* Initializing NSS with certpath: sql:/etc/pki/nssdb
*   CAfile: example_certs1/example.com.crt
  CApath: none
* SSL connection using TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
* Server certificate:
*       subject: O=httpbin organization,CN=httpbin.example.com
*       start date: Dec 22 07:13:47 2023 GMT
*       expire date: Dec 21 07:13:47 2024 GMT
*       common name: httpbin.example.com
*       issuer: CN=example.com,O=example Inc.
# ......

    -=[ teapot ]=-

       _...._
     .'  _ _ `.
    | ."` ^ `". _,
    \_;`"---"`|//
      |       ;/
      \_     _/
        `"""`
* Connection #0 to host httpbin.example.com left intact

正常我們就可以看到輸出一個茶壺,這樣我們完成了通過 TLS 來暴露服務(wù)。

TCP 路由

除了 HTTP 路由外,Gateway API 還支持 TCP 和 UDP 路由,配置 TCP 的路由規(guī)則,需要使用單獨的資源對象 TCPRoute,如下所示:

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: tcp-echo-gateway
spec:
  gatewayClassName: istio
  listeners:
    - name: tcp-31400
      protocol: TCP
      port: 31400
      allowedRoutes: # 只允許 TCPRoute 資源對象連接到這個網(wǎng)關(guān)
        kinds:
          - kind: TCPRoute
---
apiVersion: v1
kind: Service
metadata:
  name: tcp-echo-v1
spec:
  ports:
    - port: 9000
      name: tcp
  selector:
    app: tcp-echo
    version: v1
---
apiVersion: v1
kind: Service
metadata:
  name: tcp-echo-v2
spec:
  ports:
    - port: 9000
      name: tcp
  selector:
    app: tcp-echo
    version: v2
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: TCPRoute # TCPRoute 資源對象
metadata:
  name: tcp-echo
spec:
  parentRefs: # 引用定義的 Gateway 對象
    - name: tcp-echo-gateway
      sectionName: tcp-31400
  rules:
    - backendRefs:
        - name: tcp-echo-v1
          port: 9000
          weight: 80
        - name: tcp-echo-v2
          port: 9000
          weight: 20

其他使用

其他的流量管理比如故障注入、熔斷這些,Gateway API 尚不支持。

但是支持請求超時,比如對 reviews 服務(wù)的調(diào)用增加一個半秒的請求超時,可以使用下面的資源對象:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: reviews
spec:
  parentRefs:
    - group: ""
      kind: Service
      name: reviews
      port: 9080
  rules:
    - backendRefs:
        - name: reviews-v2
          port: 9080
      timeouts:
        request: 500ms

上面的對象中我們添加了一個 timeouts 字段,用于設(shè)置請求超時時間。

同樣還支持流量鏡像,如下的資源對象:

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: httpbin
spec:
  parentRefs:
    - group: ""
      kind: Service
      name: httpbin
      port: 8000
  rules:
    - filters:
        - type: RequestMirror
          requestMirror:
            backendRef:
              name: httpbin-v2
              port: 80
      backendRefs:
        - name: httpbin-v1
          port: 80

在上面的資源對象中我們添加了一個 RequestMirror 過濾器,該過濾器用于將流量鏡像到另外的服務(wù)上去。

責(zé)任編輯:姜華 來源: k8s技術(shù)圈
相關(guān)推薦

2021-07-27 06:51:53

Istio 微服務(wù)Service Mes

2025-04-17 09:09:29

2021-07-28 06:26:33

Istio 流量管理微服務(wù)

2022-05-10 07:46:08

Envoy網(wǎng)絡(luò)通訊

2023-11-09 07:23:57

Istio路由分析

2023-11-07 17:32:31

Istiok8s

2022-01-06 07:46:01

Traefik 開源Gateway API

2024-07-05 11:13:05

2021-11-01 08:16:26

模型Istio服務(wù)

2023-11-08 00:23:08

網(wǎng)關(guān)API

2024-09-23 08:03:59

2023-06-05 08:00:00

mTLSIstio安全

2023-04-18 15:18:10

2024-05-09 08:24:01

2022-11-24 08:35:28

KitexProxyless

2023-11-07 07:46:02

GatewayKubernetes

2019-08-22 09:55:17

RedisAPI數(shù)據(jù)

2024-01-30 07:58:41

KubernetesGAMMA網(wǎng)關(guān)

2023-11-07 07:08:57

2021-08-03 14:12:57

API攻擊流量安全
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久久久久久 | 国产一级淫片a直接免费看 免费a网站 | 精品日韩一区二区 | 国产一区二区三区视频 | 全免费a级毛片免费看视频免 | 一区二区三区日 | 中文精品视频 | 国产精品美女久久久久久久久久久 | 国产精品视频免费观看 | 成人免费看片 | 欧美日韩久久久 | 99久久婷婷国产综合精品电影 | 久久中文字幕电影 | 99久久中文字幕三级久久日本 | 亚洲精品中文字幕在线观看 | 欧美xxxx在线| 一区二区三区国产 | aaaaaaa片毛片免费观看 | 午夜影院视频 | 欧美一级片 | 夜夜久久| 精品久久久久久久久久久院品网 | 国产我和子的乱视频网站 | 欧美精品a∨在线观看不卡 国产精品久久国产精品 | www.国产精 | 国产乱码精品一区二区三区五月婷 | 国产精品久久久久久久久免费桃花 | 久久精品国产一区二区三区不卡 | 97天天干 | 久久综合成人精品亚洲另类欧美 | 精品国产乱码久久久久久丨区2区 | 精品美女| 欧州一区| 日日操夜夜操天天操 | 一区二区三区视频在线观看 | 国内久久 | 亚洲精品久久久9婷婷中文字幕 | 香蕉婷婷 | 一级欧美 | 精品国产欧美一区二区三区成人 | av超碰|