跳到主要内容

kong

01. kong集群

kong配置的service、routes、plugin、consumer、credentials等核心实体,都持久化在数据库中,出于性能考虑,kong在运行时,尽量避免去读数据库,所以上述的实体内容,都会缓存在内存中。

当修改或者新增的配置,在某一个kong实例上执行时,会在当前实例是生效同时写入数据库。其他kong实例通过db作为共享的配置中心,定期去同步db里的数据,实现不同的kong实例之间的配置数据的最终一致。

kong本身是一个无状态服务,通过db同步配置信息到各个kong实例。部署多个kong实例,需要在kong节点前面使用负载均衡器来分配流量。多个kong实例如果链接同一个数据库,则可认为是一个kong集群。

kong的配置文件支持3个属性:

  • db_update_frequency(default:5s)

从db更新配置到kong缓存的频率,有配置变更后,5s后会在整个kong集群里生效。

  • db_update_propagation(default:0s)

如果数据库是非强一致而是最终一致的,比如cassandra,必须配置该值。

该值代表数据库节点之间达到数据同步状态需要的时间,比如mysql主从同步。

如果该值没有配置,即默认是0s,此时读取数据库,比如典型的mysql主从分离,此时可能在从库上读取到老的值并写入缓存,导致db和缓存不一致。

配置了该值,数据变更传播到kong集群的最大事件会变成db_update_frequency(定期轮询时间)+db_update_propagation(db同步完成时间)

  • db_cache_ttl(default:3600s)

缓存失效时间,作为兜底,避免中间同步出现问题。

整体看来,使用同一个db来保证配置的持久化,运行时通过纯内存缓存来加速处理过程,通过db数据的同步来实现不同kong实例配置的最终一致(以时效性为代价),每个kong实例无状态,可任意水平扩展(其实还是一定程度受限于db的处理能力),需要在kong集群前面再增加负载均衡,以便请求可以转发到后面的kong集群上。

kong集群模式,在1.x和2.x不同,1.x主要通过共享db定时同步方式,2.x通过混部模式。详情见Kong集群(hybrid混合)部署模式_kong集群部署

02. postgreSQL

安装好postgre之后,默认会生成一个名为postgres的数据库和一个名为postgres的数据库用户。

PostgreSQL新手入门

进入控制台

psql -h localhost -p 5432 -U user -d somedb

控制台命令

\h:查看SQL命令的解释,比如\h select。
\?:查看psql命令列表。
\l:列出所有数据库。
\c [database_name]:连接其他数据库。
\d:列出当前数据库的所有表格。
\d [table_name]:列出某一张表格的结构。
\du:列出所有用户。
\e:打开文本编辑器。
\conninfo:列出当前数据库和连接的信息。

03. kong服务

默认情况下,kong监听的端口

服务端口

  • 8000 proxy接口,监听来自客户端传入的http请求,并把请求转发到上游服务器

  • 8443 proxy ssl端口

关联端口

  • 8001 admin api kong的管理api端口

  • 8444 admin api ssl

状态端口

  • 8100 需要配置STATUS_LISTEN,指定8100,如果是docker,类似KONG_STATUS_LISTEN=0.0.0.0:8100

dp/cp通信端口

  • 8005

kong网关配置json查看http://xxx:8001 https://xxx:8444

kong监控信息prometheushttp://xxx:8001/metrics

如果没有开放admin端口(8001/8444),比如说混部模式下的dp节点,默认是不需要admin端口的,这时候怎么看监控信息呢?可以考虑打开8100状态端口,通过http://xxx:8100/metrics也是可以访问到监控信息的。

而cp节点,因为需要开放admin端口,所以直接访问http://xxx:8001/metrics就可以,但是为了统一,其实dp和cp节点都使用8100状态信息端口最好,比较统一。

kong状态信息查看http://xxx:8100/status 包括server链接、内存、db状态

Kong API网关使用笔记 - 掘金

Kong 网关 快速入门 - 掘金

04. kong的admin api如何加密保护?

保护admin-api cn

保护admin-api en

主要的保护思路,admin-api的端口,不对外暴露,通过kong本身代理自己的8001端口。

  • 在kong启动时,把kong的admin_listen设置为 127.0.0.1:8001,只有本机可以访问这个地址。

  • 在kong里新建一个service,host设置为localhost,port设置为8001(admin端口)

  • service下增加path,path=/admin-api

这样,相当于kong通过xxx:8000/admin-api,代理了自身的localhost:8001,外部需要访问kong的admin api时,直接通过kong的代理端口8000来访问:xxx:8000/admin-api

自身的localhost:8001只有本机可以访问。

更进一步,如果通过docker启动的kong,可以不要映射kong的8001端口到宿主机,外部就无法访问。

通过kong代理之后,就可以在service或者path上增加鉴权,比如jwt之类的,来增加安全限制避免裸奔。

使用jwt插件加密保护admin-api

1.在konga里创建一个consumer(可以用命令行,也可以用界面)admin,需要注意,这个consumer名称需要和konga的用户名一致。

2.在consumer的credentials标签页,创建一个jwt(key和secret可以不填,会自动生成)

3.给代理admin api的route或者service配置一个jwt插件,插件的header names设置为authorization(这个是把jwt token放在header里,如果是要通过uri传输jwt token,设置uri param names,如果要通过cookie传输jwt token,需要设置cookie names)

4.在konga的connections里,设置jwt auth,填写好对应的http://xxx:8000/admin-api,key和secret取第2步生成的credentials里的key和secret即可。

img img

注意这里的172.23.0.3,因为我本地机器上用docker-compose起了kong,konga,pg等服务,并且这些服务都使用了network,所以他们有自己的虚拟网络,从konga里链接kong的时候,这里需要的虚拟网络上kong的ip,而非本地的ip。

05 本地机器使用docker-compose搭建kong集群

本地文件中,kong的管理端口都没有对宿主机暴露。并且在容器内部设置成了127.0.0.1:8001,只允许本机调用。然后通过kong的配置暴露出来。

所以直接在本机使用http://localhost:8000/admin-api 或者http://localhost:7000/admin-api是可以访问到被代理的admin api的。

version: '3.8'

networks:
kong-net:
driver: bridge

services:
kong-database:
image: postgres:9.6
container_name: kongdb-pg
restart: on-failure
networks:
- kong-net
environment:
POSTGRES_DB: kong
POSTGRES_USER: kong
POSTGRES_PASSWORD: kongpwd
PGDATA: /var/lib/postgresql/data/pgdata
ports:
- 5432:5432
volumes:
- /Users/xxx/Desktop/dws/kongtest/postgresql/postgresql.conf:/etc/postgresql/postgresql.conf
- /Users/xxx/Desktop/dws/kongtest/postgresql/pgdata:/var/lib/postgresql/data/pgdata
command: postgres -c config_file=/etc/postgresql/postgresql.conf

kong1:
image: kong:2.7.0
container_name: kong1
restart: on-failure
networks:
- kong-net
logging:
driver: json-file
options:
max-size: 16m
max-file: 8
volumes:
- /Users/xxx/Desktop/workspace/kong/lua:/code/kong/lua
environment:
GW_ENV: prod
KONG_LOG_LEVEL: info
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_PORT: 5432
KONG_PG_PASSWORD: kongpwd
KONG_PG_MAX_COCURRENT_QUERIES: 8
KONG_NGINX_HTTP_LOG_FORMAT: halo_log escape=json '{"remote_addr":"$$remote_addr","host":"$$host","server_time":"$$time_iso8601","request_method":"$$request_method","request_length":$$request_length,"path":"$$uri","status":$$status,"body_bytes":$$body_bytes_sent,"request":"$$request","request_body":"$$request_body","http_referer":"$$http_referer","http_user_agent":"$$http_user_agent","duration":$$request_time}'
KONG_PROXY_ACCESS_LOG: /dev/stdout halo_log
KONG_ADMIN_ACCESS_LOG: /dev/stdout halo_log
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_NGINX_WORKER_PROCESSES: 2
KONG_ADMIN_LISTEN: 127.0.0.1:8001, 127.0.0.1:8444 ssl
KONG_STATUS_LISTEN: 0.0.0.0:8100
KONG_LUA_PACKAGE_PATH: ./?.lua;./?/init.lua;/code/kong/lua/?.lua
KONG_PLUGINS: bundled,ab-test,ab-upstream,always-ok,authority-handover,authority-response,authority-sumbit,cas-auth,cas-login,cas-logout,cas-proxy,cas-service-validate,cas-slo,cas-username,cas-validate,fixed-window-limit,gitlab-file-list,gitlab-files,gitlab-pipeline-trigger,global-init,kcs-deploy-update,kjwt-flow,kjwt-issuer-filter,kjwt-signed,kjwt-validate,kong-upstream-update,kvu-auth,kvu-login,kvu-logout,leaky-bucket-limit,normal-halo-reply,normal-header,norn-ab-test,permission-check,rewrite-path,slide-window-limit,swimlane-upstream,switch-upstream,switch-upstream-by-host,sync-luna,token-validate
KONG_LUA_SSL_VERIFY_DEPTH: 2
KONG_NGINX_EVENTS_USE: epoll
KONG_NGINX_MAIN_ENV: GW_ENV
KONG_NGINX_HTTP_PROXY_BUFFERS: 128 128k
KONG_NGINX_HTTP_PROXY_BUFFER_SIZE: 128k
KONG_NGINX_HTTP_PROXY_MAX_TEMP_FILE_SIZE: 0
KONG_NGINX_HTTP_UPSTREAM_KEEPALIVE: 64
KONG_NGINX_HTTP_UPSTREAM_KEEPALIVE_TIMEOUT: 60s
KONG_NGINX_HTTP_LUA_SHARED_DICT: kjwt 16m; lua_shared_dict prometheus_metrics 10m
KONG_NGINX_CLIENT_BODY_BUFFER_SIZE: 512k
KONG_NGINX_HTTP_CLIENT_HEADER_BUFFER_SIZE: 16k
KONG_MEM_CACHE_SIZE: 32m
KONG_DB_CACHE_WARMUP_ENTITIES: services,routes,plugins
KONG_WORKER_CONSISTENCY: eventual
KONG_NGINX_GZIP: on
KONG_NGINX_GZIP_COMP_LEVEL: 5
KONG_NGINX_GZIP_PROXIED: any
KONG_NGINX_GZIP_VARY: on
KONG_HTTP2: on
KONG_NGINX_HTTP2_CHUNK_SIZE: 16k
ports:
- 8000:8000 # proxy
- 8443:8443 # proxy ssl
# - 8001:8001 # admin api
# - 8444:8444 # admin api ssl
- 8100:8100 # status
depends_on:
- kong-database

kong2:
image: kong:2.7.0
container_name: kong2
restart: on-failure
networks:
- kong-net
logging:
driver: json-file
options:
max-size: 16m
max-file: 8
volumes:
- /Users/xxx/Desktop/workspace/kong/lua:/code/kong/lua
environment:
GW_ENV: prod
KONG_LOG_LEVEL: info
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_PORT: 5432
KONG_PG_PASSWORD: kongpwd
KONG_PG_MAX_COCURRENT_QUERIES: 8
KONG_NGINX_HTTP_LOG_FORMAT: halo_log escape=json '{"remote_addr":"$$remote_addr","host":"$$host","server_time":"$$time_iso8601","request_method":"$$request_method","request_length":$$request_length,"path":"$$uri","status":$$status,"body_bytes":$$body_bytes_sent,"request":"$$request","request_body":"$$request_body","http_referer":"$$http_referer","http_user_agent":"$$http_user_agent","duration":$$request_time}'
KONG_PROXY_ACCESS_LOG: /dev/stdout halo_log
KONG_ADMIN_ACCESS_LOG: /dev/stdout halo_log
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_NGINX_WORKER_PROCESSES: 2
KONG_ADMIN_LISTEN: 127.0.0.1:8001, 127.0.0.1:8444 ssl
KONG_STATUS_LISTEN: 0.0.0.0:8100
KONG_LUA_PACKAGE_PATH: ./?.lua;./?/init.lua;/code/kong/lua/?.lua
KONG_PLUGINS: bundled,ab-test,ab-upstream,always-ok,authority-handover,authority-response,authority-sumbit,cas-auth,cas-login,cas-logout,cas-proxy,cas-service-validate,cas-slo,cas-username,cas-validate,fixed-window-limit,gitlab-file-list,gitlab-files,gitlab-pipeline-trigger,global-init,kcs-deploy-update,kjwt-flow,kjwt-issuer-filter,kjwt-signed,kjwt-validate,kong-upstream-update,kvu-auth,kvu-login,kvu-logout,leaky-bucket-limit,normal-halo-reply,normal-header,norn-ab-test,permission-check,rewrite-path,slide-window-limit,swimlane-upstream,switch-upstream,switch-upstream-by-host,sync-luna,token-validate
KONG_LUA_SSL_VERIFY_DEPTH: 2
KONG_NGINX_EVENTS_USE: epoll
KONG_NGINX_MAIN_ENV: GW_ENV
KONG_NGINX_HTTP_PROXY_BUFFERS: 128 128k
KONG_NGINX_HTTP_PROXY_BUFFER_SIZE: 128k
KONG_NGINX_HTTP_PROXY_MAX_TEMP_FILE_SIZE: 0
KONG_NGINX_HTTP_UPSTREAM_KEEPALIVE: 64
KONG_NGINX_HTTP_UPSTREAM_KEEPALIVE_TIMEOUT: 60s
KONG_NGINX_HTTP_LUA_SHARED_DICT: kjwt 16m; lua_shared_dict prometheus_metrics 10m
KONG_NGINX_CLIENT_BODY_BUFFER_SIZE: 512k
KONG_NGINX_HTTP_CLIENT_HEADER_BUFFER_SIZE: 16k
KONG_MEM_CACHE_SIZE: 32m
KONG_DB_CACHE_WARMUP_ENTITIES: services,routes,plugins
KONG_WORKER_CONSISTENCY: eventual
KONG_NGINX_GZIP: on
KONG_NGINX_GZIP_COMP_LEVEL: 5
KONG_NGINX_GZIP_PROXIED: any
KONG_NGINX_GZIP_VARY: on
KONG_HTTP2: on
KONG_NGINX_HTTP2_CHUNK_SIZE: 16k
ports:
- 7000:8000 # proxy
- 7443:8443 # proxy ssl
# - 7001:8001 # admin api
# - 7444:8444 # admin api ssl
- 7100:8100 # status
depends_on:
- kong-database

konga:
image: pantsel/konga:latest
container_name: konga
networks:
- kong-net
restart: on-failure
environment:
NODE_ENV: production
TOKEN_SECRET: kwai
DB_ADAPTER: postgres
DB_URI: postgresql://kong:kongpwd@kong-database:5432/konga
ports:
- 1337:1337
depends_on:
- kong1
- kong2

# konga-prepare:
# image: pantsel/konga:latest
# networks:
# - kong-net
# restart: on-failure
# environment:
# KONG_DATABASE: postgres
# KONG_PG_HOST: kong-database
# KONG_PG_DATABASE: konga
# KONG_PG_PASSWORD: kongpwd
# depends_on:
# - kong-database
# command: "-c prepare -a postgres -u postgresql://kong:kongpwd@kong-database:5432/konga"

# kong-migration:
# image: kong:2.7.0
# container_name: kong-migration
# networks:
# - kong-net
# environment:
# KONG_DATABASE: postgres
# KONG_PG_HOST: kong-database
# KONG_PG_DATABASE: kong
# KONG_PG_USER: kong
# KONG_PG_PASSWORD: kongpwd
# links:
# - kong-database
# depends_on:
# - kong-database
# command: kong migrations bootstrap --v