首页 > 自动化运维 > 大规模网络运维 > 高性能API网关Kong介绍
本文关键词:高性能、API网关、Kong、微服务
API 网关 ( ) 是随着微服务( Microservice )概念兴起的一种架构模式。原本一个庞大的单体应用( All in one )业务系统被拆分成许多微服务( Microservice )系统进行独立的维护和部署,服务拆分带来的变化是 API 的规模成倍增长, API 的管理难度也在日益增加,使用 API 网关发布和管理 API 逐渐成为一种趋势。一般来说, API 网关是运行于外部请求与内部服务之间的一个流量入口,实现对外部请求的协议转换、鉴权、流控、参数校验、监控等通用功能。
本文即将介绍的 , 是一个开源的API gateway 和微服务管理的工具,基于 Nginx 和 (特殊的 ),Kong 具有可插拔的架构,使其功能强大且灵活。
· 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 等等。
官方文档提供了多种环境下详细的 。我们这里使用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.
在本地配置 Kong 完毕后 , 我们来感受一下 Kong 强大的特性。首先我们有一个简单的 API 服务 , 之前已经写好的一个 flavors 的增删改查 , 以 flavors 的查询为例 , 我们将 GET /flavors/detail 添加到 Kong 中。
我们的API server 地址是 ,于是我们有:
· route path: /flavors/detail
· service host:
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 }
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 } ] }
可以看到目前就我们前面添加的一个。
有了服务之后,我们为服务填一个转发路由:
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 转发流程。
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 并使用指定的插件 , 我们放到 中尽心更详细的介绍。
添加一个 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" : "
}
额外的 , 我们再看一下限流插件 : 。
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 , 后面 再 进行调研吧。
kong 的模型比较清晰 , 从 service 、 route 、 plugin 到 upstream 、 consumer , 通用性比较强 , 因为插件的存在 , 功能扩展性也很高。从我们的实际业务触发,也可以参考借鉴这种模型方式,先从核心功能出发。
· [1].
· [2].
API 网关 :
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70014251/viewspace-2898701/ ,如需转载,请注明出处,否则将追究法律责任。