雲原生架構下的 API 網關實踐: Kong (二)

Kong 是 Mashape 開源的一款雲原生架構下的分佈式 API 網關,其性能和可擴展性在同類組件中,表現都很優異。Kong 官方提供了不少直接可用的插件,此外,Kong 還能夠經過插件擴展已有功能。nginx

本文的主要內容:git

  • 什麼是雲原生網關?
  • Kong 介紹
  • Kong 的基本架構
  • 使用 Kong 構建服務網關
  • 幾種經常使用插件應用
  • 自定義插件的實踐

文章篇幅較長,後半部份內容將會在下一篇文章介紹,敬請關注。sql

什麼是雲原生網關

什麼是雲原生

本文的標題是:雲原生架構下的 API 網關實踐。首先談談關於雲原生的具體定義,仁者見仁智者見智。docker

Pivotal 是雲原生應用的提出者,並推出了 Pivotal Cloud Foundry 雲原生應用平臺和 Spring 開源 Java 開發框架,成爲雲原生應用架構中先驅者和探路者。Pivotal 公司的 Matt Stine 關於雲原生應用架構的定義,提出來幾個主要特徵:數據庫

  • 符合12因素應用
  • 面向微服務架構
  • 自服務敏捷架構
  • 基於API的協做
  • 抗脆弱性

隨着技術的發展,雲原生的概念也在不斷的完善。雲原生的定義將來還會變,本文參考 CNCF V1.0 的定義:編程

雲原生技術有利於各組織在公有云、私有云和混合雲等新型動態環境中,構建和運行可彈性擴展的應用。雲原生的表明技術包括容器、服務網格、微服務、不可變基礎設施和聲明式 API。json

所以,雲原生網關很重要的特性之一,就是可以快速集成到持續發佈的雲原生環境中。bootstrap

爲何須要 API 網關?

當使用單體應用程序架構時,客戶端(Web 或移動端)經過向後端應用程序發起一次 REST 調用來獲取數據。負載均衡器將請求路由給 N 個相同的應用程序實例中的一個。而後應用程序會查詢各類數據庫表,並將響應返回給客戶端。微服務架構下,單體應用被切割成多個微服務,若是將全部的微服務直接對外暴露,勢必會出現安全方面的各類問題。後端

客戶端能夠直接向每一個微服務發送請求,其問題主要以下:api

  • 客戶端需求和每一個微服務暴露的細粒度 API 不匹配。
  • 部分服務使用的協議不是Web友好協議。可能使用 Thrift 二進制 RPC,也可能使用 AMQP 消息傳遞協議。
  • 微服務難以重構。若是合併兩個服務,或者將一個服務拆分紅兩個或更多服務,這類重構就很是困難了。

服務端的各個服務直接暴露給客戶端調用勢必會引發各類問題。同時,服務端的各個服務可擴展和伸縮性不好。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 編碼,適合服務端開發和運維人員。

Kong 介紹

Mashape 開源的高性能高可用 API 網關和 API 服務管理層——KONG(基於NGINX)特色尤其突出,它能夠經過插件擴展已有功能,這些插件(使用 lua 編寫)在 API 請求響應循環的生命週期中被執行。與此同時,KONG 自己提供包括HTTP基本認證、密鑰認證、CORS、TCP、UDP、文件日誌、API請求限流、請求轉發及NGINX監控等基本功能。目前,Kong 在 Mashape 管理了超過 15,000 個 API,爲200,000開發者提供了每個月數十億的請求支持。

  1. 什麼是 Kong
    當咱們決定對應用進行微服務改造時,應用客戶端如何與微服務交互的問題也隨之而來,畢竟服務數量的增長會直接致使部署受權、負載均衡、通訊管理、分析和改變的難度增長。

    面對以上問題,API GATEWAY是一個不錯的解決方案,其所提供的訪問限制、安全、流量控制、分析監控、日誌、請求轉發、合成和協議轉換功能,能夠解放開發者去把精力集中在具體邏輯的代碼,而不是把時間花費在考慮如何解決應用和其餘微服務連接的問題上。

  2. 爲何使用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 的基本架構

Kong 是 Mashape 開源的高性能高可用 API 網關和 API 服務管理層,一款基於 Nginx_Lua 模塊寫的高可用服務網關,因爲 Kong 是基於 Nginx 的,因此能夠水平擴展多個 Kong 服務器。經過前置的負載均衡配置把請求均勻地分發到各個 Server,來應對大批量的網絡請求。

圖片來源 Kong 官網
圖片來源 Kong 官網

Kong 主要有三個組件:

  • Kong Server :基於nginx的服務器,用來接收 API 請求。
  • Apache Cassandra/PostgreSQL:用來存儲操做數據。
  • Kong dashboard:官方推薦 UI 管理工具,固然,也可使用 restfull 方式管理 admin api。

Kong 採用插件機制進行功能定製,插件集(能夠是 0 或 N 個)在 API 請求響應循環的生命週期中被執行。插件使用 Lua 編寫,基礎功能包括:HTTP 基本認證、密鑰認證、CORS(Cross-Origin Resource Sharing,跨域資源共享)、TCP、UDP、文件日誌、API 請求限流、請求轉發以及 Nginx 監控等。

Kong 網關具備如下的特性:

  • 可擴展性: 經過簡單地添加更多的服務器,能夠輕鬆地進行橫向擴展,這意味着您的平臺能夠在一個較低負載的狀況下處理任何請求;
  • 模塊化: 能夠經過添加新的插件進行擴展,這些插件能夠經過RESTful Admin API輕鬆配置;
  • 在任何基礎架構上運行: Kong 網關能夠在任何地方都能運行。能夠在雲或內部網絡環境中部署 Kong,包括單個或多個數據中心設置,以及 public,private 或 invite-only APIs。

術語

Kong 中經常使用的術語介紹,這些術語會在下面的實踐中常常用到。

  • Route:請求的轉發規則,按照 Hostname 和 PATH,將請求轉發給 Service;
  • Services:多個 Upstream 的集合,是 Route 的轉發目標;
  • Consumer:API 的用戶,記錄用戶信息;
  • Plugin:插件,能夠是全局的,也能夠綁定到 Service、Router 或者 Consumer;
  • Certificate:https 配置的證書;
  • Sni:域名與 Certificate 的綁定,指定了一個域名對應的 https 證書;
  • Upstream:上游對象用來表示虛擬主機名,擁有多個服務(目標)時,會對請求進行負載均衡;
  • Target:最終處理請求的 Backend 服務。

使用 Kong 構建服務網關

客戶端的請求將會首先經由微服務網關處理,一些通用的功能切面將會在網關生效,即 Kong 中的插件,以後纔會將請求進行轉發到對應的 Backend 服務,以下圖所示。

圖片來源 https://konghq.com/blog/kong-1-0-ga/
圖片來源 https://konghq.com/blog/kong-1-0-ga/
在介紹了爲何須要微服務網關和 Kong 的相關概念以後,咱們將會進行實戰,使用 Kong 構建網關。

安裝實踐

目前 Kong 的最新版本 1.2,Kong 的安裝支持多種方式。官方支持以下列出方式的安裝:

圖片來源 Kong 官網
圖片來源 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 監聽的端口爲:

  • 8000:此端口是 Kong 用來監聽來自客戶端傳入的 HTTP 請求,並將此請求轉發到上有服務器;(Kong 根據配置的規則轉發到真實的後臺服務地址)
  • 8443:此端口是 Kong 用來監聽來自客戶端傳入的HTTPS請求的。它跟8000端口的功能相似,轉發 HTTPS 請求的。能夠經過修改配置文件來禁止它;
  • 8001:Admin API,經過此端口,管理者能夠對 Kong 的監聽服務進行配置,插件設置、API 的增刪改查、以及負載均衡等一系列的配置都是經過 8001 端口進行管理;
  • 8444:經過此端口,管理者能夠對 HTTPS 請求進行監控。

容器都啓動好以後,咱們來驗證一下:

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。能夠在管理界面中看到以下的記錄:

其中的一些參數,如 Retries、Connect timeout、Write/Read timeout 等參數。

建立路由

建立好服務以後,咱們須要建立具體的 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 插件,將會在下文講解。

推薦閱讀

雲原生架構下的 API 網關實踐

訂閱最新文章,歡迎關注個人公衆號

微信公衆號
相關文章
相關標籤/搜索