45 張圖帶你從 0 玩轉 Kong Gateway

Kong Gateway 解決了什麼問題?

看上圖,常見的我們的服務之間通過 rpc 相互調用。

如上圖的左部分,在沒有引入網關之前,爲了保障交互的安全,每個服務都需要自己實現一套權限校驗(Auth)、日誌、限流、監控等方案。這樣就不太好,各種成本很高。

引入網關之後呢,像鑑權、監控、安全、限流、日誌、緩存等等方案都可以統一由網關實現。各個服務只需要專注於自己的業務實現就 OK。

Kong Gateway 都有哪些模塊?

搞清楚下面的這四點 OK:

一、上圖中的最下面的兩層是:Nginx、Openretry,它的意思是:kong 是一款基於 OpenRetry(Nginx + Lua) 編寫的高可用、易擴展的 API Gateway。其實我感覺你可以直接把 Kong 理解成是 Nginx,但是 Kong 的功能不止於 Nginx。

二、上圖中間部分的 Datastore 的意思是:kong 的配置文件可以支持化的存儲在 NoSQL 中,可選:cassandra、postgreSQL。

三、上圖中的 plugin 的意思是:如果想拓展 kong 的功能,只需要提供對應的插件就行。有一些現成的插件可以直接用,可以自定義插件。

四、上圖中最上層的 Restful 的意思是:它支持通過 Restful API 的方式來操作操作和配置 Kong(管理 nginx 的配置文件)。而且 kong 有專屬的 dashboard,支持在可視化的界面下和 Restful API 交互,實現對 kong 的可視化配置。

安裝 Kong

官網 doc:https://docs.konghq.com/enterprise/1.5.x/deployment/installation/docker/

選擇安裝 1.5.X 版本的 kong,因爲 kong dashboard 對高版本的 kong 還不支持

Step1:下載鏡像

docker pull kong:1.5.0-alpine

Step2:給 image 打 tag

~]# docker images
REPOSITORY   TAG            IMAGE ID       CREATED         SIZE
kong         1.5.0-alpine   a79fdd990557   22 months ago   129MB
~]# docker tag a79fdd990557 kong-oss

Step3:創建一個專屬的網絡空間,kong 及其相關的容器均加入到這個網絡中,方便容器間的相互發現和互通

docker network create kong-ee-net

Step4:創建 volume,用於將容器的目錄掛載到宿主上,防止容器被刪後,數據丟失。

docker volume create kong-volume

Step5:啓動 kong 依賴的 db 容器:運行 postgresql 數據庫

  docker run -d --name kong-ee-database \
  --network=kong-ee-net \
  -p 5432:5432 \
  -v kong-volume:/var/lib/postgresql/data \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_DB=kong" \
  -e "POSTGRES_PASSWORD=kong" \
  postgres:9.6

此時可以使用 navicate 嘗試連接一下 postgresql 數據庫,是可以聯通的

Step6:初始化 kong 需要的數據庫

docker run --rm --network=kong-ee-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-ee-database" \
  -e "KONG_PG_PASSWORD=kong" \
  -e "KONG_PASSWORD=kong" \
  kong-oss kong migrations bootstrap

驗收結果

Step7:啓動 Kong 網關

docker run -d --name kong \
  --network=kong-ee-net \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=kong-ee-database" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kong" \
  -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
  -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
  -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
  -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
  -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
  -p 8000:8000 \
  -p 8443:8443 \
  -p 8001:8001 \
  -p 8444:8444 \
  kong-oss:latest

備註:

1、KONG_PG_HOST 和 KONG_PG_USER 的值在 Step6 中可以找到

2、最後的 kong-oss:latest,是 kong 的鏡像

3、network 是 Step3 中創建的網絡空間

啓動成功,驗收:

因爲我設置的啓動參數是:8001:8001而不127.0.0.1:8001:8001,所以可以直接通過瀏覽器訪問 8001 端口查看到 kong 的源數據信息,如下:

安裝 Konga

konga 提供了對 kong 的可視化管理能力。

konga 本身也需要連接數據庫持久化自己的一些數據,所以爲它啓動一個 postgresql

Step1:創建存儲卷

docker volume create konga-postgresql

Step2:啓動 konga

  docker run -d --name konga-database \
  --network=kong-ee-net \
  -p 5433:5432 \
  -v konga-postgresql:/var/lib/postgresql/data \
  -e "POSTGRES_USER=konga" \
  -e "POSTGRES_DB=konga" \
  -e "POSTGRES_PASSWORD=konga" \
  postgres:9.6

Step3:初始化該數據庫

docker run --rm --network=kong-ee-net \
pantsel/konga:latest \
-c prepare \
-a postgres \
-u postgres://konga:konga@konga-database:5432/konga

Step4:啓動 Konga

docker run -d -p 1337:1337 \
 --name konga \
  --network=kong-ee-net \
  -e "DB_ADAPTER=postgres" \
  -e "DB_URI=postgres://konga:konga@konga-database:5432/konga" \
  -e "NODE_ENV=production" \
  -e "DB_PASSWORD=konga" \
  pantsel/konga

驗收:http://10.4.7.103:1337/register

Step5:註冊用戶並登錄

可以在 konga 數據庫中看到註冊的用戶信息

Step6:Konga 連接 Kong

主頁 > Connections >NEW CONNECTION

Step7:激活白日夢 Kong

Step8:激活後的界面如下:

Kong 中的名稱概念解釋

Service:對應着後端的一個服務,或者是一個 App。

Route:路由,不同的 route 對應着 service 中的不同接口。

Upstream:和 nginx 中的 upstream 擦不多,都對應着一組服務節點。

Target:對應着一個 api 服務節點。

# upstream 對應kong中的Upstream
upstream default_backend {
  # server 對應着Kong中的一個target
    server 10.4.4.21:81    max_fails=fail_timeout=10s;
    server 10.4.4.22:81    max_fails=fail_timeout=10s;
}

server {
    server_name *.bairimeng.com;
    # location / 對應着Kong中的一個route
    location / {
        proxy_pass http://default_backend;
        proxy_set_header Host       $http_host;
        proxy_set_header x-forwarded-for $proxy_add_x_forwarded_for;
    }
}

使用 Konga 添加一個服務

添加 upstream

往 service 中添加服務實例

添加 service

給 service 添加後端真實的路由

驗收訪問:http://10.4.7.103:8000/serverAddr

10.4.7.103 是 kong 所在機器的地址

8000 是 kong 對外暴露的接受 http 請求的端口

如果 service 的 path 爲 / 的話,訪問路徑則是:http://10.4.7.103:8000/serverAddr/serverAddr

Kong 身份認證插件

Basic Auth

Kong 支持針對 RouteService 兩種粒度添加 Basic Auth 認證的方式

比如你添加的 Basic Auth 插件後,可以去訪問該路由去驗收結果

需要輸入用戶名和密碼之後才能訪問。

這裏的用戶名密碼其實就是 Kong 中的 Consumer 的 Basic Auth 的用戶名密碼。

Step1:創建 Consumer

Step2:爲第一步中創建的 Consumer 創建 Basic Auth 的用戶名密碼。

然後使用這個用戶名和密碼就能驗證成功,成功訪問該接口。

Jwt

jwt 的驗證可以在 service、route、consumer 三個維度上添加。

例如下:

Step1:給單個 route 添加 jwt 驗證

Step2:給想訪問 Step1 中的 route 的 Consumer 添加 Jwt 憑證

注意記錄上面的 key:bairimeng、secret:bairimeng-secret

Step3:使用 key 和 secret 簽發密鑰: https://jwt.io/

驗證

1、如果沒有執行上面的 Step2 的話,請求該接口返回值如下:

2、如果 jwt 非法的話,請求該接口返回值如下:

3、全部正常返回值如下:

Key Auth

key auth 也是 Kong 提供的一種身份證的身份。

它會對 url 中的參數 key 爲 apikey 的值進行校驗,如果合法的話則方行。

apikey 的具體值需要在 consumer 中添加

如果沒有合法的 key,將得到如下的返回值

Kong 限流

同樣 Kong 也是通過組件來實現限流操作的

可以把限流組件添加到 service、route 或者針對某個 consumer 進行限流

fbSNsE

Kong 黑白名單

配置告訴 Kong 哪些 ip 是允許訪問 kong 的,以及拒絕哪些 ip 的訪問。

針對 Consumer 僅能添加下圖中的 ip 黑白名單

針對 route、service 能添加下圖中安全策略

IP Restriction

如果非法的 ip,會得到如下的返回值

ACL

它的作用也是限制誰可以訪問 Kong、誰不可以訪問 Kong,需要和 Basic Auth 結合起來使用。

如果僅有 Basic Auth 的話,效果如下:

如果添加 ACL 之後,會在僅有 Basic Auth 的基礎上更嚴格,允許訪問的粒度就從:所有的合法用戶 細化成了 具體的某個用戶或者用戶組

如果訪問者不在 ACL 指定的白名單組中的話,返回值如下:

想正常訪問接口,需要將 consumer 加入到上面的 whitelist 指定的用戶組中,如下:

bot-detection

用於過濾請求發送者的設備信息。

如過濾掉來自火狐瀏覽器的請求如下:

這時火狐瀏覽訪問該接口的話響應如下:

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/8z6N7wss9A-3ZXwD-R99lw