網關kong及其管理工具konga的初步使用小結

1、背景

當前微服務網關的技術選型不少。常見的有springcloud系的zuul1,gateway;也能夠選擇nginx+lua方案;或者直接使用UI集成度較高的Kong。java

本文記述瞭如何使用docker安裝kong與konga(一個開源的Kong管理UI項目),以及它們的簡單使用和一些注意事項。nginx

2、經過docker安裝kong(DB模式)與konga

2.1 經過docker安裝kong(DB模式)

官方文檔:https://docs.konghq.com/install/docker/git

2020/07/03 kong目前的最新版本2.0.4,在作websocket轉發時,與tomcat版本9.0.29有衝突,會致使websocket沒法正常轉發。所以這裏咱們選擇安裝kong的一個稍微低一點的版本 2.0.0
# 若是不指定subnet,建立的network默認使用172.17網段,可能會與實際網段發生衝突
docker network create --subnet=12.10.10.0/24 kong-net

# 拉取postgres:9.6做爲kong的數據庫
docker run -d --name kong-database \
               --network=kong-net \
               -p 5432:5432 \
               -e "POSTGRES_USER=kong" \
               -e "POSTGRES_DB=kong" \
               -e "POSTGRES_PASSWORD=kong" \
               postgres:9.6

# 拉取kong:2.0.0並生成初期數據
docker run --rm \
     --network=kong-net \
     -e "KONG_DATABASE=postgres" \
     -e "KONG_PG_HOST=kong-database" \
     -e "KONG_PG_USER=kong" \
     -e "KONG_PG_PASSWORD=kong" \
     -e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
     kong:2.0.0 kong migrations bootstrap

# 啓動kong
docker run -d --name kong \
     --network=kong-net \
     -e "KONG_DATABASE=postgres" \
     -e "KONG_PG_HOST=kong-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 127.0.0.1:8001:8001 \
     -p 127.0.0.1:8444:8444 \
     kong:2.0.0

# 啓動後在宿主機訪問8000與8001端口
curl http://localhost:8000
curl http://localhost:8001

注意,kong的四個端口做用:github

  1. 8000與8443分別用於對http和https的代理訪問;
  2. 8001與8444分別是http與https的管理API訪問端口,由於管理API不宜對外暴露,因此在掛載端口時,明確了127.0.0.1,即只有宿主機本地可以訪問。

2.2 經過docker安裝konga

konga安裝直接默認最新版本(目前是0.14.9)。web

# 拉取pantsel/konga,並建立數據庫konga_db。
# 注意這裏直接使用剛剛爲了kong建立的PG數據庫實例,並使用kong的DB用戶,
# 注意這裏postgresql鏈接的寫法:
#  postgresql://<用戶>:<密碼>@<PG_Host>:<PG_Port>/<database>

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

# 啓動konga
docker run -p 1337:1337 \
             --network=kong-net \
             -e "DB_ADAPTER=postgres" \
             -e "DB_HOST=kong-database" \
             -e "DB_USER=kong" \
             -e "DB_PASSWORD=kong" \
             -e "DB_DATABASE=konga_db" \
             -e "KONGA_HOOK_TIMEOUT=120000" \
             -e "NODE_ENV=production" \
             --name konga \
             pantsel/konga
konga從命令行啓動後不會退出,但docker容器已經正常啓動。建議後面經過 portainer來重啓該容器。(portainer是一個開源的docker管理工具,自己直接拉取docker運行便可。)

3、首次訪問konga並配置kong管理API鏈接

觀察docker容器情況,確認kong-databasekongkonga三個容器所有成功啓動後,訪問地址:http://localhost:1337正則表達式

首次訪問會讓你建立konga的管理員帳戶,而後登陸,而後建立到kong管理API的鏈接,過程以下:spring

  1. 建立gonga管理員帳戶
  2. 用管理員帳戶登陸
  3. 建立到kong管理API的鏈接(鏈接地址:http://kong:8001/)
  4. 激活該鏈接
注意上面第三步,建立到kong管理API的鏈接時,由於前面啓動kong時,8001端口只掛載在 12.0.0.1:8001上,所以只有宿主機本身能夠訪問。這裏在konga容器內訪問kong時,就必須經過網絡 kong-net中的容器ip或hostname訪問。所以這裏填寫的是kong容器的name: kong,而不是宿主機IP。

4、添加路由規則

此時konga的界面仍是比較簡陋的,功能也很少。dashbord只能看到一些整體的統計信息,看不到具體每一個目標服務的訪問量。sql

若是須要添加其餘功能,須要經過PLUGINS去一個一個添加,具體還沒有研究。docker

但動態添加路由規則是徹底沒有問題的。這裏主要介紹如何添加路由規則。數據庫

kong添加路由規則主要分爲兩步:

  1. 添加要訪問的目標服務。
  2. 在已經添加的Sevice裏添加網關接收到的請求的過濾規則,即把什麼樣的請求轉發給該Service。

4.1 添加目標服務

經過左側導航菜單SERVICES,添加目標服務ADD NEW SERVICE,通常配置項目以下:

  • Name: 一般寫目標服務名。
  • Protocol: http 或 https
  • Host: 目標服務的Host
  • Port: 目標服務的端口
  • Path: 目標服務訪問根路徑,沒有特殊狀況就填寫/
注意Path不要空着,沒有指定Path就填上 /表示服務根目錄。

其餘項目通常保持默認便可。

4.2 爲目標服務添加路由

經過左側導航菜單SERVICES,點擊一個目標服務,選擇它的Routes,並點擊ADD ROUTE,配置以下:

路由通常配置項:

  • Name : 路由名稱。
  • 其餘 : 略

路由過濾條件配置項:

  • Hosts : 網關所在服務器有多個域名時,能夠根據請求的域名作過濾條件;通常不填。
  • Paths : 通常都是在Paths作過濾條件。Kong經過PCRE(與Perl兼容的正則表達式)支持paths字段的正則表達式模式匹配。所以能夠同時使用path前綴和正則表達式匹配路由。注意每寫一個Path過濾條件就要回車(必定要回車,否則konga認爲你沒有輸入。。。),多個Path過濾條件就寫多個。
  • Methods : 將HTTP methods做爲過濾條件,填入POSTGET等。
  • Headers : 須要經過Header信息做爲過濾條件時填寫。直接將header信息的屬性:值填入便可,注意回車。例如:Connection: keep-alive
  • Protocols : 將協議做爲過濾條件,http或https。
  • 其餘 : 略

注意:

  1. Hosts,Paths,Methods三者最少須要配置一個。
  2. 大部分狀況下,咱們都是根據Path來作轉發的過濾條件的,所以不一樣目標系統若是某些資源訪問Path相同的話,會致使不一樣目標服務的路由規則衝突。

關於Path衝突,建議以下:

  1. 儘可能確保不一樣的目標服務具備各自統一的資源訪問根目錄。即每一個目標服務都有本身統一且惟一的Path前綴。如,某個目標服務的Path都是/service1/*,靜態資源用/service1/static/*,API用/service1/api/*等等。
  2. 沒有統一訪問根目錄的目標服務,儘可能保證各自的路徑知足不一樣的正則表達式。好比Path的中間某一層統一爲能識別具體服務的字符串。如,某個目標服務的Path都知足/*/service2/*,靜態資源用/static/service2/*,API用/api/service2/*等等。
  3. 前面兩點都不能知足的話,考慮加入其餘過濾條件(Hosts,Headers等),例如,網關有多個域名,當請求用域名1訪問時,路由到目標服務1,用域名2訪問時,路由到目標服務2。

路由附加操做配置項:

  • Strip Path : 知足條件的請求在轉發給目標服務時,是否將Paths中匹配的部分從訪問路徑中去掉。
  • 其餘 : 略

5、關於websocket的轉發

kong是天生支持websocket轉發的,關於這一點,能夠參考官網的說明:https://docs.konghq.com/2.0.x/proxy/#proxy-websocket-traffic

但當kong位於客戶端與服務端之間時,kong的某些版本與服務器的版本可能會有衝突,致使websocket轉發發生異常。

例如,目前kong的最新版本(2.0.4)做爲網關,若是目標服務是tomcat的9.0.29版本,那麼會發生如下現象:

  • 客戶端在試圖鏈接websocket時,發生Error during WebSocket handshake: 'Upgrade' header is missing錯誤。
  • 位於kong後面的服務端tomcat可以接收到轉發的websocket鏈接請求併成功創建鏈接,但緊接着就會發生java.io.EOFException異常,致使鏈接被關閉。

具體緣由在kong的issue #5714 (https://github.com/Kong/kong/issues/5714) 中有討論,該issue已被關閉但實際上問題並未解決。。。卻是其中一個回答提到,若是將kong版本回退到2.0.0則該問題不會發生。

相關文章
相關標籤/搜索