1.Introduction
API弯管是随着微服务(Microservice)概念兴起的一种架构模式。原本一个庞大的单体应用(All in one)业务系统被拆分成许多微服务(Microservice)系统进行独立的维护和部署,服务拆分带来的变化是API的规模成倍增长,API的管理难度也在日益增加,使用API网关发布和管理API逐渐成为一种趋势。一般来说,API网关是运行于外部请求与内部服务之间的一个流量入口,实现对外部请求的协议转换、鉴权、流控、参数校验、监控等通用功能。
本文即将介绍的Kong,是一个开源的API gateway和微服务管理的工具,基于Nginx和lua-nginx-module(特殊的OpenResty),Kong具有可插拔的架构,使其功能强大且灵活。
2.Key Concepts
· Service: Kong的一个实体对象,表示了外部的上游API或者微服务
· Route: Kong的一个实体对象,表示了一种将下游请求映射到上游服务的路由
· Consumer: Kong的一个实体对象,表示使用API的开发者或者机器,在使用Kong时,一个Consumer仅与Kong交互。
· Plugin:插件用于是Kong内部将请求转发给上游API前后执行的一系列动作,Kong在其插件库中提供了非常强大的插件
· Credential: A certificate object represents a public certificate/private key pair for an SSL certificate.
· SNI: An SNI object represents a many-to-one mapping of hostnames to a certificate. That is, a certificate object can have many hostnames associated with it
· Upstream: 上游服务,指代Kong背后的API或者服务,也是客户端请求转发的目的端,The upstream object represents a virtual hostname and can be used to loadbalance incoming requests over multiple services (targets).
· Target: A target is an ip address/hostname with a port that identifies an instance of a backend service. Every upstream can have many targets, and the targets can be dynamically added. Changes are effectuated on the fly.
· Admin API -用于管理Kong配置,端点,使用者,插件等的RESTful API端点
下图展示了Kong和其他传统架构的区别,可以帮助我们理解为什么有Kong:
大概有鉴权、监控、日志、安全审计、ACL、缓存、限流、serverless等等。
3.Setup
官方文档提供了多种环境下详细的安装说明。我们这里使用docker进行安装(docker安装过程略):
#1.create docker network
$ docker network create kong-net
#2.run PostgreSQL database
$ docker run -d --name kong-database \
--network=kong-net \
-p 5432:5432 \
-e "POSTGRES_USER=kong" \
-e "POSTGRES_DB=kong" \
postgres:9.6
#3.prepare database
$ 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
Unable to find image 'kong:latest' locally
latest: Pulling from library/kong
59265c40e257: Pull complete
6389eff8e6ff: Pull complete
f58488256be6: Pull complete
Digest: sha256:f7ed033bb9955da0fcefa034d07fee324cad6d01c12ebf54268dfe825ba2e92c
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: 001_14_to_15 (executed)
core migrated up to: 002_15_to_1 (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)
migrating acl on database 'kong'...
acl migrated up to: 000_base_acl (executed)
acl migrated up to: 001_14_to_15 (executed)
migrating jwt on database 'kong'...
jwt migrated up to: 000_base_jwt (executed)
jwt migrated up to: 001_14_to_15 (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)
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)
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)
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)
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)
22 migrations processed
22 executed
database is up-to-date
#4.start Kong
$ 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
999a5cf1db1a8c23ca870933b73407d7ae5f0fd2d9a895a78627a9c27e08045c
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
999a5cf1db1a kong:latest "/docker-entrypoint.…" 8 seconds ago Up 7 seconds 0.0.0.0:8000-8001->8000-8001/tcp, 0.0.0.0:8443-8444->8443-8444/tcp kong
ecb50c2f7307 postgres:9.6 "docker-entrypoint.s…" About an hour ago Up About an hour 0.0.0.0:5432->5432/tcp
容器启动完毕后,尝试curl -i http://localhost:8001/,得到如下:
{
"plugins": {
"enabled_in_cluster": [ ],
"available_on_server": {
"response-transformer": true,
"oauth2": true,
"acl": true,
"correlation-id": true,
"pre-function": true,
"jwt": true,
"cors": true,
"ip-restriction": true,
"basic-auth": true,
"key-auth": true,
"rate-limiting": true,
"request-transformer": true,
"http-log": true,
"file-log": true,
"hmac-auth": true,
"ldap-auth": true,
"datadog": true,
"tcp-log": true,
"zipkin": true,
"post-function": true,
"request-size-limiting": true,
"bot-detection": true,
"syslog": true,
"loggly": true,
"azure-functions": true,
"udp-log": true,
"response-ratelimiting": true,
"aws-lambda": true,
"statsd": true,
"prometheus": true,
"request-termination": true
}
},
"tagline": "Welcome to kong",
"configuration": {
"plugins": [
"bundled"
],
"admin_ssl_enabled": true,
"lua_ssl_verify_depth": 1,
"trusted_ips": { },
"prefix": "/usr/local/kong",
"loaded_plugins": {
"response-transformer": true,
"request-termination": true,
"prometheus": true,
"ip-restriction": true,
"pre-function": true,
"jwt": true,
"cors": true,
"statsd": true,
"basic-auth": true,
"key-auth": true,
"ldap-auth": true,
"aws-lambda": true,
"http-log": true,
"response-ratelimiting": true,
"hmac-auth": true,
"request-size-limiting": true,
"datadog": true,
"tcp-log": true,
"zipkin": true,
"post-function": true,
"bot-detection": true,
"acl": true,
"loggly": true,
"syslog": true,
"azure-functions": true,
"udp-log": true,
"file-log": true,
"request-transformer": true,
"correlation-id": true,
"rate-limiting": true,
"oauth2": true
},
"cassandra_username": "kong",
"ssl_cert_key": "/usr/local/kong/ssl/kong-default.key",
"admin_ssl_cert_key": "/usr/local/kong/ssl/admin-kong-default.key",
"dns_resolver": { },
"pg_user": "kong",
"mem_cache_size": "128m",
"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",
"nginx_admin_directives": { },
"nginx_http_directives": [
{
"value": "prometheus_metrics 5m",
"name": "lua_shared_dict"
}
],
"pg_host": "kong-database",
"nginx_acc_logs": "/usr/local/kong/logs/access.log",
"proxy_listen": [
"0.0.0.0:8000",
"0.0.0.0:8443 ssl"
],
"client_ssl_cert_default": "/usr/local/kong/ssl/kong-default.crt",
"ssl_cert_key_default": "/usr/local/kong/ssl/kong-default.key",
"db_update_frequency": 5,
"db_update_propagation": 0,
"stream_listen": [
"off"
],
"nginx_err_logs": "/usr/local/kong/logs/error.log",
"cassandra_port": 9042,
"dns_order": [
"LAST",
"SRV",
"A",
"CNAME"
],
"dns_error_ttl": 1,
"headers": [
"server_tokens",
"latency_tokens"
],
"cassandra_lb_policy": "RequestRoundRobin",
"nginx_optimizations": true,
"pg_timeout": 5000,
"database": "postgres",
"pg_database": "kong",
"nginx_worker_processes": "auto",
"lua_package_cpath": "",
"admin_acc_logs": "/usr/local/kong/logs/admin_access.log",
"lua_package_path": "./?.lua;./?/init.lua;",
"nginx_pid": "/usr/local/kong/pids/nginx.pid",
"upstream_keepalive": 60,
"client_ssl": false,
"admin_access_log": "/dev/stdout",
"cassandra_data_centers": [
"dc1:2",
"dc2:3"
],
"cassandra_ssl": false,
"proxy_listeners": [
{
"transparent": false,
"ssl": false,
"ip": "0.0.0.0",
"proxy_protocol": false,
"port": 8000,
"http2": false,
"listener": "0.0.0.0:8000"
},
{
"transparent": false,
"ssl": true,
"ip": "0.0.0.0",
"proxy_protocol": false,
"port": 8443,
"http2": false,
"listener": "0.0.0.0:8443 ssl"
}
],
"proxy_ssl_enabled": true,
"client_max_body_size": "0",
"proxy_error_log": "/dev/stderr",
"enabled_headers": {
"latency_tokens": true,
"X-Kong-Proxy-Latency": true,
"Via": true,
"server_tokens": true,
"Server": true,
"X-Kong-Upstream-Latency": true,
"X-Kong-Upstream-Status": false
},
"dns_stale_ttl": 4,
"lua_socket_pool_size": 30,
"db_resurrect_ttl": 30,
"origins": { },
"cassandra_consistency": "ONE",
"db_cache_ttl": 0,
"admin_error_log": "/dev/stderr",
"pg_ssl_verify": false,
"dns_not_found_ttl": 30,
"pg_ssl": false,
"nginx_daemon": "off",
"nginx_kong_stream_conf": "/usr/local/kong/nginx-kong-stream.conf",
"cassandra_repl_strategy": "SimpleStrategy",
"error_default_type": "text/plain",
"dns_no_sync": false,
"nginx_proxy_directives": { },
"proxy_access_log": "/dev/stdout",
"nginx_kong_conf": "/usr/local/kong/nginx-kong.conf",
"cassandra_schema_consensus_timeout": 10000,
"dns_hostsfile": "/etc/hosts",
"admin_listeners": [
{
"transparent": false,
"ssl": false,
"ip": "0.0.0.0",
"proxy_protocol": false,
"port": 8001,
"http2": false,
"listener": "0.0.0.0:8001"
},
{
"transparent": false,
"ssl": true,
"ip": "0.0.0.0",
"proxy_protocol": false,
"port": 8444,
"http2": false,
"listener": "0.0.0.0:8444 ssl"
}
],
"ssl_cipher_suite": "modern",
"ssl_cert": "/usr/local/kong/ssl/kong-default.crt",
"cassandra_timeout": 5000,
"admin_ssl_cert_key_default": "/usr/local/kong/ssl/admin-kong-default.key",
"cassandra_ssl_verify": false,
"cassandra_contact_points": [
"kong-database"
],
"real_ip_header": "X-Real-IP",
"real_ip_recursive": "off",
"cassandra_repl_factor": 1,
"client_ssl_cert_key_default": "/usr/local/kong/ssl/kong-default.key",
"admin_ssl_cert": "/usr/local/kong/ssl/admin-kong-default.crt",
"anonymous_reports": true,
"log_level": "notice",
"kong_env": "/usr/local/kong/.kong_env",
"pg_port": 5432,
"admin_ssl_cert_default": "/usr/local/kong/ssl/admin-kong-default.crt",
"client_body_buffer_size": "8k",
"ssl_preread_enabled": true,
"ssl_cert_csr_default": "/usr/local/kong/ssl/kong-default.csr",
"stream_listeners": { },
"cassandra_keyspace": "kong",
"ssl_cert_default": "/usr/local/kong/ssl/kong-default.crt",
"nginx_conf": "/usr/local/kong/nginx.conf",
"admin_listen": [
"0.0.0.0:8001",
"0.0.0.0:8444 ssl"
]
},
"version": "1.0.3",
"node_id": "3ccef799-3037-4a8f-8ccd-2e60326b4444",
"lua_version": "LuaJIT 2.1.0-beta3",
"prng_seeds": {
"pid: 36": 229762112224,
"pid: 37": 131951181922,
"pid: 1": 136391662351
},
"timers": {
"pending": 5,
"running": 0
},
"hostname": "999a5cf1db1a"
}
上面几个端口,分别是:
· :8000 on which Kong listens for incoming HTTP traffic from your clients, and forwards it to your upstream services.
· :8443 on which Kong listens for incoming HTTPS traffic. This port has a similar behavior as the :8000 port, except that it expects HTTPS traffic only. This port can be disabled via the configuration file.
· :8001 on which the Admin API used to configure Kong listens.
· :8444 on which the Admin API listens for HTTPS traffic.
标签:migrated,网关,0.0,up,kong,ssl,API,Kong,true From: https://blog.51cto.com/u_15447023/6035973