Kong API Gateway 安装

来自Linux78|wiki

什么是API网关

在微服务的架构中,一个应用可能背拆分许多个小的服务系统,这些小系统可能自成一体,有自己的硬件资源、数据库、框架,甚至连语言都各不相同,这些小系统通常以Restfull API风格的借口提供给前端或者其他系统调用,一个应用可能会被拆分上百上千个API,管理起来极其不变,这个时候出现了API网关,API网关提供了一个统一的入口,将流量转发给对应的后端取得数据后再一次返回,并且在次基础上提供各种认证鉴权流控等等功能让后端专心于自己的业务。

使用API网关带来一下几个好处:

统一API入口

隔离后端

认证鉴权流控

负载均衡

降低后端开发对API安全性的考虑

其实无论是否是微服务的架构,只要用到了认证鉴权流控功能,我觉得都应该使用API网关,这将大大减低后端开发的成本和速度,未来扩张也方便。

目前各大云厂商都可用了商用的API网关,例如阿里云,功能强大,性能稳定,如果应用于云上的生产环境,也可以考虑。

当然开源社区中也提供几种开源的方案

名称	说明
Tyk	Tyk是一个开放源码的API网关,它是快速、可扩展和现代的。Tyk提供了一个API管理平台,其中包括API网关、API分析、开发人员门户和API管理面板。Try 是一个基于Go实现的网关服务。
Kong	Kong是一个可扩展的开放源码API Layer(也称为API网关或API中间件)。Kong 在任何RESTful API的前面运行,通过插件扩展,它提供了超越核心平台的额外功能和服务。
Orange	Orange和Kong类似也是基于OpenResty的一个API网关程序,是由国人开发的。
Zuul	Zuul是一种提供动态路由、监视、弹性、安全性等功能的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
apiaxle	Nodejs 实现的一个 API 网关。
api-umbrella	Ruby 实现的一个 API 网关。

在以上的产品中,个人还是比较推荐是用kong的,kong基于nginx,使用了lua语言,这将大大提供了性能和稳定性。

什么是Kong

Kong是一个在Nginx中运行的Lua应用程序,并且通过lua-nginx模块实现。Kong不是用这个模块编译Nginx,而是与OpenResty一起发布,OpenResty已经包含了lua-nginx-module

OpenResty 也不是 Nginx的分支,而是一组扩展其功能的模块。

Kong是一个可扩展的开源API网关,运作在RESTfull API之前,提供统一的入口,并且通过插件的形式进行扩展,插件提供了平台核心功能意外的功能和服务,例如鉴权、流控等等。

Kong是有Mashape公司开发,最早用于内部,管理着超过15000个API和微服务,每月产生数十亿个请求。

Kong是一个可扩展的服务,只需要添加多台服务器就可以配置成一个集群,kong的插件可以轻松扩张kong的功能和能力。

安装Kong

Kong支持PostgreSQL 9.5+ 和Cassandra 3.xx 作为其数据存储。所以在安装Kong之前需要先安装配置好数据库centos7 安装postgresql10,并且给Kong创建好数据库和用户名等等

Kong提供了丰富的安装方式,可以基于docker来安装kong,也可以使用包管理器来安装它。

本文使用的资源如下:

系统:centos 7.6 Kong版本:1.4.0 OpenResty 版本:1.15.8.2. postgresql 版本:10.10 1、通过包管理器来安装 通过包管理器来安装极其简单,执行一下命令即可。

wget https://bintray.com/kong/kong-rpm/download_file?file_path=centos/7/kong-1.4.0.el7.amd64.rpm
yum install kong-1.4.0.el7.amd64.rpm

查看安装目录

whereis kong
kong: /etc/kong /usr/local/bin/kong /usr/local/kong

如上,/ect/kong目录为配置文件目录,安装后会有一个官方的默认配置文件kong.conf.default 复制这个文件为kong.conf即可启动Kong.

/usr/local/kong为Kong的运行目录,Kong启动后会生成nginx的配置文件放在此目录,当然缓存文件也会存放在这个目录中。

Kong的配置文件中,如果没有启用某一项目配置,那么Kong会使用其默认的配置文件.

Kong基于openresty,所以通过包管理器来安装也会安装openresty,安装目录为/usr/local/openresty/

基本上我们不需要去修改这个目录,如果需要修改nginx的配置,我们可以通过Kong的配置文件注入nginx配置,Kong在启动的时候会生成nginx的配置文件。

创建postgresql用户

create user kong;
alter user kong with password 'kong';
create database kong owner kong;
grant all privileges on database kong to kong;

配置Kong DataSource

# 创建配置 cp kong.conf.default kong.conf
vim /etc/kong/kong.conf
# 修改数据库配置
database = postgres             # Determines which of PostgreSQL or Cassandra
pg_host = 127.0.0.1             # The PostgreSQL host to connect to.
pg_port = 5432                  # The port to connect to.
pg_user = kong                  # The username to authenticate if required.
pg_password = 123456            # The password to authenticate if required.
pg_database = kong              # The database name to connect to.

启动Kong

Kong提供了CLI以此来控制Kong的启动停止等等的操作,我们可以通过kong --help命令来查看CLI提供了哪些功能,如下:

kong --help
No such command: --help

Usage: kong COMMAND [OPTIONS] 

The available commands are:
check
health
migrations
prepare
quit
reload
restart
roar
start
stop
version

Options:
--v              verbose
--vv             debug

对应的参数功能如下:

参数	功能
check	检查配置文件
health	检查节点的健康状态
migrations	迁移数据库,再第一次配置Kong时候必须要运行此命令,用来初始化数据库.. 
数据库的信息保存再配置文件中,所以使用此命令需要通过-c指定配置文件
prepare	在配置的前缀目录中准备Kong前缀。这个命令可以用于从nginx二进制文件启动Kong而不使用'kong start'
quit	优雅的停止Kong,在退出之前会先处理完已经接受到的请求
reload	重载配置文件
restart	重启Kong
roar	这个参数我也不知道干什么的,可能只是打印出吉祥物?
start	启动Kong,通过-c来指定配置文件
stop	停止运行Kong
version	查看版本
--v	以上任意参数都可以加张-v选项,此选修会打印出信息。
--vv	以上任意参数都可以加张-v选项,此选修会打印出更为丰富的debug信息。

现在启动Kong,因为是第一次启动,所以需要先运行迁移命令,以初始化数据库。

kong migrations list -c /etc/kong/kong.conf -v
2019/11/19 03:08:14 [verbose] Kong: 1.4.0
2019/11/19 03:08:14 [verbose] reading config file at /etc/kong/kong.conf
2019/11/19 03:08:14 [verbose] prefix in use: /usr/local/kong
2019/11/19 03:08:15 [verbose] retrieving database schema state...
2019/11/19 03:08:15 [verbose] schema state retrieved
2019/11/19 03:08:15 [info] Database needs bootstrapping; run 'kong migrations bootstrap'
kong migrations bootstrap
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)
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)
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)
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: 001_14_to_15 (executed)
oauth2 migrated up to: 002_15_to_10 (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: 001_14_to_15 (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: 001_14_to_15 (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: 001_14_to_15 (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: 001_14_to_15 (executed)
rate-limiting migrated up to: 002_15_to_10 (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: 001_14_to_15 (executed)
acl migrated up to: 002_130_to_140 (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)
migrating session on database 'kong'...
session migrated up to: 000_base_session (executed)
34 migrations processed
34 executed
Database is up-to-date

如上,在migrations参数中,还可以跟上list、up、reset的参数,其中,list是显示当前迁移的信息,up参数查询缺少的部分,并且修复、reset的重置所有的迁移

迁移成功之后可以使用kong start来启动Kong

kong start -c /etc/kong/kong.conf --vv
2019/11/19 03:12:28 [verbose] Kong: 1.4.0
2019/11/19 03:12:28 [debug] ngx_lua: 10015
2019/11/19 03:12:28 [debug] nginx: 1015008
2019/11/19 03:12:28 [debug] Lua: LuaJIT 2.1.0-beta3
2019/11/19 03:12:28 [verbose] reading config file at /etc/kong/kong.conf
2019/11/19 03:12:28 [debug] reading environment variables
2019/11/19 03:12:28 [debug] admin_access_log = "logs/admin_access.log"
2019/11/19 03:12:28 [debug] admin_error_log = "logs/error.log"
2019/11/19 03:12:28 [debug] admin_listen = {"127.0.0.1:8001","127.0.0.1:8444 http2 ssl"}
2019/11/19 03:12:28 [debug] anonymous_reports = true
2019/11/19 03:12:28 [debug] cassandra_consistency = "ONE"
2019/11/19 03:12:28 [debug] cassandra_contact_points = {"127.0.0.1"}
2019/11/19 03:12:28 [debug] cassandra_data_centers = {"dc1:2","dc2:3"}
2019/11/19 03:12:28 [debug] cassandra_keyspace = "kong"
2019/11/19 03:12:28 [debug] cassandra_lb_policy = "RequestRoundRobin"
2019/11/19 03:12:28 [debug] cassandra_port = 9042
2019/11/19 03:12:28 [debug] cassandra_refresh_frequency = 60
2019/11/19 03:12:28 [debug] cassandra_repl_factor = 1
2019/11/19 03:12:28 [debug] cassandra_repl_strategy = "SimpleStrategy"
2019/11/19 03:12:28 [debug] cassandra_schema_consensus_timeout = 10000
2019/11/19 03:12:28 [debug] cassandra_ssl = false
2019/11/19 03:12:28 [debug] cassandra_ssl_verify = false
2019/11/19 03:12:28 [debug] cassandra_timeout = 5000
2019/11/19 03:12:28 [debug] cassandra_username = "kong"
2019/11/19 03:12:28 [debug] client_body_buffer_size = "8k"
2019/11/19 03:12:28 [debug] client_max_body_size = "0"
2019/11/19 03:12:28 [debug] client_ssl = false
2019/11/19 03:12:28 [debug] database = "postgres"
2019/11/19 03:12:28 [debug] db_cache_ttl = 0
2019/11/19 03:12:28 [debug] db_cache_warmup_entities = {"services","plugins"}
2019/11/19 03:12:28 [debug] db_resurrect_ttl = 30
2019/11/19 03:12:28 [debug] db_update_frequency = 5
2019/11/19 03:12:28 [debug] db_update_propagation = 0
2019/11/19 03:12:28 [debug] dns_error_ttl = 1
2019/11/19 03:12:28 [debug] dns_hostsfile = "/etc/hosts"
2019/11/19 03:12:28 [debug] dns_no_sync = false
2019/11/19 03:12:28 [debug] dns_not_found_ttl = 30
2019/11/19 03:12:28 [debug] dns_order = {"LAST","SRV","A","CNAME"}
2019/11/19 03:12:28 [debug] dns_resolver = {}
2019/11/19 03:12:28 [debug] dns_stale_ttl = 4
2019/11/19 03:12:28 [debug] error_default_type = "text/plain"
2019/11/19 03:12:28 [debug] headers = {"server_tokens","latency_tokens"}
2019/11/19 03:12:28 [debug] log_level = "notice"
2019/11/19 03:12:28 [debug] lua_package_cpath = ""
2019/11/19 03:12:28 [debug] lua_package_path = "./?.lua;./?/init.lua;"
2019/11/19 03:12:28 [debug] lua_socket_pool_size = 30
2019/11/19 03:12:28 [debug] lua_ssl_verify_depth = 1
2019/11/19 03:12:28 [debug] mem_cache_size = "128m"
2019/11/19 03:12:28 [debug] nginx_admin_directives = {}
2019/11/19 03:12:28 [debug] nginx_daemon = "on"
2019/11/19 03:12:28 [debug] nginx_http_directives = {{value="TLSv1.1 TLSv1.2 TLSv1.3",name="ssl_protocols"}}
2019/11/19 03:12:28 [debug] nginx_http_ssl_protocols = "TLSv1.1 TLSv1.2 TLSv1.3"
2019/11/19 03:12:28 [debug] nginx_http_status_directives = {}
2019/11/19 03:12:28 [debug] nginx_http_upstream_directives = {{value="60s",name="keepalive_timeout"},{value="100",name="keepalive_requests"},{value="60",name="keepalive"}}
2019/11/19 03:12:28 [debug] nginx_http_upstream_keepalive = "60"
2019/11/19 03:12:28 [debug] nginx_http_upstream_keepalive_requests = "100"
2019/11/19 03:12:28 [debug] nginx_http_upstream_keepalive_timeout = "60s"
2019/11/19 03:12:28 [debug] nginx_optimizations = true
2019/11/19 03:12:28 [debug] nginx_proxy_directives = {}
2019/11/19 03:12:28 [debug] nginx_sproxy_directives = {}
2019/11/19 03:12:28 [debug] nginx_stream_directives = {}
2019/11/19 03:12:28 [debug] nginx_user = "nobody nobody"
2019/11/19 03:12:28 [debug] nginx_worker_processes = "auto"
2019/11/19 03:12:28 [debug] origins = {}
2019/11/19 03:12:28 [debug] pg_database = "kong"
2019/11/19 03:12:28 [debug] pg_host = "192.168.56.11"
2019/11/19 03:12:28 [debug] pg_max_concurrent_queries = 0
2019/11/19 03:12:28 [debug] pg_password = "******"
2019/11/19 03:12:28 [debug] pg_port = 5432
2019/11/19 03:12:28 [debug] pg_semaphore_timeout = 60000
2019/11/19 03:12:28 [debug] pg_ssl = false
2019/11/19 03:12:28 [debug] pg_ssl_verify = false
2019/11/19 03:12:28 [debug] pg_timeout = 5000
2019/11/19 03:12:28 [debug] pg_user = "kong"
2019/11/19 03:12:28 [debug] plugins = {"bundled"}
2019/11/19 03:12:28 [debug] prefix = "/usr/local/kong/"
2019/11/19 03:12:28 [debug] proxy_access_log = "logs/access.log"
2019/11/19 03:12:28 [debug] proxy_error_log = "logs/error.log"
2019/11/19 03:12:28 [debug] proxy_listen = {"0.0.0.0:8000","0.0.0.0:8443 http2 ssl"}
2019/11/19 03:12:28 [debug] real_ip_header = "X-Real-IP"
2019/11/19 03:12:28 [debug] real_ip_recursive = "off"
2019/11/19 03:12:28 [debug] router_consistency = "strict"
2019/11/19 03:12:28 [debug] router_update_frequency = 1
2019/11/19 03:12:28 [debug] service_mesh = false
2019/11/19 03:12:28 [debug] ssl_cipher_suite = "modern"
2019/11/19 03:12:28 [debug] 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"
2019/11/19 03:12:28 [debug] status_access_log = "off"
2019/11/19 03:12:28 [debug] status_error_log = "logs/status_error.log"
2019/11/19 03:12:28 [debug] status_listen = {"off"}
2019/11/19 03:12:28 [debug] stream_listen = {"off"}
2019/11/19 03:12:28 [debug] trusted_ips = {}
2019/11/19 03:12:28 [debug] upstream_keepalive = 60
2019/11/19 03:12:28 [verbose] prefix in use: /usr/local/kong
2019/11/19 03:12:28 [debug] loading subsystems migrations...
2019/11/19 03:12:28 [verbose] retrieving database schema state...
2019/11/19 03:12:29 [verbose] schema state retrieved
2019/11/19 03:12:29 [verbose] preparing nginx prefix directory at /usr/local/kong
2019/11/19 03:12:29 [verbose] SSL enabled, no custom certificate set: using default certificate
2019/11/19 03:12:29 [verbose] generating default SSL certificate and key
2019/11/19 03:12:29 [verbose] Admin SSL enabled, no custom certificate set: using default certificate
2019/11/19 03:12:29 [verbose] generating admin SSL certificate and key
2019/11/19 03:12:29 [warn] ulimit is currently set to "1024". For better performance set it to at least "4096" using "ulimit -n"
2019/11/19 03:12:44 [debug] searching for OpenResty 'nginx' executable
2019/11/19 03:12:44 [debug] /usr/local/openresty/nginx/sbin/nginx -v: 'nginx version: openresty/1.15.8.2'
2019/11/19 03:12:44 [debug] found OpenResty 'nginx' executable at /usr/local/openresty/nginx/sbin/nginx
2019/11/19 03:12:44 [debug] testing nginx configuration: KONG_NGINX_CONF_CHECK=true /usr/local/openresty/nginx/sbin/nginx -t -p /usr/local/kong -c nginx.conf
2019/11/19 03:12:49 [debug] searching for OpenResty 'nginx' executable
2019/11/19 03:12:49 [debug] /usr/local/openresty/nginx/sbin/nginx -v: 'nginx version: openresty/1.15.8.2'
2019/11/19 03:12:49 [debug] found OpenResty 'nginx' executable at /usr/local/openresty/nginx/sbin/nginx
2019/11/19 03:12:49 [debug] sending signal to pid at: /usr/local/kong/pids/nginx.pid
2019/11/19 03:12:49 [debug] kill -0 `cat /usr/local/kong/pids/nginx.pid` >/dev/null 2>&1
2019/11/19 03:12:49 [debug] starting nginx: /usr/local/openresty/nginx/sbin/nginx -p /usr/local/kong -c nginx.conf
2019/11/19 03:12:54 [debug] nginx started
2019/11/19 03:12:54 [info] Kong started

指定了--vv之后会打印出启动的debug信息,启动成功之后会自动再后台以daemon的方式运行。

启动之后看一下Kong默认监听了那些端口

netstat -tunlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:5432            0.0.0.0:*               LISTEN      19164/postmaster
tcp        0      0 0.0.0.0:8443            0.0.0.0:*               LISTEN      19567/nginx: master
tcp        0      0 127.0.0.1:8444          0.0.0.0:*               LISTEN      19567/nginx: master 
tcp        0      0 0.0.0.0:8000            0.0.0.0:*               LISTEN      19567/nginx: master
tcp        0      0 127.0.0.1:8001          0.0.0.0:*               LISTEN      19567/nginx: master

如上,监听了4个端口,分别是:

8000:API网关http代理端口

8443:API网关https代理端口

8001:Kong管理API的http端口

8444:Kong管理API的https端口

再观察一下,启动的进程名称均为nginx

Kong的默认运行目录在/usr/local/kong,我们看一下这个目录有什么东西:

ls -l /usr/local/kong/ 
total 72
drwxr-xr-x 2 root   root    37 Nov 19 02:20 bin
drwx------ 2 nobody root     6 Nov 19 03:12 client_body_temp
-rw-r--r-- 1 root   root 55501 Oct 22 18:27 COPYRIGHT
drwx------ 2 nobody root     6 Nov 19 03:12 fastcgi_temp
drwxr-xr-x 3 root   root    21 Nov 19 02:20 include
drwxr-xr-x 4 root   root   260 Nov 19 02:20 lib
drwxr-xr-x 2 root   root    65 Nov 19 03:12 logs
-rw-r--r-- 1 root   root   220 Nov 19 03:12 nginx.conf 
-rw-r--r-- 1 root   root  5652 Nov 19 03:12 nginx-kong.conf
-rw-r--r-- 1 root   root  1501 Nov 19 03:12 nginx-kong-stream.conf
drwxr-xr-x 2 root   root    23 Nov 19 03:12 pids
drwx------ 2 nobody root     6 Nov 19 03:12 proxy_temp
drwx------ 2 nobody root     6 Nov 19 03:12 scgi_temp
drwxr-xr-x 2 root   root   114 Nov 19 03:12 ssl
drwx------ 2 nobody root     6 Nov 19 03:12 uwsgi_temp

这个目录和nginx的工作目录非常像。

其中,里面的nginx.conf 和 nginx-kong.conf 就是Kong在启动的时候自动生成的nginx配置文件啦。

Kong API网关安装启动成功。