微服务网关Kong安装试用和实践总结

220 阅读4分钟

一、安装

1、由于不想用PostgreSQL和Cassandra数据库,所以我选择的是无DB模式(DB-less mode)

2、选择Docker模式安装,避免环境配置问题。

Docker安装步骤如下:

docker pull kong:2.3.3
 
docker network create kong-net
 
mkdir -p /hot_data/kong1
 
docker run -d --name kong1 \
     --network=kong-net \
     -v /hot_data/kong1:/usr/local/kong/declarative \
     -e "KONG_DATABASE=off" \
     -e "KONG_DECLARATIVE_CONFIG=/usr/local/kong/declarative/kong.yml" \
     -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:2.3.3

# 查看启动日志

docker logs kong1

# 启动成功后验证

curl -i http://localhost:8001/

具体参见官方文档:docs.konghq.com/install/doc…

3、选择一个kong admin API的图形界面,由于KongA已经停更,我选择了pocketdigi/kong-admin-ui

安装方法如下:

docker run -d --name kong-admin-ui -p
8899:80 pocketdigi/kong-admin-ui:0.5.2

然后访问http://localhost:8899即可。

二、配置

在当前目录下创建kong.yml文件,内容如下:

_format_version: "2.1"
_transform: true
 
upstreams:
- name: talos
  targets:
  - target: 192.168.66.11:6600
    weight: 100
 
services:
- name: talos-service
  host: talos
 
routes:
- name: talos-route
  service: talos-service
  hosts: ["hello.talos.com"]

    然后执行admin api可以让配置生效(实时生效、无需重启):

curl 
-X POST -F "config=@kong.yml" --url
http://192.168.66.11:8001/config

其中@kong.yml是指该文件路径为当前目录,后面http url为kong admin的地址。

配置说明:

四个概念:Upstream、Target、Service、Route

• Target:是最终处理请求的Backend服务。

• Upstream:Target集合的负载均衡策略。

• Services:是多个Upstream的集合,根据Route转发。

• Route:是请求的转发规则,按照Hostname和PATH,将请求转发给Service。

下面是一个完整配置例子:

(注意,下面是例子是基于DB模式的,对于DB-less模式,只能通过kong.yml文件来配置,然后post提交kong.yml即可)

# 创建一个upstream

$ curl -X POST http://kong:8001/upstreams \
--data "name=address.v1.service"

# 给upstream添加两个target

$ curl -X POST http://kong:8001/upstreams/address.v1.service/targets \
    --data "target=192.168.34.15:80" \
    --data "weight=100"
$ curl -X POST http://kong:8001/upstreams/address.v1.service/targets \
    --data "target=192.168.34.16:80" \
    --data "weight=50"

# 创建一个把Blue上游作为目标的Service

$ curl -X POST http://kong:8001/services/  \
    --data "name=address-service"  \
    --data "host=address.v1.service" \
    --data "path=/address"

# 最后,为Service添加Route

$ curl -X POST
http://kong:8001/services/address-service/routes/ \
--data "hosts[]=address.mydomain.com"

然后在操作系统的hosts路由里面绑定:

192.168.66.11(kong地址) address.mydomain.com

然后访问:address.mydomain.com:8000/,即可达到Target…

如果要做**“蓝绿发布”**的话,上面的配置为“蓝”,下面再添加一套“绿”配置如下:

# 为地址服务v2,创建一个新的Green upstream

$ curl -X POST http://kong:8001/upstreams \ 
--data "name=address.v2.service"

# 给upstream添加两个目标

$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \
    --data "target=192.168.34.17:80"
    --data "weight=100"
$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \
    --data "target=192.168.34.18:80" \
    --data "weight=100"

    然后把Service的Upstream切换为“绿”配置,流量就“全绿”了。

# 将服务从Blue环境转换为Green环境, v1 -> v2

$ curl -X PATCH
http://kong:8001/services/address-service \
--data "host=address.v2.service"

类似地,“金丝雀”发布,只要改变Target的权重即可,比如最开始为100:0,然后改成95:5,然后改成80:20,就可以逐步控制流量的进入,如下所示。

# 第一个目标权重 800

$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \
    --data "target=192.168.34.17:80" \
    --data "weight=900"

# 第二个目标权重 200

$ curl -X POST http://kong:8001/upstreams/address.v2.service/targets \
    --data "target=192.168.34.18:80" \
    --data "weight=200"

    实际上Upstream和Service的配置,类似于下面的Nginx配置:

upstream address.v1.service {
  server 192.168.34.15:80;
  server 192.168.34.16:80;
}
server {
  listen 8000;
  location / {
    proxy_pass http://address.v1.service;
  }
}

   在网关集成登录身份验证:

由于是微服务应用,所以后端不使用Session,最常用的方案就是JWT Token。

Kong对 JWT身份验证 支持较好。

首先,Kong支持多种身份验证方式(Basic Auth、JWT、Key Auth等),通用认证流程如下:

  1. 向一个API或全局添加AUTH插件(此插件不作用于consumers);
  2. 创建一个consumer对象;
  3. 为consumer提供指定的验证插件方案的身份验证凭据;
  4. 现在,只要有请求进入Kong,都将检查其提供的身份验证凭据(通常在header或者url参数中,取决于auth类型),如果该请求无法被验证或者验证失败,则请求会被锁定,不执行向上有服务转发的操作。

但是,上述的一般流程并不是总是有效的。譬如,当使用了外部验证方案(比如LDAP)时,KONG就不会(不需要)对consumer进行身份验证。

什么是Consumers?

最简单的理解和配置consumer的方式是,将其于用户进行一一映射,即一个consumer代表一个用户(或应用)。但是对于KONG而言,这些都无所谓。consumer的核心原则是你可以为其添加插件,从而自定义他的请求行为。所以,或许你会有一个手机APP应用,并为他的每个版本都定义一个consumer,又或者你又一个应用或几个应用,并为这些应用定义统一个consumer,这些都无所谓。这是一个模糊的概念,他叫做consumer,而不是user!万万要区分开来,且不可混淆。

具体JWT验证方式就不讲了,直接看官方文档吧。值得说明的是,Kong的JWT验证是标准的验证方法,而且还支持对过期时间进行检验。如果需要防重放等特殊验证方法,则标准组件不适合,只能自己写插件。

插件开发:

基于Lua语言,有相关的Demo工程和文档,以及很多现成的插件代码可以参考。

容易实现的功能有:内存缓存,连接Redis,发送HTTP请求。但暂时没找到连接MySQL的例子。

另外,也可以使用Golang写插件,官方曾经弄了一个方案及Demo,但案例不多,还处于非常原始阶段。