高效能API閘道器Kong介紹
作者:天翼雲 張帆
本文關鍵詞:高效能、 API 閘道器、 Kong 、微服務
0.Introduction to Kong
· (簡介)
· (關鍵概念)
· (安裝說明)
· ( API 管理 )
o (新增服務)
o 4.2 List current services (列表查詢當前服務)
o (為服務新增路由)
o (外掛)
o (新增消費者)
o ( 限流 )
o (小節總結)
· (高階特性)
o (負載均衡)
· ( Kong控制檯)
· (總結)
· (參考)
1.Introduction
API 閘道器 ( ) 是隨著微服務( Microservice )概念興起的一種架構模式。原本一個龐大的單體應用( All in one )業務系統被拆分成許多微服務( Microservice )系統進行獨立的維護和部署,服務拆分帶來的變化是 API 的規模成倍增長, API 的管理難度也在日益增加,使用 API 閘道器釋出和管理 API 逐漸成為一種趨勢。一般來說, API 閘道器是執行於外部請求與內部服務之間的一個流量入口,實現對外部請求的協議轉換、鑑權、流控、引數校驗、監控等通用功能。
本文即將介紹的 , 是一個開源的API gateway 和微服務管理的工具,基於 Nginx 和 (特殊的 ),Kong 具有可插拔的架構,使其功能強大且靈活。
2.Key Concepts
· Service: Kong 的一個實體物件,表示了外部的上游 API 或者微服務
· Route: Kong 的一個實體物件,表示了一種將下游請求對映到上游服務的路由
· Consumer: Kong 的一個實體物件,表示使用 API 的開發者或者機器,在使用 Kong 時,一個 Consumer 僅與 Kong 互動。
· Plugin :外掛用於是 Kong 內部將請求轉發給上游 API 前後執行的一系列動作, Kong 在其 中提供了非常強大的外掛
· Credential: A certificate object represents a public certificate/private key pair for an SSL certificate.
· SNI: An SNI object represents a many-to-one mapping of hostnames to a certificate. That is, a certificate object can have many hostnames associated with it
· Upstream: 上游服務 , 指代 Kong 背後的 API 或者服務 , 也是客戶端請求轉發的目的端 , The upstream object represents a virtual hostname and can be used to loadbalance incoming requests over multiple services (targets).
· Target: A target is an ip address/hostname with a port that identifies an instance of a backend service. Every upstream can have many targets, and the targets can be dynamically added. Changes are effectuated on the fly.
· Admin API - 用於管理 Kong 配置,端點,使用者,外掛等的 RESTful API 端點
下圖展示了Kong 和其他 傳統 架構的區別,可以幫助我們理解為什麼有Kong :
大概有鑑權、監控、日誌、安全審計、ACL 、快取、限流、 serverless 等等。
3.Setup
官方文件提供了多種環境下詳細的 。我們這裡使用docker 進行安裝( docker 安裝過程略):
# 1 .create docker network
$ docker network create kong-net
# 2 .run PostgreSQL database
$ docker run -d --name kong-database \
--network=kong-net \
- p 5432 : 5432 \
- e "POSTGRES_USER=kong" \
- e "POSTGRES_DB=kong" \
postgre s:9 . 6
# 3 .prepare database
$ docker run --rm \
--network=kong-net \
- e "KONG_DATABASE=postgres" \
- e "KONG_PG_HOST=kong-database" \
- e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kon g:latest kong migrations bootstrap
Unable to find image 'kong:latest' locally
lates t: Pulling from library/kong
59265 c40e257: Pull complete
6389 eff8e6ff: Pull complete
f58488256be6: Pull complete
Diges t: sha256 :f7ed033bb9955da0fcefa034d07fee324cad6d01c12ebf54268dfe825ba2e92c
Statu s: Downloaded newer image for kon g:latest
bootstrapping database...
migrating core on database 'kong' ...
core migrated up to : 000 _base (executed)
core migrated up to : 001 _14_to_15 (executed)
core migrated up to : 002 _15_to_1 (executed)
migrating oauth2 on database 'kong' ...
oauth2 migrated up to : 000 _base_oauth2 (executed)
oauth2 migrated up to : 001 _14_to_15 (executed)
oauth2 migrated up to : 002 _15_to_10 (executed)
migrating acl on database 'kong' ...
acl migrated up to : 000 _base_acl (executed)
acl migrated up to : 001 _14_to_15 (executed)
migrating jwt on database 'kong' ...
jwt migrated up to : 000 _base_jwt (executed)
jwt migrated up to : 001 _14_to_15 (executed)
migrating basic-auth on database 'kong' ...
basic-auth migrated up to : 000 _base_basic_auth (executed)
basic-auth migrated up to : 001 _14_to_15 (executed)
migrating key-auth on database 'kong' ...
key-auth migrated up to : 000 _base_key_auth (executed)
key-auth migrated up to : 001 _14_to_15 (executed)
migrating rate-limiting on database 'kong' ...
rate-limiting migrated up to : 000 _base_rate_limiting (executed)
rate-limiting migrated up to : 001 _14_to_15 (executed)
rate-limiting migrated up to : 002 _15_to_10 (executed)
migrating hmac-auth on database 'kong' ...
hmac-auth migrated up to : 000 _base_hmac_auth (executed)
hmac-auth migrated up to : 001 _14_to_15 (executed)
migrating response-ratelimiting on database 'kong' ...
response-ratelimiting migrated up to : 000 _base_response_rate_limiting (executed)
response-ratelimiting migrated up to : 001 _14_to_15 (executed)
response-ratelimiting migrated up to : 002 _15_to_10 (executed)
22 migrations processed
22 executed
database is up - to -date
# 4 .start Kong
$ docker run -d --name kong \
--network=kong-net \
- e "KONG_DATABASE=postgres" \
- e "KONG_PG_HOST=kong-database" \
- 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 \
kon g:latest
999 a5cf1db1a8c23ca870933b73407d7ae5f0fd2d9a895a78627a9c27e08045c
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
999 a5cf1db1a kon g:latest "/docker-entrypoint. … " 8 seconds ago Up 7 seconds 0.0 . 0.0 : 8000 - 8001 -> 8000 - 8001 /tcp, 0.0 . 0.0 : 8443 - 8444 -> 8443 - 8444 /tcp kong
ecb50c2f7307 postgre s:9 . 6 "docker-entrypoint.s … " About an hour ago Up About an hour 0.0 . 0.0 : 5432 -> 5432 /tcp
容器啟動完畢後 , 嘗試 curl -i , 得到如下 :
{
"plugins" : {
"enabled_in_cluster" : [ ],
"available_on_server" : {
"response-transformer" : true ,
"oauth2" : true ,
"acl" : true ,
"correlation-id" : true ,
"pre-function" : true ,
"jwt" : true ,
"cors" : true ,
"ip-restriction" : true ,
"basic-auth" : true ,
"key-auth" : true ,
"rate-limiting" : true ,
"request-transformer" : true ,
"http-log" : true ,
"file-log" : true ,
"hmac-auth" : true ,
"ldap-auth" : true ,
"datadog" : true ,
"tcp-log" : true ,
"zipkin" : true ,
"post-function" : true ,
"request-size-limiting" : true ,
"bot-detection" : true ,
"syslog" : true ,
"loggly" : true ,
"azure-functions" : true ,
"udp-log" : true ,
"response-ratelimiting" : true ,
"aws-lambda" : true ,
"statsd" : true ,
"prometheus" : true ,
"request-termination" : true
}
},
"tagline" : "Welcome to kong" ,
"configuration" : {
"plugins" : [
"bundled"
],
"admin_ssl_enabled" : true ,
"lua_ssl_verify_depth" : 1 ,
"trusted_ips" : { },
"prefix" : "/usr/local/kong" ,
"loaded_plugins" : {
"response-transformer" : true ,
"request-termination" : true ,
"prometheus" : true ,
"ip-restriction" : true ,
"pre-function" : true ,
"jwt" : true ,
"cors" : true ,
"statsd" : true ,
"basic-auth" : true ,
"key-auth" : true ,
"ldap-auth" : true ,
"aws-lambda" : true ,
"http-log" : true ,
"response-ratelimiting" : true ,
"hmac-auth" : true ,
"request-size-limiting" : true ,
"datadog" : true ,
"tcp-log" : true ,
"zipkin" : true ,
"post-function" : true ,
"bot-detection" : true ,
"acl" : true ,
"loggly" : true ,
"syslog" : true ,
"azure-functions" : true ,
"udp-log" : true ,
"file-log" : true ,
"request-transformer" : true ,
"correlation-id" : true ,
"rate-limiting" : true ,
"oauth2" : true
},
"cassandra_username" : "kong" ,
"ssl_cert_key" : "/usr/local/kong/ssl/kong-default.key" ,
"admin_ssl_cert_key" : "/usr/local/kong/ssl/admin-kong-default.key" ,
"dns_resolver" : { },
"pg_user" : "kong" ,
"mem_cache_size" : "128m" ,
"ssl_ciphers" : "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256" ,
"nginx_admin_directives" : { },
"nginx_http_directives" : [
{
"value" : "prometheus_metrics 5m" ,
"name" : "lua_shared_dict"
}
],
"pg_host" : "kong-database" ,
"nginx_acc_logs" : "/usr/local/kong/logs/access.log" ,
"proxy_listen" : [
"0.0.0.0:8000" ,
"0.0.0.0:8443 ssl"
],
"client_ssl_cert_default" : "/usr/local/kong/ssl/kong-default.crt" ,
"ssl_cert_key_default" : "/usr/local/kong/ssl/kong-default.key" ,
"db_update_frequency" : 5 ,
"db_update_propagation" : 0 ,
"stream_listen" : [
"off"
],
"nginx_err_logs" : "/usr/local/kong/logs/error.log" ,
"cassandra_port" : 9042 ,
"dns_order" : [
"LAST" ,
"SRV" ,
"A" ,
"CNAME"
],
"dns_error_ttl" : 1 ,
"headers" : [
"server_tokens" ,
"latency_tokens"
],
"cassandra_lb_policy" : "RequestRoundRobin" ,
"nginx_optimizations" : true ,
"pg_timeout" : 5000 ,
"database" : "postgres" ,
"pg_database" : "kong" ,
"nginx_worker_processes" : "auto" ,
"lua_package_cpath" : "" ,
"admin_acc_logs" : "/usr/local/kong/logs/admin_access.log" ,
"lua_package_path" : "./?.lua;./?/init.lua;" ,
"nginx_pid" : "/usr/local/kong/pids/nginx.pid" ,
"upstream_keepalive" : 60 ,
"client_ssl" : false ,
"admin_access_log" : "/dev/stdout" ,
"cassandra_data_centers" : [
"dc1:2" ,
"dc2:3"
],
"cassandra_ssl" : false ,
"proxy_listeners" : [
{
"transparent" : false ,
"ssl" : false ,
"ip" : "0.0.0.0" ,
"proxy_protocol" : false ,
"port" : 8000 ,
"http2" : false ,
"listener" : "0.0.0.0:8000"
},
{
"transparent" : false ,
"ssl" : true ,
"ip" : "0.0.0.0" ,
"proxy_protocol" : false ,
"port" : 8443 ,
"http2" : false ,
"listener" : "0.0.0.0:8443 ssl"
}
],
"proxy_ssl_enabled" : true ,
"client_max_body_size" : "0" ,
"proxy_error_log" : "/dev/stderr" ,
"enabled_headers" : {
"latency_tokens" : true ,
"X-Kong-Proxy-Latency" : true ,
"Via" : true ,
"server_tokens" : true ,
"Server" : true ,
"X-Kong-Upstream-Latency" : true ,
"X-Kong-Upstream-Status" : false
},
"dns_stale_ttl" : 4 ,
"lua_socket_pool_size" : 30 ,
"db_resurrect_ttl" : 30 ,
"origins" : { },
"cassandra_consistency" : "ONE" ,
"db_cache_ttl" : 0 ,
"admin_error_log" : "/dev/stderr" ,
"pg_ssl_verify" : false ,
"dns_not_found_ttl" : 30 ,
"pg_ssl" : false ,
"nginx_daemon" : "off" ,
"nginx_kong_stream_conf" : "/usr/local/kong/nginx-kong-stream.conf" ,
"cassandra_repl_strategy" : "SimpleStrategy" ,
"error_default_type" : "text/plain" ,
"dns_no_sync" : false ,
"nginx_proxy_directives" : { },
"proxy_access_log" : "/dev/stdout" ,
"nginx_kong_conf" : "/usr/local/kong/nginx-kong.conf" ,
"cassandra_schema_consensus_timeout" : 10000 ,
"dns_hostsfile" : "/etc/hosts" ,
"admin_listeners" : [
{
"transparent" : false ,
"ssl" : false ,
"ip" : "0.0.0.0" ,
"proxy_protocol" : false ,
"port" : 8001 ,
"http2" : false ,
"listener" : "0.0.0.0:8001"
},
{
"transparent" : false ,
"ssl" : true ,
"ip" : "0.0.0.0" ,
"proxy_protocol" : false ,
"port" : 8444 ,
"http2" : false ,
"listener" : "0.0.0.0:8444 ssl"
}
],
"ssl_cipher_suite" : "modern" ,
"ssl_cert" : "/usr/local/kong/ssl/kong-default.crt" ,
"cassandra_timeout" : 5000 ,
"admin_ssl_cert_key_default" : "/usr/local/kong/ssl/admin-kong-default.key" ,
"cassandra_ssl_verify" : false ,
"cassandra_contact_points" : [
"kong-database"
],
"real_ip_header" : "X-Real-IP" ,
"real_ip_recursive" : "off" ,
"cassandra_repl_factor" : 1 ,
"client_ssl_cert_key_default" : "/usr/local/kong/ssl/kong-default.key" ,
"admin_ssl_cert" : "/usr/local/kong/ssl/admin-kong-default.crt" ,
"anonymous_reports" : true ,
"log_level" : "notice" ,
"kong_env" : "/usr/local/kong/.kong_env" ,
"pg_port" : 5432 ,
"admin_ssl_cert_default" : "/usr/local/kong/ssl/admin-kong-default.crt" ,
"client_body_buffer_size" : "8k" ,
"ssl_preread_enabled" : true ,
"ssl_cert_csr_default" : "/usr/local/kong/ssl/kong-default.csr" ,
"stream_listeners" : { },
"cassandra_keyspace" : "kong" ,
"ssl_cert_default" : "/usr/local/kong/ssl/kong-default.crt" ,
"nginx_conf" : "/usr/local/kong/nginx.conf" ,
"admin_listen" : [
"0.0.0.0:8001" ,
"0.0.0.0:8444 ssl"
]
},
"version" : "1.0.3" ,
"node_id" : "3ccef799-3037-4a8f-8ccd-2e60326b4444" ,
"lua_version" : "LuaJIT 2.1.0-beta3" ,
"prng_seeds" : {
"pid: 36" : 229762112224 ,
"pid: 37" : 131951181922 ,
"pid: 1" : 136391662351
},
"timers" : {
"pending" : 5 ,
"running" : 0
},
"hostname" : "999a5cf1db1a"
}
上面幾個埠,分別是:
· :8000 on which Kong listens for incoming HTTP traffic from your clients, and forwards it to your upstream services.
· :8443 on which Kong listens for incoming HTTPS traffic. This port has a similar behavior as the :8000 port, except that it expects HTTPS traffic only. This port can be disabled via the configuration file.
· :8001 on which the Admin API used to configure Kong listens.
· :8444 on which the Admin API listens for HTTPS traffic.
4.API Management
在本地配置 Kong 完畢後 , 我們來感受一下 Kong 強大的特性。首先我們有一個簡單的 API 服務 , 之前已經寫好的一個 flavors 的增刪改查 , 以 flavors 的查詢為例 , 我們將 GET /flavors/detail 新增到 Kong 中。
我們的API server 地址是 ,於是我們有:
· route path: /flavors/detail
· service host:
4.1 Add a service
curl -i -X POST \
- -url http: / /localhost:8001/services/ \ - -data 'name=example-flavors'\ - -data 'url=
得到的響應 :
HTTP/1.1 201 Created
Date : Wed, 27 Feb 2019 06:08:25 GMT
Content-Type : application/json; charset=utf-8
Connection : keep-alive
Access-Control-Allow-Origin : *
Server : kong/1.0.3
Content-Length : 273
{ "host" : "127.0.0.1" , "created_at" : 1551247705 , "connect_timeout" : 60000 , "id" : "abba6d52-b239-4b8f-ad11-1e7389d4cf71" , "protocol" : "http" , "name" : "example-flavors" , "read_timeout" : 60000 , "port" : 8080 , "path" : "/flavors/detail" , "updated_at" : 1551247705 , "retries" : 5 , "write_timeout" : 60000 }
4.2 List current services
curl -i -X GET \
- -url http: / /localhost:8001/services/
得到的響應:
HTTP/1.1 200 OK
Date : Wed, 27 Feb 2019 06:11:07 GMT
Content-Type : application/json; charset=utf-8
Connection : keep-alive
Access-Control-Allow-Origin : *
Server : kong/1.0.3
Content-Length : 296
{ "next" : null , "data" : [ { "host" : "127.0.0.1" , "created_at" : 1551247705 , "connect_timeout" : 60000 , "id" : "abba6d52-b239-4b8f-ad11-1e7389d4cf71" , "protocol" : "http" , "name" : "example-flavors" , "read_timeout" : 60000 , "port" : 8080 , "path" : "/flavors/detail" , "updated_at" : 1551247705 , "retries" : 5 , "write_timeout" : 60000 } ] }
可以看到目前就我們前面新增的一個。
4.3 Add a route to service
有了服務之後,我們為服務填一個轉發路由:
curl -i -X POST \
- -url http: / /localhost:8001/services/example-flavors/routes \ - -data 'hosts[]=hb.ctyun.com' \ - -data 'paths[]=/flavors/detail' \ - -data 'name=flavor-detail'
得到的響應是 :
HTTP/1.1 201 Created
Date : Wed, 27 Feb 2019 06:24:00 GMT
Content-Type : application/json; charset=utf-8
Connection : keep-alive
Access-Control-Allow-Origin : *
Server : kong/1.0.3
Content-Length : 377
{ "created_at" : 1551248640 , "methods" : null , "id" : "11dbb4a1-7452-4d40-a45a-de3f3cad5275" , "service" : { "id" : "abba6d52-b239-4b8f-ad11-1e7389d4cf71" }, "name" : "flavor-detail" , "hosts" : [ "hb.ctyun.com" ], "updated_at" : 1551248640 , "preserve_host" : false , "regex_priority" : 0 , "paths" : [ "/flavors/detail" ], "sources" : null , "destinations" : null , "snis" : null , "protocols" : [ "http" , "https" ], "strip_path" : true }
原先獲取flavors 列表,我們是通過:
curl -X GET http: // localhost: 8080 /flavors/ detail
而我們現在可以直接通過Kong 進行訪問,注意,我們必須修改 Header ,新增指定的 Host 資訊:
curl -X GET http: // localhost: 8000 /flavors/ detail -H 'Host:hb.ctyun.com'
結果遇到了報錯,提示:
172.18.0.1 - - [27/Feb/2019:06:43:17 +0000] " GET /flavors/detail HTTP/1.1" 502 69 "-" "curl/7.54.0"
2019 / 02 / 27 06 : 43 : 17 [error] 36 # 0 : * 35879 connect() failed ( 111 : Connection refused) while connecting to upstream, client: 172.18.0.1 , server: kong, request: " GET /flavors/detail HTTP/1.1" , upstream: " , host: "hb.ctyun.com"
可以看到能夠按照路由規則進行轉發,但是由於網路問題(kong 部署在了 docker 容器中),所以沒有辦法進行訪問。
我們重新建立service 、 route ,並使用 來驗證:
# 執行一個容器,將本地的 8080 的請求轉發到容器的 80 埠
docker run -d --name simple-web-server \
--network kong-net \
-p 8080 : 80 kennethreitz/httpbin
# 建立名為 demo 的 service
curl -i -X POST \
--url http: //localhost:8001/services/ \
--data 'name=demo' \
--data 'url=
HTTP/ 1.1 201 Created
Date: Wed, 27 Feb 2019 07 : 51 : 45 GMT
Content-Type: application/json; charset=utf -8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/ 1.0.3
Content-Length: 256
{
"host" : "simple-web-server" ,
"created_at" : 1551253905 ,
"connect_timeout" : 60000 ,
"id" : "978de8a6-6767-4741-baca-a25c9a131f9d" ,
"protocol" : "http" ,
"name" : "demo" ,
"read_timeout" : 60000 ,
"port" : 80 ,
"path" : "/get" ,
"updated_at" : 1551253905 ,
"retries" : 5 ,
"write_timeout" : 60000
}
# 為 service demo 配置 route 規則
curl -i -X POST \
--url http: //localhost:8001/services/demo/routes \
--data 'hosts[]=api.ctyun.com' \
--data 'paths[]=/get' \
--data 'name=demo-get'
HTTP/ 1.1 201 Created
Date: Wed, 27 Feb 2019 07 : 52 : 40 GMT
Content-Type: application/json; charset=utf -8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/ 1.0.3
Content-Length: 361
{
"created_at" : 1551253960 ,
"methods" : null ,
"id" : "06d6754e-a4ae-4be6-9b87-b64ccfe6c920" ,
"service" : {
"id" : "978de8a6-6767-4741-baca-a25c9a131f9d"
},
"name" : "demo-get" ,
"hosts" : [
"api.ctyun.com"
],
"updated_at" : 1551253960 ,
"preserve_host" : false ,
"regex_priority" : 0 ,
"paths" : [
"/get"
],
"sources" : null ,
"destinations" : null ,
"snis" : null ,
"protocols" : [
"http" ,
"https"
],
"strip_path" : true
}
然後我們嘗試通過訪問 kong , 轉發到 httpbin :
curl -i -X GET http: //localhost:8000/get -H 'Host:api.ctyun.com'
HTTP/ 1.1 200 OK
Content- Type: application/json
Content- Length: 266
Connection: keep-alive
Server: gunicorn/ 19.9.0
Date: Wed, 27 Feb 2019 07 : 56 : 50 GMT
Access-Control-Allow- Origin: *
Access-Control-Allow- Credentials: true
X-Kong-Upstream- Latency: 9
X-Kong-Proxy- Latency: 84
Via: kong/ 1.0.3
{
"args" : {},
"headers" : {
"Accept" : "*/*" ,
"Connection" : "keep-alive" ,
"Host" : "simple-web-server" ,
"User-Agent" : "curl/7.54.0" ,
"X-Forwarded-Host" : "api.ctyun.com"
},
"origin" : "172.18.0.1" ,
"url" : "
}
至此,我們已經可以通過來源host 、 route 將請求換髮到指定的目標 host ,並且得到了返回值,這就算完成了基本 API 轉發流程。
4.4 Plugins
Kong 提供了非常豐富的外掛,都可以在 找得到。這裡我們簡單為我們的服務配置一個 的plugin 。
在服務demo 上啟用 key-auth 的外掛:
curl -X POST http: //localhost:8001/services/demo/plugins \
--data "name=key-auth"
{
"created_at" : 1551256029 ,
"config" : {
"key_names" : [
"apikey"
],
"run_on_preflight" : true ,
"anonymous" : null ,
"hide_credentials" : false ,
"key_in_body" : false
},
"id" : "4eaa000f-0fa2-4b3e-8c13-2db4c6b7ce49" ,
"service" : {
"id" : "978de8a6-6767-4741-baca-a25c9a131f9d"
},
"enabled" : true ,
"run_on" : "first" ,
"consumer" : null ,
"route" : null ,
"name" : "key-auth"
}
也可以在具體的 route 上啟用外掛 , 比如 :
curl -X POST http: // <host> :8001 /routes/{route_id} /plugins \
--data "name=key-auth"
我們這裡就不再贅述了。
開啟外掛後 , 再次訪問前面的 simple-web-server , 則有 :
curl -i -X GET http: //localhost:8000/get -H 'Host:api.ctyun.com'
HTTP/ 1.1 401 Unauthorized
Date: Wed, 27 Feb 2019 08 : 27 : 13 GMT
Content- Type: application/json; charset=utf -8
Connection: keep-alive
WWW- Authenticate: Key realm= "kong"
Content- Length: 41
Server: kong/ 1.0.3
{ "message" : "No API key found in request" }
此時外掛 key-auth 已經開啟了 , 開啟之後怎麼用呢 ? 要想使用鑑權外掛 , 離不開 Consumer 。如何建立 Consumer 並使用指定的外掛 , 我們放到 中盡心更詳細的介紹。
4.5 Add Consumers
新增一個 consumer , username 和 custom_id 指定任一即可 :
curl -i -X POST \
- -url http: / /localhost:8001/consumers/ \ - -data "username=<USERNAME>" \ - -data "custom_id=<CUSTOM_ID>"
如 :
curl -i -X POST \
--url http: //localhost:8001/consumers/ \
--data "username=elbarco"
HTTP/ 1.1 201 Created
Date: Wed, 27 Feb 2019 08 : 47 : 50 GMT
Content- Type: application/json; charset=utf -8
Connection: keep-alive
Access-Control-Allow- Origin: *
Server: kong/ 1.0.3
Content- Length: 107
{
"custom_id" : null ,
"created_at" : 1551257270 ,
"username" : "elbarco" ,
"id" : "738627ae-57e9-4b20-9d1d-fb12998d5296"
}
為使用者提供一個key :
curl -i -X POST \
--url http: //localhost:8001/consumers/elbarco/key-auth/ \
--data 'key=hola-elbarco'
HTTP/ 1.1 201 Created
Date: Wed, 27 Feb 2019 09 : 12 : 12 GMT
Content- Type: application/json; charset=utf -8
Connection: keep-alive
Access-Control-Allow- Origin: *
Server: kong/ 1.0.3
Content- Length: 147
{
"key" : "hola-elbarco" ,
"created_at" : 1551258732 ,
"consumer" : {
"id" : "738627ae-57e9-4b20-9d1d-fb12998d5296"
},
"id" : "b9cb021d-cb37-4841-b172-40ff2dcacb5e"
}
此時 , 我們就可以帶著鑑權訪問前面的 simple-web-server 了 , 有兩種方式 :
curl { proxy path}?apikey=<some_key>
curl { proxy path} \
-H 'apikey: <some_key>'
我們這裡任選一種即可 :
curl -i -X GET http: //localhost:8000/get -H 'Host:api.ctyun.com' -H 'apikey:hola-elbarco'
HTTP/ 1.1 200 OK
Content- Type: application/json
Content- Length: 398
Connection: keep-alive
Server: gunicorn/ 19.9.0
Date: Wed, 27 Feb 2019 09 : 19 : 31 GMT
Access-Control-Allow- Origin: *
Access-Control-Allow- Credentials: true
X-Kong-Upstream- Latency: 68
X-Kong-Proxy- Latency: 26
Via: kong/ 1.0.3
{
"args" : {},
"headers" : {
"Accept" : "*/*" ,
"Apikey" : "hola-elbarco" ,
"Connection" : "keep-alive" ,
"Host" : "simple-web-server" ,
"User-Agent" : "curl/7.54.0" ,
"X-Consumer-Id" : "738627ae-57e9-4b20-9d1d-fb12998d5296" ,
"X-Consumer-Username" : "elbarco" ,
"X-Forwarded-Host" : "api.ctyun.com"
},
"origin" : "172.18.0.1" ,
"url" : "
}
4.6 Rate limiting
額外的 , 我們再看一下限流外掛 : 。
5.Advanced Features
5.1 Load balancing
6.Kong Dashboard (From community)
Kong 的商業版中 , 提供了一個視覺化介面工具 , 叫做 , 功能很是強大 , 比如 :
試用需要申請,我們轉而在社群中尋求替代工具,於是在Github 上搜到了 ,提供了使用npm 和 docker 安裝兩種方式,這裡採用 docker 的方式安裝一下,看看效果:
# Start Kong Dashboard
docker run --rm -p 9090:8080 pgbi/kong-dashboard start --kong-url
# Start Kong Dashboard on a custom port
docker run --rm -p [port]:8080 pgbi/kong-dashboard start --kong-url
# Start Kong Dashboard with basic auth
docker run --rm -p 8080:8080 pgbi/kong-dashboard start \ --kong-url --basic-auth user1=password1 user2=password2
# See full list of start options
docker run --rm -p 8080:8080 pgbi/kong-dashboard start -- help
docker run --rm --name kong-dashboard -p 9090 :808i0 pgbi/kong-dashboard start --kong-url http: //locahost :8001
docker run --rm --network kong-net --name kong-dashboard -p 9090 :8080 pgbi/kong-dashboard start --kong-url http: //kong :8001
Connecting to Kong on http: //kong :8001 ...
This version of Kong dashboard doesn't support Kong v0.15 and higher.
受限於 Kong 的版本 :
docker container exec 999 a5cf1db1a kong version
1.0.3
我們沒辦法接入 kong-dashboard , 後面 再 進行調研吧。
7.Summary
kong 的模型比較清晰 , 從 service 、 route 、 plugin 到 upstream 、 consumer , 通用性比較強 , 因為外掛的存在 , 功能擴充套件性也很高。從我們的實際業務觸發,也可以參考借鑑這種模型方式,先從核心功能出發。
8.Reference
· [1].
· [2].
API 閘道器 :
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70014251/viewspace-2898701/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- API 閘道器 KongAPI
- kong 一個高效能的 API 閘道器API
- 閘道器服務Kong和konga介紹安裝使用教程
- kong閘道器部署
- 整合一套高效能閘道器Kong
- API閘道器:Apache APISIX 3.0與Kong 3.0比較APIApache
- Docker 安裝 Kong 閘道器Docker
- 高效能API閘道器(1)、微服務API閘道器架構設計API微服務架構
- 高效能微服務閘道器.NETCore客戶端Kong.Net開源釋出微服務NetCore客戶端
- 最新出爐!開源 API 閘道器的效能對比:APISIX 3.0 和 Kong 3.0API
- 微服務 API Gateway kong 閘道器實踐及jwt-header外掛開發微服務APIGatewayJWTHeader
- 30分鐘通過Kong實現.NET閘道器
- api閘道器設計API
- 開放API閘道器實踐(一) ——設計一個API閘道器API
- .net core自定義高效能的Web API服務閘道器WebAPI
- API閘道器,企業級閘道器可擴充套件API套件
- API 閘道器策略二三事API
- 【杭州活動】API 閘道器與高效能服務最佳實踐API
- http代理504閘道器超時錯誤原因介紹HTTP
- .Net Core微服務——閘道器(1):ocelot整合及介紹微服務
- 花5分鐘時間來了解一下高效能閘道器Kong會有意外收穫
- Api閘道器Kong整合Consul做服務發現及在Asp.Net Core中的使用APIASP.NET
- dubbo-gateway 高效能dubbo閘道器Gateway
- Spring Boot整合Zuul API閘道器Spring BootZuulAPI
- 微服務閘道器Kong 1.0正式釋出!提供100+項功能微服務
- 如何設計一個高效能閘道器
- API閘道器:第8層網路API
- 拆輪子:閘道器GOKU-API-GatewayGoAPIGateway
- 微服務實踐分享(2)api閘道器微服務API
- 八步部署NGINX Plus API閘道器NginxAPI
- 如何建設企業級API閘道器API
- 微服務基礎——厲害了!API閘道器微服務API
- 開放API閘道器實踐(三) —— 限流API
- 探索使用Nginx +Lua 構建 API 閘道器NginxAPI
- Janusec應用安全閘道器(WAF閘道器)
- Ceph物件閘道器,多區域閘道器物件
- 【12月14日廣州活動】API 閘道器與高效能服務最佳實踐API
- [12月14日廣州活動] API 閘道器與高效能服務最佳實踐API