Kong使用

Kong使用數據庫模式

1. 創建kong-net網絡

$ docker network create kong-net

2. 啓動PostgreSQL容器

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:11.7

3. 運行臨時Kong容器遷移數據庫

docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations bootstrap

4. 啓動Kong容器

docker run -d --name kong \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-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 80:8000 \
-p 443:8443 \
-p 8001:8001 \
-p 8444:8444 \
kong:latest

5. 驗證

curl -s -i http://localhost:8001/ | jq

6. dashboard

# 遷移konga數據表到pgsql
docker run --name konga --rm \
--network=kong-net \
pantsel/konga -c prepare -a postgres -u postgresql://kong:kong@kong-database:5432/kong

# 啓動konga
docker run -p 1337:1337 -d \
--network=kong-net \
-e "DB_ADAPTER=postgres" \
-e "DB_HOST=kong-database" \
-e "DB_USER=kong" \
-e "DB_PASSWORD=kong" \
-e "DB_DATABASE=kong" \
-e "KONGA_HOOK_TIMEOUT=120000" \
-e "DB_PG_SCHEMA=public" \
-e "NODE_ENV=production" \
--name konga \
pantsel/konga

Kong概率術語

upstream: 是對上游服務器的抽象;

target: 代表了一個物理服務,是ip+port的抽象;

service: 是抽象層面的服務,它也可以直接映射到一個物理服務(host 指向 ip + port),也可以指向一個upstream來做到負載均衡;

route: 是路由的抽象,它負責將實際的request映射到service

默認情況下,Kong監聽的端口是:8000、8001、8443、8444

8444:通過此端口,管理者可以對HTTP請求進行監控

其中8000/8443分別是用來監聽來自客戶端的Http和Https請求,等價於Nginx默認的80和443端口,而8001端口是默認的管理端口,可以通過HTTP Restful API來動態管理Kong的配置

Kong的簡單使用

一個典型的Nginx的配置

upstream www {
	server localhost:3001 weight=100;
}

server {
    server_name www.flask.com;
	listen 80;
	location / {
		proxy_pass http://www;
	}
}

如上簡單的Nginx配置,可以轉換爲如下的Http請求

對應的Kong配置

  1. 配置upstream
curl -X POST http://10.0.0.10:8001/upstreams --data "name=www-ups"
  1. 配置target
curl -X POST http://10.0.0.10:8001/upstreams/www-ups/targets --data "target=10.0.0.10:3001" --data "weight=100"
  1. 配置service
curl -X POST http://10.0.0.10:8001/services --data "name=www-svc" --data "host=www-ups"
  1. 配置route
curl -X POST http://10.0.0.10:8001/routes \
--data "name=www-route" \
--data "hosts[]=www.flask.com" \
--data "paths[]=/" \
--data "service.id=741dc49d-0a96-4e1d-90c3-d1948cba1175"
  1. 訪問www-route(uri)
curl -s -X GET http://www.flask.com
# --url 指定kong proxy服務器的ip:port, 默認爲8000端口,這裏映射到虛擬機的80端口
curl -s -X GET --url 'http://10.0.0.10:80' --header 'Host: www.flask.com'

這一切都是動態的,無需手動reload nginx.conf

爲Kong新增路由信息時涉及到了upstream,target,service,route等概念,便是Kong最核心的四個對象.

Kong 插件簡單使用

www-svc服務添加5次/分的限流

curl -X POST http://10.0.0.10:8001/services/www-svc/plugins \
--data "name=rate-limiting" \
--data "config.minute=5"

www-svc服務添加jwt插件

curl -X POST http://10.0.0.10:8001/services/www-svc/plugins \
--data "name=jwt"

代理緩存插件

curl -i -X POST http://10.0.0.10:8001/plugins \
--data name=proxy-cache \
--data config.content_type="application/json" \
--data config.cache_ttl=30 \
--data config.strategy=memory

驗證代理緩存

# 注意響應的內容格式必須是json格式的纔有效果
curl -i -X GET --url 'http://10.0.0.10:80' --header 'Host: demo1.flask.com'
X-Cache-Status: Miss
X-Cache-Status: Hit

設置祕鑰認證插件

curl -X POST http://10.0.0.10:8001/routes/demo1/plugins \
--data name=key-auth
curl -i -X GET --url 'http://10.0.0.10:80' --header 'Host: demo1.flask.com'
# 返回{"message":"No API key found in request"}

創建消費者
curl -i -X POST -d "username=consumer&custom_id=consumer" http://10.0.0.10:8001/consumers/

創建消費者祕鑰
curl -i -X POST http://10.0.0.10:8001/consumers/consumer/key-auth -d 'key=apikey'

驗證祕鑰
curl -i -X GET --url 'http://10.0.0.10:80' --header 'Host: demo1.flask.com' -H 'apikey:apikey'

禁用插件
curl -s  -X GET http://10.0.0.10:8001/routes/demo1/plugins | jq '.data[].id'
curl -X PATCH http://10.0.0.10:8001/routes/demo1/plugins/81554ece-ef5b-42c5-91c4-9e0bf9e29920 \
 --data "enabled=false"

同理,插件也可以安裝在route之上

獲取www-svc的所有路由名稱和routeId,帶上cookie和 authorization
curl -s -b "io=rCMjxICHRJ6zv2PTAAAF" -H 'authorization: Bearer eyJhbGciOiJIUzI1NiJ9.MQ.Lu-KcR4aCeuT9hi1K474zV3s4VaopLDCcf4nZvH6DQo' http://10.0.0.10:1337/kong/services/741dc49d-0a96-4e1d-90c3-d1948cba1175/routes |jq '.data[].name, .data[].id'

curl -X POST http://10.0.0.10:8001/routes/{routeId}/plugins \
--data "name=jwt"

curl -X POST http://10.0.0.10:8001/routes/c3ea95c1-7a56-4fad-847e-f77de918bf26/plugins \
--data "name=rate-limiting" \
--data "config.second=5"

Base Auth訪問

curl -s -H 'Authorization: Basic dGVzdDp0ZXN0' --url 'http://10.0.0.10:80'  --header 'Host: hello.flask.com'

Kong不添加Upstream,直接使用services訪問

#添加services
curl -i -X POST \
--url http://10.0.0.10:8001/services/ \
--data 'name=svc-demo1' \
--data 'url=http://httpbin.org/ip'

#添加routes
curl -i -X POST \
--url http://10.0.0.10:8001/services/svc-demo1/routes \
--data 'name=demo1' \
--data 'hosts[]=demo1.flask.com'

#訪問測試
curl -i -X GET \
--url http://10.0.0.10:80/ \
--header 'Host: demo1.flask.com'

Kong OAuth2驗證

1.1 使用Kong的管理API端口8001添加一個名稱爲book的服務

curl -s -X POST \
--url http://localhost:8001/services/ \
--data 'name=book' \
--data 'url=http://10.0.0.10:3002/v1/books' | jq

1.2 給book服務添加一個路由 /v1/books

# paths[]的值必須與book服務中的/v1/books一致,使book服務暴露出來以供用戶訪問,book服務沒必要添加多個路由

curl -s -X POST \
--url http://localhost:8001/services/book/routes \
--data 'name=v1' \
--data 'hosts[]=book.com' \
--data 'paths[]=/v1/books' | jq

1.3 通過Kong在8000端口暴露出來的服務地址獲取所有的書籍

curl -s -X GET \
--url http://localhost:8001/v1/books \
--header 'Host: book.com' | jq

# 獲取book服務的描述信息
curl -s http://localhost:8001/services/book | jq
# 獲取book服務使用的插件
curl -s http://localhost:8001/services/book/plugins | jq

1.4 爲book服務啓動OAuth2.0 Authentication插件,並激活簡化模式授權

curl -s -X POST \
--url http://localhost:8001/services/book/plugins \
--data "name=oauth2" \
--data "config.scopes=email,phone" \
--data "config.mandatory_scope=true" \
--data "config.enable_implicit_grant=true" | jq

# 獲取oauth2插件的provision_key,待會發請求需要
curl -s http://localhost:8001/services/book/plugins | jq '.data[].config.provision_key' | sed 's/"//g'

provision_key: SBUm1zCs5ropHZcCL5iUwoIz2bQW3ZWG

1.5 添加一個username爲laowang消費者

# custom_id參數可以省略,此參數是一個自定義的唯一標識,它作用是把消費者老王映射到另外一個數據庫上
curl -s -X POST \
--url http://localhost:8001/consumers/  \
--data "username=laowang" | jq

1.6 爲消費者老王創建一個名爲Book App的應用

# redirect_uri參數定義發送code和state的回調地址
參數{client_id}和{client_secret}可自定義,省略時由系統隨機生成

curl -s -X POST \
--url http://localhost:8001/consumers/laowang/oauth2/ \
--data "name=Book App" \
--data "redirect_uris=http://getkong.org" | jq

1.7 根據client_id查詢消費者的應用程序信息

# 獲取 laowang 的client_id
curl -s http://localhost:8001/consumers/laowang | jq '.id'
client_id: dfdd8230-ce2e-4378-b42a-de73ae846ada

# 記錄下消費者老王下的OAuth2的client_secret和client_id
curl -s -X GET \
--url http://localhost:8001/oauth2 \
--data "client_id=dfdd8230-ce2e-4378-b42a-de73ae846ada" | jq 

# laowang的oauth2信息
client_secret: HnBL9tbsARkS6wUu5cpFsSgfhA3tGJ85
client_id: 3mYuLCNoCrY6hnoDjb7Bc3LZcmGkl6iU

1.8 測試請求 /v1/books 接口

# 通過Kong的proxy端口暴露出來的服務地址讀一條書籍記錄,實際上是通過Kong在轉發我的請求,不管是讀1條記錄還讀所有書籍記錄,我們都無權獲得數據

curl -s -X GET \
--url http://localhost:80/v1/books \
--header 'Host: book.com' | jq

#響應
{
  "error_description": "The access token is missing",
  "error": "invalid_request"
}

1.9 生成訪問令牌

# 所有步驟在瀏覽器中完成,簡化模式下令牌對訪問者是可見的,且客戶端不需要認證。
客戶端將發送由參數{client_id},{response_type},
{scope},{provision_key},{authenticated_userid},{state}構成的POST請求直接獲得訪問令牌
{state}客戶端的當前狀態,可以指定任意值,認證服務器會原封不動地返回這個值
{scope}表示申請的權限範圍
{authenticated_userid}已授予權限的終端登錄用戶userid

curl -s -X POST \
--url https://localhost:443/v1/books/oauth2/authorize \
--header 'Host: book.com' \
--data "client_id=3mYuLCNoCrY6hnoDjb7Bc3LZcmGkl6iU" \ #laowang的oauth2的client_id
--data "response_type=token" \
--data "scope=email,phone" \
--data "provision_key=SBUm1zCs5ropHZcCL5iUwoIz2bQW3ZWG" \
--data "authenticated_userid=1206" \
--data "state=xyz" --insecure | jq

# 響應
{
  "redirect_uri": "http://getkong.org#access_token=a3z6QvuqdhMgz6G9RrAmLqcfCY85s8fK&expires_in=7200&state=xyz&token_type=bearer"
}

1.10 使用令牌訪問book接口

curl -s -X GET \
--url https://localhost:443/v1/books \
--header "Authorization: Bearer a3z6QvuqdhMgz6G9RrAmLqcfCY85s8fK" \
--header 'Host: book.com' --insecure | jq
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章