Kong mesh深度分析報告

做者:單家駿

Kong是一個基於OpenResty (Nginx) 封裝的微服務中間件產品,在微服務架構體系中,做爲API網關以及API中間件(kubernetes ingress)提供服務。因爲其天生具有Nginx的高性能、nginx-lua插件的可定製性,再加上完善的社區以及齊全的文檔,在中小企業用戶羣很是受歡迎,擁有較好的羣衆基礎。nginx

2018年8月,kong發佈了1.0 GA版本,正式宣佈其支持service mesh,並提供社區版以及企業版2個版本。下面咱們從Demo、配置、功能這3方面,對kong mesh進行體驗及分析。git

Demo體驗

Kong社區提供了kong mesh的demo (github.com/Kong/kong-m…),該demo是實現的是tcp四層透明代理轉發業務。github

該demo主要作的事情是:提供兩個服務servicea以及serviceb,serviceb做爲服務端,經過ncat監聽8080端口,接受外部的TCP消息;servicea做爲client端,經過ncat將當前server的時間發往serviceb。Demo的運行效果以下:web

在客戶端節點,每隔兩秒會發送一次時間戳到服務端。數據庫

服務端節點,每隔兩秒打印一次時間戳。api

接下來,咱們詳細瞭解一下該demo背後的技術原理。緩存

首先,咱們來分析一下kong-mesh業務總體組網:安全

從組網中能夠看出,kong mesh也分控制面與數據面。bash

控制面爲圖中kong-admin的POD,3副本實例獨立部署,對外提供Admin API供用戶設置各類規則配置。websocket

數據面爲圖中servicea及serviceb的POD,每一個POD中會啓動一個kong容器做爲sidecar,經過iptables規則將外發以及到達的流量劫持到kong容器中,而後kong會根據路由規則將流量轉發到對應的實例。下面咱們看看POD的部署配置:

部署配置關鍵點在於流量接管的設置,POD在啓動應用前,會使用istio/proxy_init鏡像來初始化環境,圖中的參數的含義是,使用TProxy(透明代理)的流量接管模式,將發往8080端口(業務serviceb監聽端口)的流量經過7000端口(kong監聽端口)來進行代理。

瞭解清楚該部署配置後,咱們就能夠比較容易地使用kong來代理http服務了。主要改動點仍是在於POD的部署配置的修改。以下圖所示:

值得注意的是,代理HTTP服務和代替TCP不同,屬於7層轉發,不能使用上文的透明代理方式來進行接管。所以在setup_network的啓動參數中,須要指定流量接管模式爲REDIRECT,經過iptables顯式將報文導入到kong,kong再根據報文內容進行匹配後,再路由到目標服務(你們若是須要http demo的代碼,能夠到github.com/andrewshan/…下載)。

那麼,kong又是根據什麼規則去路由的呢?下面咱們會繼續體驗kong mesh的配置規則。

配置分析

kong mesh的配置集中存儲在DB中,當前僅支持Postgre以及cassandra。控制面kong-admin會把配置規則寫入到DB中,數據面的Kong會按期從數據庫讀取配置規則並更新緩存。

在demo中,咱們經過k8s Job向kong-admin寫入了兩條數據:

http --ignore-stdin put kong-admin:8001/services/service-b host=serviceb port=8080 protocol=tcp -f  
 http --ignore-stdin post kong-admin:8001/services/service-b/routes name=service-b sources[1].ip=0.0.0.0/0 protocols=tcp -f 複製代碼

第一條語句是添加一個名字叫service-b的服務;

第二條語句是爲service-b的服務添加路由規則,容許源ip在0.0.0.0/0網段的tcp包能夠轉發到service-b。

規則添加後,分別在services和routes表中能夠查詢到相關的記錄:

那麼問題來了,kong的規則模型具體是什麼含義?這些規則是怎麼組合工做的呢? 首先,咱們先看看kong的規則模型:

從圖上可見,Service是規則模型的核心,一個Service表明一個目標服務URL。

Route表明的是Service的細粒度路由規則,定義了根據不一樣的客戶端請求屬性來選擇目標端Service,一個Service可關聯多個Route規則。可類比istio中的VirtualService。

Upstream定義的是針對具體的目標Service,所採起的負載均衡策略,以及健康檢查相關配置,一個Service可關聯0-1個Upstream。可類比istio中的DestinationRule。

Target定義的是具體的服務節點實例,可定義權重,一個target關聯一個upstream。 具體的詳細規則描述,可參考kong的官方文檔:docs.konghq.com/?_ga=2.4432…

在k8s環境下部署,若是直接使用k8s平臺所提供的kube-dns的域名解析能力以及ClusterIP/NodePort的負載均衡的話,那麼原則上只須要配置Service以及Route規則就能夠進行工做。Upstream和Target屬於可選配置。

咱們繼續看看,kong-mesh自己如何根據這些規則進行路由。

Kong的路由及負載均衡能力是構建於openresty的access_by_lua以及balancer_by_lua這2個phase之上的。Servicea發送的請求經過iptables將流量導入到客戶端側(servicea-kong),kong收到後,根據請求消息進行route_match,找出匹配的目標service,而後再根據service的可用target進行負載均衡,找到目標serviceb節點實例進行發送。

服務端serviceb-kong收到請求後,因爲啓動前經過環境變量配置好了本地路由規則:

env:
   - name: KONG_ORIGINS
     value: "tcp://serviceb:8080=tcp://127.0.0.1:8080"複製代碼

根據該規則,kong直接把target爲serviceb:8080的請求直接投遞給serviceb。最終完成整個請求路由過程。

接下來,咱們再看看,kong基於上述的配置模型,能夠提供什麼樣的功能,以及與其餘mesh產品的差別點。

功能對比

下表將kong mesh (community)與當下熱門的istio+envoy組合進行功能比較,你們能夠了解一下相關的差別(相關數據來源於kong官網)

功能點 kong-mesh (community) istio + envoy 分析
服務發現 經過admin api添加服務,並只能發現經過api添加的服務 支持對接k8s, consul等註冊中心進行服務發現 從平臺獨立性來看,kong mesh佔優; 從服務接管易用性來看,istio佔優
服務協議 支持http, http2, websocket, stream 支持http, http2, grpc, websocket, stream istio+envoy佔優
服務路由 支持根據源、目標地址,method、host、path、protocol等細粒度的路由 支持除左側列舉的全部能力外,還支持按header以及subset(標籤)的路由 istio+envoy佔優
負載均衡 支持輪詢、權重、一致性hash的負載均衡模式 支持除左側列舉的全部負載均衡模式外,還支持隨機、最低負載等模式 istio+envoy佔優
健康檢查 支持主動健康檢查以及被動健康檢查(熔斷) 支持主動健康檢查以及被動健康檢查(熔斷) 基本對等
安全 支持Certificate證書管理,支持JWT+TLS加密傳輸 支持證書下發及更新,JWT+mTLS加密傳輸 基本對等
多用戶 支持按consumer受權 支持RBAC用戶-角色受權 istio+envoy佔優
故障注入 不支持 支持 istio+envoy佔優
監控統計 繼承nginx的統計能力,支持按請求、鏈接、健康狀態等維度的統計 支持更細粒度的好比按協議、Zone的統計 istio+envoy佔優
可擴展性 背靠openresty,提供強大的自定義插件能力,使用lua進行開發 提供lua插件開發能力,但能力比較基礎 kong mesh佔優
學習曲線 kong自身提供控制面和數據面能力,組網簡單,純lua語言上手較輕鬆 istio+envoy一塊兒至少4個組件,跨兩種語言,上手較難 kong mesh佔優

整體上來看,kong mesh相對istio+envoy在功能知足度上略佔劣勢,不過勝在簡單、可擴展性強,社區活躍度高(stars稍多於istio),將來結合社區將功能補齊也不是難事。

總結

Kong做爲一個從API網關演變而來的service mesh產品,背靠成熟的OpenResty,擁有不輸istio+envoy的功能知足度、且社區活躍,版本更新較快(平均2週一個release),比較適合中小型團隊以及之前kong的老用戶試水service mesh。

相關文章
相關標籤/搜索