使用 Kong 搭建网关
为什么要自己搭建网关?
首先明确网关的用途,我使用网关完全是统一管理自己的各种后台接口。在搭建自己的网关前我的后台接口十分散乱,有的部署在云函数的 HTTP 事件触发器上,有的部署在云函数的 Web 云函数上,有的在腾讯云的 API 网关上,有的在 nginx 代理上,这次自己搭建网关主要是整理提供的接口,同时清理不必要的配置。
如果说单单上面的原因还不至于需要自己再折腾一次,但腾讯这几天取消了云函数的免费额度,而且下个月开始只要使用就会扣除基础服务费 12.8 元,这能忍吗?既然服务可以使用云函数跑,那照样可以在 docker 中跑,所以将云函数中的服务全部迁移到服务器的 docker 上。PS:由于云函数最开始不支持容器部署,所以一些旧的服务都是直接和云厂商的服务绑定的,这些旧服务就暂时停止吧。
启动 Kong Gateway(docker)
kong 作为一个开源的网关服务还是很稳定的,以下是 Kong 的部署方法,注意修改其中的 PASSWORD。
- 
启动数据库,这个数据库为 Kong提供服务。docker run -d --name kong-database \ --network=kong-net \ -p 5432:5432 \ -e "POSTGRES_USER=kong" \ -e "POSTGRES_DB=kong" \ -e "POSTGRES_PASSWORD=kongpass" \ postgres:9.6
- 
初始化配置,这里配置数据库。 docker run --rm --network=kong-net \ -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ -e "KONG_PG_PASSWORD=kongpass" \ kong/kong-gateway:2.8.1.0-alpine kong migrations bootstrap
- 
启动 Kong网关,因为后续将使用nginx代理,SSL将放到nginx中配置,而且使用的是社区版,所以只是用8001和8000端口即可。docker run -d --name kong-gateway \ --network=kong-net \ -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=kong-database" \ -e "KONG_PG_USER=kong" \ -e "KONG_PG_PASSWORD=kongpass" \ -e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \ -p 8000:8000 \ -p 8001:8001 \ kong/kong-gateway:2.8.1.0-alpine- :8000:用于提供网关服务;
- :8001:用于配置- Kong监听的管理- API;
 
现在已经将 Kong 配置完成了,下面启动一个 UI 界面帮助我们管理。
启动 konga
konga 是一个第三方的 GUI 管理页面。
我们同样使用 docker 配置。
docker run -p 1337:1337 \
  --network kong-net \
  --name konga \
  -e "NODE_ENV=production" \
  -e "TOKEN_SECRET=fdasfeag34agft" \
  pantsel/konga
启动之后,只需要开启 1337 端口即可通过 UI 界面配置我们的 kong 网关。
首次进入需要填写 kong 配置接口,因为以上的服务都加入到了 kong-net 网络中,所以只需要填写 http://kong-gateway:8001 即可。
配置 nginx
因为需要使用 nginx 配置 SSL 服务,所以这里修改 nginx 配置。
server {
    listen 80;
    server_name hostname;
    return 301 https://hostname;
}
server {
    listen 443 ssl;
    server_name hostname;
    location / {
        proxy_pass http://localhost:8000;
        proxy_set_header    Host            $http_host;
        proxy_set_header    X-Real-IP       $remote_addr;
        proxy_set_header    X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_redirect      off;
    }
    ssl_certificate /config/nginx/cert/fullchain.cer;
    ssl_certificate_key /config/nginx/cert/cert.key;
    ssl_session_timeout 1d;
    ssl_session_cache shared:MozSSL:10m;  # about 40000 sessions
    ssl_session_tickets off;
    # intermediate configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;
    # HSTS (ngx_http_headers_module is required) (63072000 seconds)
    add_header Strict-Transport-Security "max-age=63072000" always;
}
添加服务
在 Kong 中,需要区分 services 和 routes,services 是对后端服务的访问设置,routes 是网关对外提供的服务。一个 service 可以有多个 route,而一个 route 只能有一个 service。
因为我的服务都在一台服务器上,所以为了安全起见我将服务都加入到 kong 同一个网络中,所以在配置 service 时只需要在 HOST 字段填入容器名称即可,同时还可以不必添加端口映射,提高安全性。
Todo:这里应该填写一些如何添加服务更详细的说明,但不想写了,就这样吧,如果有问题再说。