转载 李亚飞 大佬的文章:https://www.lyafei.com/

背景

我们有批设备卖给了海外的服务商,老外请了第三方检测机构,检测设备与我们系统的安全性,结果找到了近 40+ 的安全漏洞,有很大一部分的安全漏洞提炼出来,其实可以统一解决掉,因为涉及服务和安卓组件太多,如果一个一个修改,不管是时间还是人力投入都很巨大,那快速并且改动最小的方法就是从网关上解决这些问题。

网关是微服务中不可或缺的一部分,它承载了所有请求流量入口,参数验证拦截,用户权限验证等,但是除了 JAVA 的 spring cloud 之外,公共网关屈指可数,其中最受关注的就是 Kong 了,在这里给大家分享一下 kong 网关的基本情况以及使用安装的方式。

Kong 是在客户端和(微)服务间转发 API 通信的 API 网关,通过插件扩展功能。Kong 有两个主要组件:

  1. Kong Server :基于 nginx 的服务器,用来接收 API 请求
  2. Apache Cassandra:用来存储操作数据

你可以通过增加更多 Kong Server 机器对 Kong 服务进行水平扩展,通过前置的负载均衡器向这些机器分发请求。根据文档描述,两个 Cassandra 节点就足以支撑绝大多数情况,但如果网络非常拥挤,可以考虑适当增加更多节点。

对于开源社区来说,Kong 中最诱人的一个特性是可以通过插件扩展已有功能,这些插件在 API 请求响应循环的生命周期中被执行。插件使用 Lua 编写,而且 Kong 还有如下几个基础功能:HTTP 基本认证、密钥认证、CORS( Cross-origin Resource Sharing,跨域资源共享)、TCP、UDP、文件日志、API 请求限流、请求转发以及 nginx 监控。

附上:
Kong 官网:https://konghq.com/
Kong GitHub地址:https://github.com/kong/kong

Why Kong?

if you are building for the web, mobile, or IoT (Internet of Things) you will likely end up needing common functionality to run your actual software. Kong can help by acting as a gateway (or a sidecar) for microservices requests while providing load balancing, logging, authentication, rate-limiting, transformations, and more through plugins.

在这里插入图片描述

以上是官网的解释,在网上搜索总结了下 Kong 的主要优势:

  • 插件市场丰富,很多插件可以降低开发成本
  • 可扩展性,可以编写 lua 脚本来定制自己的参数验证权限验证等操作
  • 基于 openResty,openResty 基于 Nginx 保障了强劲的性能
  • 便捷性能扩容,只需要水平增加服务器资源性能就能提升
  • 负载均衡健康检查

Docker安装Kong

本文使用的是 Kong 最新版本
postgreSql 数据库版本必须 > 9.4

有关如何在 Docker 中使用 Kong 的详细信息,可以在托管该映像的 DockerHub 存储库中找到:kong。并且还有一个具有内置编排和可伸缩性的 Docker Compose 模板

数据库模式

创建一个Docker网络

因为不是通过 docker-composer 启动的容器需要互相访问需要在同一个网络名下才可以互相访问,所以需要创建一个自定义网络,以使容器能够发现彼此并进行通信。在本文示例中 kong-net 为网络名称,你可以使用任何名称

[root@izbp12g2yvanoh4aaqyse0z ~]# docker network create kong-net
30c81260684556d5e9dec685cdb948dde8235875d84c93ad33c411ee6379eaa4
启动数据库

这里提供了 Kong 容器连接到 Cassandra 或 PostgreSQL 容器,两种方式
如果你想使用 Cassandra 容器:

docker run -d --name kong-database \
           --network=kong-net \
           -p 9042:9042 \
           cassandra:3

如果你想使用 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:9.6

在这里我选择使用 PostgreSQL 数据库

[root@izbp12g2yvanoh4aaqyse0z ~]# 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:9.6
Unable to find image 'postgres:9.6' locally
9.6: Pulling from library/postgres
b248fa9f6d2a: Pull complete 
8ce5aee1dc0e: Pull complete 
......
......
db910e83d79a: Pull complete 
03cde239cd9d: Pull complete 
Digest: sha256:5c5e70504814776a669b154ed563ea63566425a5c1d61ed985b7c3fe8103412a
Status: Downloaded newer image for postgres:9.6
9f992ef6ed452190e6f514e4761bd959f20bb844dd0156df826f2a3f4e2f4da0
准备数据库

使用临时 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

Kong < 0.15的注意事项:Kong 版本低于 0.15(最大0.14)时,请使用 up 子命令代替 bootstrap。还要注意,Kong < 0.15时,永远不要同时运行迁移。一次只能有一个 Kong 节点执行迁移。对于 0.15、1.0 及更高版本,此限制被取消。

[root@izbp12g2yvanoh4aaqyse0z ~]# 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
Unable to find image 'kong:latest' locally
latest: Pulling from library/kong
4167d3e14976: Pull complete 
691048dd26e3: Pull complete 
e71040f3ce48: Pull complete 
Digest: sha256:f7a2bb6ae3baf60e3ca0d6ba5f83ebe3caf64fe8b6aa8dd6a5d3df16a22775c2
Status: Downloaded newer image for kong:latest
Bootstrapping database...
migrating core on database 'kong'...
core migrated up to: 000_base (executed)
core migrated up to: 003_100_to_110 (executed)
core migrated up to: 004_110_to_120 (executed)
core migrated up to: 005_120_to_130 (executed)
core migrated up to: 006_130_to_140 (executed)
core migrated up to: 007_140_to_150 (executed)
core migrated up to: 008_150_to_200 (executed)
migrating hmac-auth on database 'kong'...
hmac-auth migrated up to: 000_base_hmac_auth (executed)
hmac-auth migrated up to: 002_130_to_140 (executed)
migrating oauth2 on database 'kong'...
oauth2 migrated up to: 000_base_oauth2 (executed)
oauth2 migrated up to: 003_130_to_140 (executed)
migrating jwt on database 'kong'...
jwt migrated up to: 000_base_jwt (executed)
jwt migrated up to: 002_130_to_140 (executed)
migrating basic-auth on database 'kong'...
basic-auth migrated up to: 000_base_basic_auth (executed)
basic-auth migrated up to: 002_130_to_140 (executed)
migrating key-auth on database 'kong'...
key-auth migrated up to: 000_base_key_auth (executed)
key-auth migrated up to: 002_130_to_140 (executed)
migrating rate-limiting on database 'kong'...
rate-limiting migrated up to: 000_base_rate_limiting (executed)
rate-limiting migrated up to: 003_10_to_112 (executed)
migrating acl on database 'kong'...
acl migrated up to: 000_base_acl (executed)
acl migrated up to: 002_130_to_140 (executed)
migrating acme on database 'kong'...
acme migrated up to: 000_base_acme (executed)
migrating response-ratelimiting on database 'kong'...
response-ratelimiting migrated up to: 000_base_response_rate_limiting (executed)
migrating session on database 'kong'...
session migrated up to: 000_base_session (executed)
24 migrations processed
24 executed
Database is up-to-date
启动kong-service

运行迁移并准备好数据库后,启动将连接到数据库容器的 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 8000:8000 \
     -p 8443:8443 \
     -p 127.0.0.1:8001:8001 \
     -p 127.0.0.1:8444:8444 \
     kong:latest

8000,监听来自客户端的 HTTP 流量,转发到你的 upstream 服务上
8443,监听 HTTPS 的流量,功能跟 8000 一样。可以通过配置文件禁止
8001,Kong的HTTP监听的api管理接口
8444,Kong的HTTPS监听的API管理接口

[root@izbp12g2yvanoh4aaqyse0z ~]# 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 8000:8000 \
>      -p 8443:8443 \
>      -p 127.0.0.1:8001:8001 \
>      -p 127.0.0.1:8444:8444 \
>      kong:latest
aaff8bde816bdb5f853b48e813e03e6512ed1c4f9c7595daa0bacc0118f7a6a2

在这里插入图片描述

使用Kong

调用一下地址有输出即可

curl -i http://localhost:8001/

无数据库模式

在无数据库模式下启动 Kong 的步骤如下:

创建一个Docker网络

这与上面数据库模式相同。也使用 kong-net 网络名称,也可以将其更改为其他名称。

docker network create kong-net

在无数据库模式下运行 Kong 并非必须严格执行此步骤,但是如果你将来要添加其他内容(例如由 Redis集群备份的限速插件),则这是一个很好的预防措施。

创建一个Docker卷

Docker Volume 是主机内部的一个文件夹,可以映射到容器中的文件夹。数据卷有一个名称。在这种情况下,命名为 kong-vol

docker volume create kong-vol

查看该数据卷是否存在

docker volume inspect kong-vol

会返回一个 json,类似以下内容

[
      {
          "CreatedAt": "2020-04-24T15:40:09Z",
          "Driver": "local",
          "Labels": {},
          "Mountpoint": "/var/lib/docker/volumes/kong-vol/_data",
          "Name": "kong-vol",
          "Options": {},
          "Scope": "local"
      }
 ]

注意 MountPoint 目录。下一步,我们需要该路径。

准备声明性配置文件

语法和属性在 Kong 官网的 “声明性配置格式” 说明中描述。

在此添加你需要的任何核心实体(服务,路由,插件,使用者等)。

假设为它命名 kong.yml,将其保存 MountPoint 目录下:/var/lib/docker/volumes/kong-vol/_data/kong.yml

无数据库模式下启动Kong

尽管可以修改参数 KONG_DATABASE = off 来启动 Kong 容器,但通常还是希望通过 KONG_DECLARATIVE_CONFIG 变量名将声明性配置文件作为参数包括在内。为此,我们需要使文件在容器内“可见”。我们使用 -v 标志来实现这一点,该标志将 kong-vol 卷映射到 /usr/local/kong/declarative 容器中的文件夹。

docker run -d --name kong \
     --network=kong-net \
     -v "kong-vol:/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 127.0.0.1:8001:8001 \
     -p 127.0.0.1:8444:8444 \
     kong:latest

使用Kong

Kong 应该正在运行,并且应该包含 kong.yml 中添加的一些实体:

curl -i http://localhost:8001/

例如,获取服务列表:

curl -i http://localhost:8001/services
Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐