前些天發現了一個巨牛的人工智能學習網站,通俗易懂,風趣幽默,忍不住分享一下給大家。點擊跳轉到教程。
當前版本采用KONGv0.12.3
當我們決定對應用進行微服務改造時,應用客戶端如何與微服務交互的問題也隨之而來,畢竟服務數量的增加會直接導致部署授權、負載均衡、通信管理、分析和改變的難度增加。
面對以上問題,API GATEWAY是一個不錯的解決方案,其所提供的訪問限制、安全、流量控制、分析監控、日志、請求轉發、合成和協議轉換功能,可以解放開發者去把精力集中在具體邏輯的代碼,而不是把時間花費在考慮如何解決應用和其他微服務鏈接的問題上。
在眾多API GATEWAY框架中,Mashape開源的高性能高可用API網關和API服務管理層——KONG(基于NGINX)特點尤為突出,它可以通過插件擴展已有功能,這些插件(使用lua編寫)在API請求響應循環的生命周期中被執行。于此同時,KONG本身提供包括HTTP基本認證、密鑰認證、CORS、TCP、UDP、文件日志、API請求限流、請求轉發及NGINX監控等基本功能。目前,Kong在Mashape管理了超過15,000個API,為200,000開發者提供了每月數十億的請求支持。
本篇云框架將結合數據查詢服務實例介紹KONG API GATEWAY及其最佳實踐方法。
相關云框架:[云框架]基于Spring Cloud的微服務架構-用戶指南
?
快速部署
一鍵部署
一鍵部署至好雨云幫
本地部署
-
準備Docker環境
-
克隆倉庫
git clone https://github.com/cloudframeworks-apigateway/user-guide-apigateway
-
基于docker-compose運行命令 (docker-compose.yml)
docker-compose -f docker-compose.yml up -d
-
訪問路徑
http://本機IP:8000?- kong url
http://本機IP:8001?- kong admin url
https://本機IP:8443?- kong https url
http://本機IP:8081?- kong dashboard ui
https://本機IP:8080/api/persons?- user api url
https://本機IP:8080/api/newinfos?- newinfo api url
查看分步快速部署
框架說明-業務
數據查詢應用,顧名思義提供簡單的數據查詢服務,應用對外提供兩個端口:
-
user:處理敏感數據,如限制訪問
-
newinfo:普通數據,對所有人開放
對比以上兩個端口,我們可以相對清楚的理解KONG及其插件的效果和配置方法。
本例數據查詢應用業務架構比較簡明,如下圖所示:

框架說明-組件
本例使用KONG本身實現ROUTING,并添加了OAuth 2.0(AUTHENTICATION實現)、IP Restriction(SECURITY實現)、Rate Limiting(TRAFFIC CONTROL實現)、File(LOGGING實現)等4個插件。(查看更多官方插件)
以下管理配置通過命令行實現。KONG也可以通過UI管理界面進行管理和配置,方法請參考KONG DASHBOARD。
?
?

-
newinfo端口僅通過KONG實現與user端口的路由,其他插件未使用
-
KONG代理方式包括:1)應用通過攜帶HOST頭部路由到對應的API應用;2)通過不同的uri路由到API應用
-
以上兩種方式均為基于Openresty動態增加upstream以及對upstream的DNS resolver來實現
-
客戶端將先請求KONG服務器,并被代理到最終的API應用,而插件在API響應循環的生命周期中被執行
-
-
user端口信息敏感,限制訪問用戶;newinfo端口信息不敏感,無需限制訪問用戶(AUTHENTICATION實現)
-
user端口控制訪問地址,僅規定IP可訪問;newinfo端口無此限制(SECURITY實現)
-
user端口控制訪問頻率,newinfo端口可無限制訪問(TRAFFIC CONTROL實現)
-
user端口可獲取每次訪問日志(LOGGING實現)
KONG基本使用
注冊API
使用Kong代理API,首先需要把API注冊到Kong,并通過返回數據查看注冊是否成功,如:
curl -i -X POST \--url http://127.0.0.1:8001/apis/ \--data 'name=personapi' \--data 'hosts=personapi' \--data 'upstream_url=https://本機IP:8080/api/persons' ? ? ? ? # 本機IP通過ifconfig查看
添加用戶
API可能沒有用戶概念,會出現隨意調用的情況。為此Kong提供了一種consumer對象(全局共用),如某API啟用了key-auth,沒有身份的訪問者將無法調用該API,
命令如下:
-
創建一個consumer
curl -X POST \--data "username=oauthadmin" \--data "custom_id=personapi" \http://127.0.0.1:8001/consumers/
-
在key-auth插件中為此consumer生成key
curl -X POST \http://127.0.0.1:8001/consumers/oauthadmin/key-auth \
此時即可使用key來通過權限驗證訪問API了,需要注意的是:
-
若另一API也開通了key-auth插件,那么這個consumer也是可以通過key-auth驗證訪問這個API的,想要控制這種情況,需借助Kong的ACL插件
-
對于Kong來講,認證與權限是兩個不同的概念
API添加插件
目前,Kong默認提供了31種插件,插件獨立作用于每一個API,不同的API可以使用完全不同的插件。
這是一種非常科學的設計,因為在實際情況中很可能會出現有的API完全開放,不需要任何認證,有的API會涉及敏感數據,權限控制需要非常嚴格;有的API完全不在乎調用頻次或者日志,有的API則嚴格限制調用頻次或者日志等類似情況。
命令如下:
-
添加插件:
curl -i -X POST \--url http://127.0.0.1:8001/apis/personapi/plugins/ \--data 'name=key-auth'
-
訪問驗證:
curl -H 'Host: personapi' -H 'TT: {KEY}' http://127.0.0.1:8000
curl -H 'Host: personapi' http://127.0.0.1:8000/
ROUTING實現
user端口和newinfo端口之間實現路由,需先將服務注冊到Kong,外部訪問將統一走api gateway代理。
命令如下:
-
注冊user api
curl -i -X POST \--url http://127.0.0.1:8001/apis/ \--data 'name=personapi' \--data 'hosts=personapi' \--data 'upstream_url=https://本機IP:8080/api/persons'
-
注冊newinfo api
curl -i -X POST \--url http://127.0.0.1:8001/apis/ \--data 'name=newinfoapi' \--data 'hosts=newinfoapi' \--data 'upstream_url=https://本機IP:8080/api/newinfos'
-
注冊成功后即可通過Kong代理訪問
-
用戶信息(user端口)
命令:
curl -H 'Host: personapi' http://127.0.0.1:8000
返回:
[{"pid":1,"name":"lucien","age":30},{"pid":2,"name":"Joe","age":28},{"pid":3,"name":"smith","age":32},{"pid":4,"name":"Tod","age":56},{"pid":5,"name":"linken","age":34},{"pid":6,"name":"truple","age":23},{"pid":7,"name":"tdt","age":20} ]
-
新聞信息(newinfo端口)
命令:
curl -H 'Host: newinfoapi' http://127.0.0.1:8000
返回:
[{"nid":1,"title":"一路一代代","content":"what happending...."},{"nid":2,"title":"雪中悍刀行","content":"人生三不朽,立功立德立言"} ]
-
此時,可以將用戶信息、新聞通知對外訪問控制限制為只有Kong可以訪問,外部請求全部通過Kong進行代理。
AUTHENTICATION實現
通過OAuth 2.0 Authentication插件實現user端口的用戶訪問限制,
-
注冊Oauth2插件,詳情參見配置說明
curl -X POST \--data 'name=oauth2' \--data 'config.enable_password_grant=true' \--data 'config.provision_key=qwe1238amsdh23' \http://127.0.0.1:8001/apis/personapi/plugins
-
添加Consumer及Consumer對應的credentials
curl -X POST \--data "username=oauthadmin" \--data "custom_id=personapi" \http://127.0.0.1:8001/consumers/
curl -X POST \--data "name=oauthadmin" \--data "client_id=personapi" \--data "redirect_uri=https://本機IP:8080/api/persons" \http://127.0.0.1:8001/consumers/oauthadmin/oauth2
-
申請accesstoken并訪問
命令:
curl -k -H 'Host: personapi' \--data "client_id=5bee1b6679e5463599d7ce64b14c2795" \--data "client_secret=54f2a058f30f46e8b5ccc8d6788eb081" \--data "provision_key=qwe1238amsdh23" \--data "authenticated_userid=b48bf407-c2b7-41a9-8e0f-43eead2fc60f" \--data "grant_type=password" \https://127.0.0.1:8443/oauth2/token
返回:
{"refresh_token":"e87d871957eb4717bb0002054ae8c9a3","token_type":"bearer","access_token":"bad2a7ee579e4389880ae29b3610c639","expires_in":7200 }
-
訪問
-
使用token訪問user api
命令:
curl -H 'Host: personapi' \-H 'Authorization: bearer bad2a7ee579e4389880ae29b3610c639' \http://127.0.0.1:8000
返回:
[{"pid":1,"name":"lucien","age":30},{"pid":2,"name":"Joe","age":28},{"pid":3,"name":"smith","age":32},{"pid":4,"name":"Tod","age":56},{"pid":5,"name":"linken","age":34},{"pid":6,"name":"truple","age":23},{"pid":7,"name":"tdt","age":20} ]
-
不使用token訪問user api
命令:
curl -H 'Host: personapi' http://127.0.0.1:8000
返回:
{"error_description":"The access token is missing","error":"invalid_request" }
-
newinfo端口由于數據不敏感,無需特殊配置。
SECURITY實現
通過添加IP Restriction插件,實現對user端口的訪問限制,即僅規定IP可訪問。
-
為user端口添加IP Restriction插件擴展,并設置白名單(只有名單內的IP可以訪問API)
curl -X POST \--data 'name=ip-restriction' \--data 'config.whitelist=172.17.0.1' \http://127.0.0.1:8001/apis/personapi/plugins
-
訪問效果:
-
白名單內IP訪問:
命令:
curl -H 'Host: personapi' http://127.0.0.1:8000
返回:
[{"pid":1,"name":"lucien","age":30},{"pid":2,"name":"Joe","age":28},{"pid":3,"name":"smith","age":32},{"pid":4,"name":"Tod","age":56},{"pid":5,"name":"linken","age":34},{"pid":6,"name":"truple","age":23},{"pid":7,"name":"tdt","age":20} ]
-
其他IP訪問:
命令:
curl -H 'Host: personapi' http://172.17.0.1:8000
返回:
{"message":"Your IP address is not allowed" }
-
newinfo端口無需配置此插件。
TRAFFIC CONTROL實現
user端口通過Rate Limiting插件控制用戶訪問頻率,避免無限制訪問。
-
為user端口添加Rate Limiting插件擴展(此處設置1分鐘內只能訪問1次)
curl -X POST \--data 'name=rate-limiting' \--data 'config.minute=1' \http://127.0.0.1:8001/apis/personapi/plugins
-
訪問效果:
-
正常訪問展示:
命令:
curl -H 'Host: personapi' http://127.0.0.1:8000
返回:
[{"pid":1,"name":"lucien","age":30},{"pid":2,"name":"Joe","age":28},{"pid":3,"name":"smith","age":32},{"pid":4,"name":"Tod","age":56},{"pid":5,"name":"linken","age":34},{"pid":6,"name":"truple","age":23},{"pid":7,"name":"tdt","age":20} ]
-
超出次數的訪問展示:
命令:
curl -H 'Host: personapi' http://127.0.0.1:8000
返回:
{"message":"API rate limit exceeded" }
-
newinfo端口無需配置此插件。
LOGGING實現
user端口通過File-log插件實現對于每次訪問日志的獲取,需要注意為日志文件寫權限,日志格式參考Log Format。
-
為user端口添加File-log插件,并設置為日志文件路徑設為:/tmp/file.log
curl -X POST \--data 'name=file-log' \--data 'config.path=/tmp/file.log' \http://127.0.0.1:8001/apis/personapi/plugins
-
添加日志插件后,每次訪問都會被記錄
newinfo端口無需配置此插件。
KONG插件開發
-
git clone Kong到本地
git clone git@github.com:Mashape/kong.git
-
創建自定義插件目錄
cd ${KONG_DIR} cd kong mkdir custom_plugins
-
新增插件
cd ${KONG_DIR} cd kong mkdir custom_plugins cd custom_plugins mkdir xxx
-
編輯插件的schema.lua、handler.lua, 根據實際情況完成插件邏輯(lua教程)
-
修改
${KONG_DIR}/templates/kong_defaults.lua
,配置custom_plugins=xxx -
執行luaracks make安裝插件到本地進行測試
-
制作kong鏡像,并快速部署
KONG插件開發示例:log2zmq
KONG插件開發示例:accesslimiting
?
?
轉自: https://github.com/cloudframeworks-apigateway/user-guide-apigateway#KONG%E5%9F%BA%E6%9C%AC%E4%BD%BF%E7%94%A8