API 網關作為客戶端訪問后端的入口,已經存在很長時間了,它主要是用來管理” 南北向 “的流量;近幾年服務網格開始流行,它主要是管理系統內部,即 “東西向” 流量,而像 Istio 這樣的服務網格還內置了網關,從而將系統內外部的流量納入了統一管控。這經常給初次接觸 Istio 的人帶來困惑 —— 服務網格與 API 網關之間是什么關系?是不是使用了 Istio 就可以替代了 API 網關?Istio 的 API 網關是如何運作的?有哪些方式暴露 Istio mesh 中的服務?這篇文章給為你解答。
主要觀點
服務網格誕生的初衷是為了解決分布式應用的內部流量的管理問題,而在此之前 API 網關已存在很久了。
雖然 Istio 中內置了 Gateway,但是你仍可以使用自定義的 Ingress Controller來代理外部流量
API 網關和服務網格正朝着融合的方向發展
如何暴露Istio mesh 中的服務?
下圖展示了使用 Istio Gateway、Kubernetes Ingress、API Gateway 及 NodePort/LB 暴露 Istio mesh 中服務的四種方式。
其中陰影表示的是 Istio mesh,mesh 中的的流量屬於集群內部(東西向)流量,而客戶端訪問 Kubernetes 集群內服務的流量屬於外部(南北向)流量。不過因為 Ingress、Gateway 也是部署在 Kubernetes 集群內的,這些節點訪問集群內其他服務的流量就難以歸屬了。
方式 | 控制器 | 功能 |
NodePort/LoadBalancer | Kubernetes | 負載均衡 |
Kubernetes Ingress | Ingress Controller | 負載均衡、TLS、虛擬主機、流量路由 |
Istio Gateway | Istio | 負載均衡、TLS、虛擬主機、高級流量路由、其他 Istio 的高級功能 |
API 網關 | API Gateway | 負載均衡、TLS、虛擬主機、流量路由、API 生命周期管理、權限認證、數據聚合、賬單和速率限制 |
由於 NodePort/LoadBalancer 是 Kubernetes 內置的基本的暴露服務的方式,本文就不討論這種方式了。下文將對其他三種方式分別作出說明。
使用kubernetes ingress暴露服務
我們都知道 Kubernetes 集群的客戶端是無法直接訪問 Pod 的 IP 地址的,因為 Pod 是處於 Kubernetes 內置的一個網絡平面中。我們可以將 Kubernetes 內的服務使用 NodePort 或者 LoadBlancer 的方式暴露到集群以外。同時為了支持虛擬主機、隱藏和節省 IP 地址,可以使用 Ingress[1] 來暴露 Kubernetes 中的服務。Kubernetes Ingress 原理如下圖所示。
簡單的說,Ingress 就是從 Kubernetes 集群外訪問集群的入口,將用戶的 URL 請求轉發到不同的服務上。Ingress 相當於 Nginx、Apache 等負載均衡方向代理服務器,其中還包括規則定義,即 URL 的路由信息,路由信息得的刷新由 Ingress controller[2] 來提供。
apiVersion: networking.k8s.io/v1beta1 kind: Ingress metadata: annotations: kubernetes.io/ingress.class: istio name: ingress spec: rules: - host: httpbin.example.com http: paths: - path: /status/* backend: serviceName: httpbin servicePort: 8000
上面的例子中的 kubernetes.io/ingress.class: istio
注解表明該 Ingress 使用的 Istio Ingress Controller。
使用istio gateway暴露服務
我們都知道 Istio 是繼承 Kubernetes 之后發展出來的一個流行的服務網格實現,它實現了 Kubernetes 沒有的一些功能,請參考什么是 Istio?為什么 Kubernetes 需要 Istio?[3] 簡要來說,正是因為 Istio 補足了 Kubernetes 對於雲原生應用的流量管理、可觀察性和安全方面的短板,使得流量管理變得對應用程序透明,使這部分功能從應用程序中轉移到了平台層,成為了雲原生基礎設施。
Istio 0.8 以前版本中使用 Kubernetes Ingress[4] 來作為流量入口,其中使用 Envoy 作為 Ingress Controller。在 Istio 0.8 及以后的版本中,Istio 創建了 Gateway 對象。Gateway 和 VirtualService 用於表示 Istio Ingress 的配置模型,Istio Ingress 的缺省實現則采用了和 sidecar 相同的 Envoy 代理。通過該方式,Istio 控制面用一致的配置模型同時控制了入口網關和內部的 sidecar 代理。這些配置包括路由規則,策略檢查、遙測收集以及其他服務管控功能。
Istio Gateway 的功能與 Kubernetes Ingress 類似,它負責進出集群的南北流量。Istio Gateway 描述了一個負載均衡器,用於承載進出服務網格邊緣的連接。該規范描述了一組開放端口和這些端口所使用的協議,以及用於負載均衡的 SNI 配置等。
Istio Gateway 資源本身只能配置 L4 到 L6 的功能,例如暴露的端口、TLS 設置等;但 Gateway 可與 VirtualService 綁定,在 VirtualService 中可以配置七層路由規則,例如按比例和版本的流量路由,故障注入,HTTP 重定向,HTTP 重寫等所有 Mesh 內部支持的路由規則。
下面是一個 Gateway 與 VirtualService 綁定的示例。擁有 istio: ingressgateway
標簽的 pod 將作為 Ingress Gateway 並路由對 httpbin.example.com
虛擬主機的 80 端口的 HTTP 訪問,這相當於給 Kubernetes 敞開了一個外部訪問的入口。這與使用 Kubernetes Ingress 最大的區別就是,需要我們手動將 VirtualService 與 Gateway 綁定,並指定 Gateway 所在的 pod。
apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: httpbin-gateway spec: selector: istio: ingressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - "httpbin.example.com"
下面這個 VirtualService 通過 gateways
與上面的網關綁定在了一起,以接受來自該網關的流量。
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: httpbin spec: hosts: - "httpbin.example.com" gateways: - httpbin-gateway http: - match: - uri: prefix: /status route: - destination: port: number: 8000 host: httpbin
使用api網關暴露服務
API 網關是位於客戶端和后端服務之間的 API 管理工具,一種將客戶端接口與后端實現分離的方式,在微服務中得到了廣泛的應用。當客戶端發出請求時,API 網關會將其分解為多個請求,然后將它們路由到正確的位置,生成響應,並跟蹤所有內容。
API Gateway 是微服務架構體系中的一類型特殊服務,它是所有微服務的入口,它的職責是執行路由請求、協議轉換、聚合數據、認證、限流、熔斷等。大多數企業 API 都是通過 API 網關部署的。API 網關通常會處理跨 API 服務系統的常見任務,例如用戶身份驗證、速率限制和統計信息。
在網格中可以有一個或多個 API Gateway。API 網關的職責有:
- 請求路由和版本控制
- 方便單體應用到微服務的過渡
- 權限認證
- 數據聚合:監控和計費
- 協議轉換
- 消息和緩存
- 安全和報警
以上很多基本功能比如路由和權限認證通過 Istio Gateway 也可以實現,只是在功能的豐富度和擴展性方面有些成熟的 API Gateway 可能更占優勢,不過在 Istio mesh 中再引入 API Gateway 也可能帶來一些弊端。
- 引入了 API Gateway,需要考慮 API Gateway 本身的部署、運維、負載均衡等場景,增加了后端服務的復雜度
- API Gateway中承載了大量的接口適配,導致難以維護
- 對於部分場景,增加了一跳可能導致性能的降低
參考
https://mp.weixin.qq.com/s/Dt4ge1H4JXhHS91vRMBUWA