Kong 网关简介及简单使用
Kong 网关简介及简单使用
1、kong 网关简介
Kong是在客户端和微服务端转发 API 通信的 API 网关,可以通过插件扩展功能。Kong 主要有两个重要的的组件:
- Kong Server:基于 nginx 的服务器,用来接收 API 请求
- Apache Cassandra:用于存储操作数据
我们可以通过增加更多的 Kong Server服务器对 Kong 服务进行水平扩展,通过前置的负载均衡器向这些机器发送分发请求。根据文档描述,两个 Cassandra 节点就足以支撑绝大多数情况,但如果网络非常拥挤,可以适当考虑增加更多的节点。
对于我们来说,Kong 中最为重要的一个特性就是可以通过插件扩展已有功能,这些插件在 API 请求响应循环的生命周期内被执行。插件使用 Lua 编写,而且 Kong 还有如下几个基础功能:
HTTP 基本认证,密匙认证,CORS(Cross-origin Resource Sharing,跨域资源共享),TCP,UDP,文件日志,API请求限流,请求转发及 Nginx 监控等等
2、docker 部署 kong
官方文档:https://hub.docker.com/_/kong/
设置网络
docker network create kong-net
安装数据库, PostgreSQL and Cassandra,推荐使用 postgres(版本号可自由选择)
docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:11.1-alpine
准备 kong 数据
docker run --rm \
--network=kong-net \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=kong-database" \
-e "KONG_CASSANDRA_CONTACT_POINTS=kong-database" \
kong:latest kong migrations bootstrap
启动kong,设置postgres 数据库
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 \
kong:latest
:8000 Kong 在该端口上侦听来自客户端的传入 HTTP 流量,并将其转发到上游服务
:8443 Kong 在其上侦听传入的 HTTPS 流量。此端口具有与端口 8000 类似的行为,不过他仅支持 HTTPS通信,可以通过配置文件禁用此端口
:8001 用于配置 Kong 侦听的 admin api
:8444 admin api 在其上侦听 HTTPS 流量
检查 kong 是否正常运行
curl -i http://localhost:8001/
安装图形化界面
docker run -d --name kong-dashboard \
--network=kong-net \
--link kong:kong \
-p 8081:8080 \
pgbi/kong-dashboard:v2 migrations up
3、配置服务
向 kong添加 API,我们需要先添加一个 service,即使用 kong 用来指代其管理的上游 API 和微服务的名称
我们将创建一个指向Mockbin API的服务。Mockbin是一个“回声”类型的公共网站,它将返回的请求返回给请求者,作为响应。这有助于了解Kong如何代理您的API请求。
在开始对服务提出请求之前,需要为其添加一条路由。路线指定到达香港后如何(以及是否)将请求发送到其服务。单个服务可以具有多个路由。
配置服务和路线后,您将可以使用它们通过Kong发出请求。
Kong 在port上公开了RESTful Admin API:8001
。Kong的配置(包括添加服务和路由)是通过该API上的请求进行的。
1)使用 admin api添加服务
发出以下cURL请求以将您的第一个服务(指向Mockbin API)添加到Kong:
curl -i -X POST \
--url http://localhost:8001/services/ \
--data 'name=example-service' \
--data 'url=http://mockbin.org'
内容回复:
HTTP/1.1 201 Created
Date: Fri, 07 Feb 2020 09:04:51 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.1
Content-Length: 296
X-Kong-Admin-Latency: 210
{"host":"mockbin.org","created_at":1581066291,"connect_timeout":60000,"id":"1148d98c-2eeb-4988-af84-d3173080bdd9","protocol":"http","name":"example-service","read_timeout":60000,"port":80,"path":null,"updated_at":1581066291,"retries":5,"write_timeout":60000,"tags":null,"client_certificate":null}%
SERVICES API详解
1、添加 services
请求地址:/service/
请求方法:POST
请求主体:
属性 | 描述 |
---|---|
name(可选) | 服务名称. |
protocol | 该协议用于与upstream通信。它可以是http(默认)或https。 |
host | upstream服务器的主机。 |
port | upstream服务器端口。默认为80 |
path(可选) | 在向upstream服务器请求中使用的路径。默认为空。 |
retries(可选) | 在代理失败的情况下执行的重试次数。默认值是5。 |
connect_timeout(可选) | 建立到upstream服务器的连接的超时时间。默认为60000。 |
write_timeout(可选) | 将请求发送到upstream服务器的两个连续写操作之间的超时时间。默认为60000。 |
read_timeout(可选) | 将请求发送到upstream服务器的两个连续读取操作之间的超时时间。默认为60000。 |
url(简写属性) | 将协议、主机、端口和路径立即设置成简短的属性。这个属性是只写的(管理API从来不“返回”url)。 |
2、查找 service
请求地址:/services/{name or id}
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
name or id(必填) | 检索的唯一标识符或服务名称。 |
请求地址:/routes/{route id}/service
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
route id(必填) | 属于要检索的服务的路由的唯一标识符。 |
3、查找 service 列表
请求地址:/services/
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
offset(可选) | 用于分页的游标。偏移量是定义列表中的位置的对象标识符。 |
size(可选,默认是100 max是1000) | 每个页面返回的对象数量的限制。 |
4、更新 service
请求地址:/service/{name or id}
请求方法:PATCH
请求主体:
属性 | 描述 |
---|---|
name or id(必填) | 要更新的服务的id或name属性。 |
请求地址:/routes/{route id}/service
请求方法:PATCH
请求主体:
属性 | 描述 |
---|---|
route id(必填) | 要更新服务的路由的id属性。 |
5、删除 service
请求地址:/services/{name or id}
请求方法:DELETE
请求主体:
属性 | 描述 |
---|---|
name or id(必填) | 要删除的服务的id或name属性。 |
2)添加服务路线
curl -i -X POST \
--url http://localhost:8001/services/example-service/routes \
--data 'hosts[]=example.com'
内容回复:
HTTP/1.1 201 Created
Date: Fri, 07 Feb 2020 09:05:40 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.1
Content-Length: 429
X-Kong-Admin-Latency: 26
{"id":"535592c2-c8b5-4f40-9a37-22f1dae115b8","path_handling":"v0","paths":null,"destinations":null,"headers":null,"protocols":["http","https"],"methods":null,"snis":null,"service":{"id":"1148d98c-2eeb-4988-af84-d3173080bdd9"},"name":null,"strip_path":true,"preserve_host":false,"regex_priority":0,"updated_at":1581066340,"sources":null,"hosts":["example.com"],"https_redirect_status_code":426,"tags":null,"created_at":1581066340}%
kong 现在知道服务名称,并准备代理请求
ROUTE API详解
1、添加 route
请求地址:/routes/
请求方法:POST
请求主体:
属性 | 描述 |
---|---|
protocols | 这条路线应该允许的协议列表。默认情况下,它是“http”、“https”,这意味着路由接受这两种方式。当设置为“HTTPS”时,HTTP请求会被请求升级到HTTPS。通过表单编码,符号是协议=http&协议=https。使用JSON,使用数组。 |
methods(半可选) | 与此路由相匹配的HTTP方法列表。例如: ["GET", "POST"].至少有一个主机、路径或方法必须被设置。用表单编码参数是methods[]=GET&methods[]=OPTIONS。使用JSON,使用数组。 |
hosts(半可选) | 与此路径匹配的域名列表。例如:example.com. 至少有一个主机、路径或方法必须被设置。用表单编码参数是 hosts[]=foo.com&hosts[]=bar.com。使用JSON,使用数组。 |
paths(半可选) | 与此路径相匹配的路径列表。例如: /my-path.至少有一个主机、路径或方法必须被设置。用表单编码参数是 paths[]=/foo&paths[]=/bar. 使用JSON,使用数组。 |
strip_path(可选) | 当通过一条路径匹配一条路径时,从upstream请求URL中剥离匹配的前缀。默认值为true。 |
preserve_host(可选) | 当通过一个主机域名匹配一条路由时,在upstream请求头中使用请求主机头。默认设置为false,upstream主机头将是服务主机的主机头。 |
service | 这条路线的服务是相关的。这是路由代理通信的地方。用表单编码参数是service.id=<service_id>。如果是JSON,则使用"service": |
2、查找 route
请求地址:/routes/{id}
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
id(必填) | 检索路由的id属性。 |
3、查找 route 列表
请求地址:/routes/
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
offset(可选) | 用于分页的游标。偏移量是定义列表中的位置的对象标识符。 |
size(可选,默认是100 max是1000) | 每个页面返回的对象数量的限制。 |
4、更新 route
请求地址:/routes/{id}
请求方法:PATCH
请求主体:
属性 | 描述 |
---|---|
id(必填) | 更新路由的id属性。 |
5、删除 route
请求地址:/route/{ id}
请求方法:DELETE
请求主体:
属性 | 描述 |
---|---|
id(必填) | 删除路由的id属性。 |
6、列出与 service 相关的 route
请求地址:/services/{service name or id}/routes
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
service name or id(必填) | 要检索路由的服务的id或name属性。当使用这个API时,只有属于指定服务的路由才会被列出。 |
3)通过 kong 转发请求
发出以下cURL请求,以验证Kong是否正确地将请求转发到您的服务。请注意,默认情况下, Kong在port上处理代理请求:8000
:
curl -i -X GET \
--url http://localhost:8000/ \
--header 'Host: example.com'
如果成功响应,表示 kong 已经成功转发我们的请求,转发 url 地址为步骤 1 中的地址
4、启用插件
Kong的核心原则之一是其通过插件的可扩展性。插件使我们可以轻松地向服务中添加新功能或使其更易于管理。
在下面的步骤中,将配置key-auth插件以向服务添加身份验证。在添加此插件之前, 对服务的所有请求都将在上游被代理。添加并配置此插件后,只会代理具有正确密钥的请求-Kong将拒绝所有其他请求,从而保护上游服务免遭未经授权的使用。
1)配置密匙身份验证插件
curl -i -X POST \
--url http://localhost:8001/services/example-service/plugins/ \
--data 'name=key-auth'
注意:此插件还接受一个config.key_names
参数,默认为['apikey']
。它是应该在请求期间包含apikey的标头和参数名称(均受支持)的列表。
内容回复:
HTTP/1.1 201 Created
Date: Fri, 07 Feb 2020 09:15:07 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.1
Content-Length: 363
X-Kong-Admin-Latency: 52
{"created_at":1581066907,"config":{"key_names":["apikey"],"run_on_preflight":true,"anonymous":null,"hide_credentials":false,"key_in_body":false},"id":"c032c177-dac4-435b-a3b6-b39edd9c11fe","service":{"id":"1148d98c-2eeb-4988-af84-d3173080bdd9"},"enabled":true,"protocols":["grpc","grpcs","http","https"],"name":"key-auth","consumer":null,"route":null,"tags":null}%
2)确认插件配置正确
curl -i -X GET \
--url http://localhost:8000/ \
--header 'Host: example.com'
由于未指定所需的apikey 标题或者参数,因此响应应为 401authorized
内容回复:
HTTP/1.1 401 Unauthorized
Date: Fri, 07 Feb 2020 09:15:28 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
WWW-Authenticate: Key realm="kong"
Content-Length: 41
X-Kong-Response-Latency: 14
Server: kong/2.0.1
{"message":"No API key found in request"}%
5、添加消费者
通过 restful api 创建消费者
curl -i -X POST \
--url http://localhost:8001/consumers/ \
--data "username=Jason"
内容回复:
HTTP/1.1 201 Created
Date: Fri, 07 Feb 2020 09:22:44 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.1
Content-Length: 117
X-Kong-Admin-Latency: 46
{"custom_id":null,"created_at":1581067364,"id":"947b5a94-f0d1-4955-9903-d5d489be4015","tags":null,"username":"Jason"}%
注意:custom_id
在创建使用者以将使用者与现有用户数据库相关联时,Kong还接受参数。
CONSUMER API 详解:
1、创建Consumer
请求地址:/consumers/
请求方法:POST
请求主体:
属性 | 描述 |
---|---|
username(半可选) | 用户的唯一用户名。username 或custom_id 二选一。 |
custom_id(半可选) | 消费者存储唯一ID - 用于现有数据库中的用户进行映射。username 或custom_id 二选一。 |
2、检索Consumer
请求地址:/consumers/{username or id}
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
username or id(必选) | 要检索的消费者的唯一标识符或用户名。 |
3、Consumer列表
请求地址:/consumers/
请求方法:GET
请求主体:
属性 | 描述 |
---|---|
id(可选) | 基于消费者id 字段的过滤器。 |
custom_id(可选) | 基于消费者custom_id 字段的过滤器。 |
username(可选) | 基于消费者username 字段的过滤器。 |
offset(可选) | 用于分页的游标。偏移量是定义列表中的位置的对象标识符。 |
size(可选,默认是100) | 每个页面返回的对象数量的限制。 |
4、更新Consumer
请求地址:/consumers/{username or id}
请求方法:PATCH
请求主体:
属性 | 描述 |
---|---|
username or id(必选) | 更新的唯一标识符或用户名。 |
请求主体:同1、添加Consumer
5、更新或创建Consumer
请求地址:/consumers/
请求方法:PUT
请求主体:同1、添加Consumer
6、删除Consumer
请求地址:/consumers/{username or id}
请求方法:DELETE
请求主体:
属性 | 描述 |
---|---|
username or id(必选) | 更新的唯一标识符或用户名。 |
2)为消费者提供关键凭证
现在,我们可以Jason
通过发出以下请求为我们最近创建的使用者创建密钥:
curl -i -X POST \
--url http://localhost:8001/consumers/Jason/key-auth/ \
--data 'key=ENTER_KEY_HERE'
内容回复:
HTTP/1.1 201 Created
Date: Fri, 07 Feb 2020 09:27:40 GMT
Content-Type: application/json; charset=utf-8
Connection: keep-alive
Access-Control-Allow-Origin: *
Server: kong/2.0.1
Content-Length: 172
X-Kong-Admin-Latency: 56
{"created_at":1581067660,"consumer":{"id":"947b5a94-f0d1-4955-9903-d5d489be4015"},"id":"6b59a5e1-fa04-4d4b-b3b1-2e044b9c0605","tags":null,"ttl":null,"key":"ENTER_KEY_HERE"}%
3)验证消费者凭证有效
现在,我们可以发出以下请求来验证我们的Jason
消费者凭证是否有效:
curl -i -X GET \
--url http://localhost:8001 \
--header "Host: example.com" \
--header "apikey: ENTER_KEY_HERE"
内容回复:
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Content-Length: 10695
Connection: keep-alive
Server: Cowboy
Etag: W/"29c7-XG+PICJmz/J+UYWt5gkKqqAUXjc"
Vary: Accept-Encoding
Date: Fri, 07 Feb 2020 09:28:04 GMT
Via: kong/2.0.1
X-Kong-Upstream-Status: 200
X-Kong-Upstream-Latency: 746
X-Kong-Proxy-Latency: 1523
Kong-Cloud-Request-ID: 3a1112d6c34f47aeb5df4ba2435b0f70
如果正常响应表示该消费者请求被kong成功转发并返回数据