Kong 是 Mashape 開源的一款雲原生架構下的分佈式 API 網關,其性能和可擴展性在同類組件中,表現都很優異。Kong 官方提供了不少直接可用的插件,此外,Kong 還能夠經過插件擴展已有功能。nginx
本文的主要內容:git
文章篇幅較長,後半部份內容將會在下一篇文章介紹,敬請關注。sql
本文的標題是:雲原生架構下的 API 網關實踐。首先談談關於雲原生的具體定義,仁者見仁智者見智。docker
Pivotal 是雲原生應用的提出者,並推出了 Pivotal Cloud Foundry 雲原生應用平臺和 Spring 開源 Java 開發框架,成爲雲原生應用架構中先驅者和探路者。Pivotal 公司的 Matt Stine 關於雲原生應用架構的定義,提出來幾個主要特徵:數據庫
隨着技術的發展,雲原生的概念也在不斷的完善。雲原生的定義將來還會變,本文參考 CNCF V1.0 的定義:編程
雲原生技術有利於各組織在公有云、私有云和混合雲等新型動態環境中,構建和運行可彈性擴展的應用。雲原生的表明技術包括容器、服務網格、微服務、不可變基礎設施和聲明式 API。json
所以,雲原生網關很重要的特性之一,就是可以快速集成到持續發佈的雲原生環境中。bootstrap
當使用單體應用程序架構時,客戶端(Web 或移動端)經過向後端應用程序發起一次 REST 調用來獲取數據。負載均衡器將請求路由給 N 個相同的應用程序實例中的一個。而後應用程序會查詢各類數據庫表,並將響應返回給客戶端。微服務架構下,單體應用被切割成多個微服務,若是將全部的微服務直接對外暴露,勢必會出現安全方面的各類問題。後端
客戶端能夠直接向每一個微服務發送請求,其問題主要以下:api
服務端的各個服務直接暴露給客戶端調用勢必會引發各類問題。同時,服務端的各個服務可擴展和伸縮性不好。API 網關是微服務架構中的基礎組件,位於接入層之下和業務服務層之上,如前所述的這些功能適合在 API 網關實現。
關於服務網關的開源組件,有 Netflix Zuul、Spring Cloud Gateway、Kong、Traefik、NGINX 和服務網關類型的 Envoy 等。在以前的文章已經介紹過可編程的新型網關:Spring Cloud Gateway,須要瞭解的讀者能夠查看 Spring Cloud Gateway。 本文主要介紹現代微服務網關 Kong,在 Kong 的官網介紹中,第一條特性即是 Kong 的雲原生屬性:與平臺無關,Kong 能夠從裸機運行到 Kubernetes。本文基於 Kong 1.2.1,自定義插件部分會涉及部分 Lua 編碼,適合服務端開發和運維人員。
Mashape 開源的高性能高可用 API 網關和 API 服務管理層——KONG(基於NGINX)特色尤其突出,它能夠經過插件擴展已有功能,這些插件(使用 lua 編寫)在 API 請求響應循環的生命週期中被執行。與此同時,KONG 自己提供包括HTTP基本認證、密鑰認證、CORS、TCP、UDP、文件日誌、API請求限流、請求轉發及NGINX監控等基本功能。目前,Kong 在 Mashape 管理了超過 15,000 個 API,爲200,000開發者提供了每個月數十億的請求支持。
什麼是 Kong
當咱們決定對應用進行微服務改造時,應用客戶端如何與微服務交互的問題也隨之而來,畢竟服務數量的增長會直接致使部署受權、負載均衡、通訊管理、分析和改變的難度增長。
面對以上問題,API GATEWAY是一個不錯的解決方案,其所提供的訪問限制、安全、流量控制、分析監控、日誌、請求轉發、合成和協議轉換功能,能夠解放開發者去把精力集中在具體邏輯的代碼,而不是把時間花費在考慮如何解決應用和其餘微服務連接的問題上。
爲何使用Kong
在衆多 API GATEWAY 框架中,Mashape 開源的高性能高可用API網關和API服務管理層——KONG(基於 NGINX)特色尤其突出,它能夠經過插件擴展已有功能,這些插件(使用 lua 編寫)在API請求響應循環的生命週期中被執行。於此同時,KONG自己提供包括 HTTP 基本認證、密鑰認證、CORS、TCP、UDP、文件日誌、API請求限流、請求轉發及 NGINX 監控等基本功能。目前,Kong 在 Mashape 管理了超過 15,000 個 API,爲 200,000 開發者提供了每個月數十億的請求支持。
Kong 是 Mashape 開源的高性能高可用 API 網關和 API 服務管理層,一款基於 Nginx_Lua 模塊寫的高可用服務網關,因爲 Kong 是基於 Nginx 的,因此能夠水平擴展多個 Kong 服務器。經過前置的負載均衡配置把請求均勻地分發到各個 Server,來應對大批量的網絡請求。
Kong 主要有三個組件:
Kong 採用插件機制進行功能定製,插件集(能夠是 0 或 N 個)在 API 請求響應循環的生命週期中被執行。插件使用 Lua 編寫,基礎功能包括:HTTP 基本認證、密鑰認證、CORS(Cross-Origin Resource Sharing,跨域資源共享)、TCP、UDP、文件日誌、API 請求限流、請求轉發以及 Nginx 監控等。
Kong 網關具備如下的特性:
Kong 中經常使用的術語介紹,這些術語會在下面的實踐中常常用到。
客戶端的請求將會首先經由微服務網關處理,一些通用的功能切面將會在網關生效,即 Kong 中的插件,以後纔會將請求進行轉發到對應的 Backend 服務,以下圖所示。
目前 Kong 的最新版本 1.2,Kong 的安裝支持多種方式。官方支持以下列出方式的安裝:
除了官方提供的安裝方式,還有社區提供的安裝方式,詳細瞭解參見:konghq.com/install/。
筆者爲了方便,基於 docker 的方式安裝。docker-compose.yml 中定義的鏡像、依賴和參數以下所示:
version: "3.7"
services:
kong:
image: kong:1.1.2
environment:
- "KONG_DATABASE=postgres"
- "KONG_PG_HOST=kong-database"
- "KONG_CASSANDRA_CONTACT_POINTS=kong-database"
- "KONG_PROXY_ACCESS_LOG=/dev/stdout"
- "KONG_ADMIN_ACCESS_LOG=/dev/stdout"
- "KONG_PROXY_ERROR_LOG=/dev/stderr"
- "KONG_ADMIN_ERROR_LOG=/dev/stderr"
- "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl"
ports:
- 8000:8000
- 8443:8443
- 8001:8001
- 8444:8444
networks:
- kong-net
depends_on:
- kong-database
konga:
image: pantsel/konga
environment:
- "TOKEN_SECRET=blueskykong.com"
- "NODE_ENV=production"
ports:
- 8080:1337
networks:
- kong-net
depends_on:
- kong-database
kong-database:
image: postgres:9.6
ports:
- "5432:5432"
environment:
- POSTGRES_USER=kong
- POSTGRES_DB=kong
networks:
- kong-net
volumes:
- /etc/localtime:/etc/localtime:ro
- /data/data/postgresql:/var/lib/postgresql/data
networks:
kong-net:
external: true
複製代碼
如上的 docker-compose.yml 會啓動三個容器服務:Kong、konga 和 kong-database。這三個容器之間的通訊須要增長 network 段,把容器放在同一個網段內,相關連接修改成容器名稱來訪問:
docker network create kong-net
複製代碼
所啓動的三個容器服務,除了 Kong 以外的兩個服務:konga 是 Kong 的 Dashboard,基於 js 的客戶端管理工具,對外暴露的端口爲 8080;kong-database 是 Kong 的數據庫服務,存儲配置信息,這裏使用的是 postgres。須要注意的是,在啓動 Kong 容器以前,須要保持數據庫的 Docker 容器在運行狀態,並執行以下初始化數據庫的操做:
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
kong:latest kong migrations bootstrap
複製代碼
數據庫初始化成功後,再次啓動 docker-compose.yml 服務就能夠了。咱們看到 Kong 映射出多個端口,默認狀況下,Kong 監聽的端口爲:
容器都啓動好以後,咱們來驗證一下:
curl -i http://localhost:8001/
HTTP/1.1 200 OK
Date: Sat, 20 Jul 2019 08:39:08 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/1.1.2
Content-Length: 5785
...
複製代碼
如上的結果,表示安裝正確,能夠正常使用 Kong。訪問 http://localhost:8080 訪問 Konga 的管理界面,第一次登陸使用須要建立管理員賬號和密碼。
更多內容參照官網的安裝文檔。至此,Kong 以及管理工具都已安裝完成,下面將進入 API Gateway 的具體實踐。
如咱們在術語部分的介紹,服務是上游服務的抽象,能夠是一個應用,或者具體某個接口。Kong 提供了管理接口,咱們能夠經過請求 8001 管理接口直接建立,也能夠經過安裝的管理界面,實現的效果是同樣的。
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=aoho-blog' \
--data 'url=http://blueskykong.com/'
複製代碼
咱們建立一個服務名爲 aoho-blog
,指定轉發的地址爲 http://blueskykong.com
。能夠在管理界面中看到以下的記錄:
建立好服務以後,咱們須要建立具體的 API 路由。路由是請求的轉發規則,根據 Hostname 和 PATH,將請求轉發。
curl -i -X POST \
--url http://localhost:8001/services/aoho-blog/routes \
--data 'hosts[]=blueskykong.com' \
--data 'paths[]=/api/blog'
複製代碼
如上在 aoho-blog 中建立了一個訪問 /api/blog 的路由,在管理界面能夠看到相應的記錄:
建立好路由以後,咱們就能夠訪問 /api/blog。
Kong 默認經過 8000 端口處理代理的請求。成功的響應意味着 Kong 將 http://localhost:8000
的請求轉發到配置的 URL,並將響應轉發給咱們。須要注意的是,若是 API 暴露的地址與前面 Host 定義的地址(blueskykong.com)不一致,就須要在請求的 Headers 裏面加入 Header,Kong 根據上面請求中定義的 Header:Host,執行此操做。
本文主要介紹了雲原生和雲原生網關的相關概念,隨後具體介紹了本文的主角 Kong 的特性和基本架構。重點介紹瞭如何使用 Kong 構建服務網關。Kong 官方和社區提供了不少插件,關於 Kong 中的經常使用插件使用,以及如何定製本身的 Kong 插件,將會在下文講解。