iT邦幫忙

2026 iThome 鐵人賽

DAY 21
0
Kubernetes

初見 Kubernetes - 純網站後端開發踏入 K8s 世界的經驗分享系列 第 21 篇

Day 21 - Istio 入口,接手原本應用 Gateway 的路由

  • 分享至 

  • xImage
  •  

Day 19 的流量由 Traefik Ingress 進入 api-gateway,再轉送到兩個 API。

今天將換成 Istio 入口,讓 Istio IngressGateway 接收 request,並透過 Gateway 宣告可接收的 host 與 port,再由 VirtualService 將路徑直接導向各服務的 ClusterIP Service。

確認新路徑可用後,先前建立的應用程式 api-gateway 這個 Pod 服務就可以移除掉,讓整個下游微服務 API 都交由 Istio 來處理,也就是所謂的 Istio Service Mesh。

會這樣切換,是因為我在實務專案經驗中,想把兩種入口分開管:業務 API 和站台交給 Istio IngressGateway 接收,再用 VirtualService 管路由

而像是 Prometheus 這類監控、基礎叢集設施服務,則留在原本的 Ingress 入口。

這樣之後要調整 API 路由、發布版本,或處理監控入口的問題,就能各自查各自的設定,不會全部混在一起。

Istio 業務入口的請求與路由設定

這邊要先說明清楚三件事情:

  • api-gateway 是我們先前部署的應用
  • Istio IngressGateway 是實際接收入口流量的服務
  • Gateway 是宣告叢集入口的 K8s 資源

以下用一份 VirtualService 處理原本 Gateway 的兩條 API 路由,也讓入口的 / 能找到 Portal。

路由由上往下比對,是有順序性的,較明確的 API 路徑要放在 / 前面,否則如果將 / 擺在最前面,那就會讓所有 Request 都符合該規則,而全部都導向到 /:

apiVersion: networking.istio.io/v1
kind: Gateway
metadata:
  name: demo-gateway
  namespace: team-a
spec:
  selector:
    istio: ingressgateway
  servers:
    - port:
        number: 80
        name: http
        protocol: HTTP
      hosts:
        - demo.example.internal
---
apiVersion: networking.istio.io/v1
kind: VirtualService
metadata:
  name: app-routes
  namespace: team-a
spec:
  hosts:
    - demo.example.internal
  gateways:
    - demo-gateway
  http:
    - match:
        - uri:
            prefix: /api/a
      route:
        - destination:
            host: api-a.team-a.svc.cluster.local
            port:
              number: 80
    - match:
        - uri:
            prefix: /api/b
      route:
        - destination:
            host: api-b.team-a.svc.cluster.local
            port:
              number: 80
    - match:
        - uri:
            prefix: /
      route:
        - destination:
            host: portal-web.team-a.svc.cluster.local
            port:
              number: 80

上面這份 YAML 是看網址的開頭(prefix)來決定要送去哪個服務。

VirtualService 也可以用 exact 指定完整路徑,或用 regex 比對符合某種規則的路徑;需要的話,還能看 HTTP method、header 或 query parameter。

它也能在轉送前用 rewrite 改掉後端收到的網址。假設外面打的是 /api/a/health,但 api-a 只認得 /health,就可以把比對用的前綴設成 /api/a/,再用 rewrite 把這段換成 /。

目前這份 YAML 沒有設定 rewrite,所以後端收到的還是原本的路徑。要不要改寫,得看後端 API 實際接受什麼路徑,基本上就是看需求啦。

從 Gateway Pod 切換到 Istio IngressGateway 時,先確認 Istio IngressGateway 本身的服務 Pod 已經 Ready、入口可連線,並從入口逐一測試 Portal、/api/a、/api/b 的回應是否如預期。

再檢查 VirtualService 的 host/path、各 Service 的 EndpointSlice 與後端 log,確認原本由應用 Gateway 承擔的路由與必要行為都已有替代方式後,才移除舊的資源:

kubectl -n team-a delete deployment api-gateway
kubectl -n team-a delete service api-gateway

應用 Gateway 如果還處理 authentication、header、timeout 或錯誤回應,也要逐項盤點並驗證承接方式,避免改用 Istio 後反而讓某些功能異常了。

參考資料


上一篇
Day 20 - Requests、Limits 與 HPA
下一篇
Day 22 - Canary 金絲雀部署與 Blue-Green 藍綠部署
系列文
初見 Kubernetes - 純網站後端開發踏入 K8s 世界的經驗分享 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言