1、概述
API 網關作為客戶端訪問后端的入口,已經存在很長時間了,它主要是用來管理”南北向“的流量;近幾年服務網格開始流行,它主要是管理系統內部,即“東西向”流量,而像 Istio 這樣的服務網格還內置了網關,從而將系統內外部的流量納入了統一管控。這經常給初次接觸 Istio 的人帶來困惑——服務網格與 API 網關之間是什么關系?是不是使用了 Istio 就可以替代了 API 網關?Istio 的 API 網關是如何運作的?有哪些方式暴露 Istio mesh 中的服務?這篇文章給為你解答。
2、主要觀點
- 服務網格誕生的初衷是為了解決分布式應用的內部流量的管理問題,而在此之前 API 網關已存在很久了。
- 雖然 Istio 中內置了Gateway,但是你仍可以使用自定義的 Ingress Controller 來代理外部流量。
- API 網關和服務網格正朝着融合的方向發展。
3、如何暴露 Istio mesh 中的服務?
下圖展示了使用 Istio Gateway、Kubernetes Ingress、API Gateway 及 NodePort/LB 暴露 Istio mesh 中服務的四種方式。
其中陰影表示的是 Istio mesh,mesh 中的的流量屬於集群內部(東西向)流量,而客戶端訪問 Kubernetes 集群內服務的流量屬於外部(南北向)流量。不過因為 Ingress Controller、Istio Gateway 也是部署在 Kubernetes 集群內的,這些節點訪問集群內其他服務的流量可以認為是內部間的訪問(東西向)。
方式 | 控制器 | 功能 |
---|---|---|
NodePort/LoadBalancer | Kubernetes | 負載均衡 |
Kubernetes Ingress | Ingress Controller | 負載均衡、TLS、虛擬主機、流量路由 |
Istio Gateway | Istio | 負載均衡、TLS、虛擬主機、高級流量路由、其他 Istio 的高級功能 |
API 網關 | API Gateway | 負載均衡、TLS、虛擬主機、流量路由、API 生命周期管理、權限認證、數據聚合、賬單和速率限制 |
以上4種方式方式都可以作為客戶端訪問Kubernetes集群內部服務的入口,其中Istio Gateway、Kubernetes Ingress、API網關都是以Pod形式部署在Kubernetes集群內部的,這三種方式訪問集群內其他服務的流量都是內部間的訪問。Istio Gateway與Kubernetes Ingress相比,Istio Gateway提供了更廣泛的自定義和靈活性,並允許將 Istio 功能(例如監控和路由規則)應用於進入集群的流量,Istio官方文檔建議使用Istio Gateway而不是 Ingress 來利用 Istio 提供的完整功能集;API網關一般都是以微服務的形式部署在Kubernetes集群內部作為客戶端訪問的入口,這個沒什么好講的一般都是使用開源的方案作為API網關例如Zuul;NodePort/LoadBalancer 是 Kubernetes 內置的基本的暴露服務的方式,一般測試使用。
由於目前我們生產環境一直都是使用Nginx Ingress Controller作為客戶端訪問Kubernetes集群內部服務的入口方式,並且沒有使用到Istio Gateway的特有功能(API 生命周期管理、權限認證、數據聚合、賬單和速率限制),所以本文只會介紹如何使用Nginx Ingress Controller暴露 Istio mesh 中的服務。
4、使用Kubernetes Ingress暴露服務
我們都知道 Kubernetes 集群的客戶端是無法直接訪問 Pod 的 IP 地址的,因為 Pod 是處於 Kubernetes 內置的一個網絡平面中。我們可以將 Kubernetes 內的服務使用 NodePort 或者 LoadBlancer 的方式暴露到集群以外。同時為了支持虛擬主機、隱藏和節省 IP 地址,可以使用 Ingress 來暴露 Kubernetes 中的服務。Kubernetes Ingress 原理如下圖所示。
簡單的說,Ingress 就是從 Kubernetes 集群外訪問集群的入口,將用戶的 URL 請求轉發到不同的服務上。Ingress 相當於 Nginx、Apache 等負載均衡方向代理服務器,其中還包括規則定義,即 URL 的路由信息,路由信息得的刷新由 Ingress controller來提供。
4.1 使用 Nginx Ingress Controller 作為 Istio 網格入口
1、首先需要給Nginx Ingress Controller所在的Pod進行Sidecar注入,這樣Nginx Ingress Controller就可以和Kubernetes集群內其他注入Sidecar的服務進行流量治理。(SideCar注入本文不再講解,詳解見Istio1.12.1 Sidecar注入配置 )
nginx.ingress.kubernetes.io/service-upstream: 'true' nginx.ingress.kubernetes.io/upstream-vhost: <服務名>.<命名空間>.svc.cluster.local
下面解釋寫這兩個注解的含義:
注解 | 類型/選項 | 功能描述 |
---|---|---|
nginx.ingress.kubernetes.io/service-upstream | true 或 false | 默認 Nginx 以 Service 中 Pod 的 IP 和端口為 Upstream 中的成員列表,該參數為 true 時,將以 Service 的 ClusterIP 和端口為被代理入口,該功能避免了因 Pod 漂移帶來的 Upstream 的配置變化。 |
nginx.ingress.kubernetes.io/upstream-vhost |
string | 自定義發送到上游服務器的信息頭字段中 Host 的內容,相當於 Nginx 配置指令 proxy_set_header Host $host 的設置,
Host 包含客戶端訪問的真實的域名和端口號。假設參數值為my-service.default.svc.cluster.local,相當於用此值覆蓋了客戶端真實訪問的的域名。
|
參考:https://jimmysong.io/blog/istio-servicemesh-api-gateway/
參考:https://preliminary.istio.io/latest/zh/docs/tasks/traffic-management/ingress/kubernetes-ingress/