Kong网关:入门、实战与进阶
上QQ阅读APP看书,第一时间看更新

1.5 使用Kong网关搭建Web应用

区别于传统的HelloWorld示例(仅简单打印一句语句),本节将介绍如何使用Kong网关搭建一个前后端分离的Web应用。通过这个示例,读者将对Kong网关全局有一个更好的认识。

1.5.1 示例项目介绍

该示例项目为搭建一个简单的待办任务列表Web应用(todos),前端使用Vue框架,后端基于Node.js的Express框架,数据库使用MongoDB。项目目录结构如下所示。


├── Readme.md
├── backend
├── docker-compose.yml
└── frontend

其中,frontend和backend目录分别对应项目的前后端应用。整个项目基于Docker容器启动。docker-compose.yml为启动配置文件,配置项如代码清单1-3所示。

程序清单1-3 docker-compose.yml文件


1 version: "3"
  2 services:
  3   backend:
  4     container_name: backend
  5     build:
  6       context: ./backend
  7     depends_on:
  8       - db
  9     volumes:
 10       - ./backend:/usr/app
 11       - /usr/app/node_modules
 12     environment:
 13       - MONGO_URL=mongodb://db:27017/todos
 14       - APP_PORT=80
 15     ports: ['80:80']
 16   db:
 17     container_name: db
 18     image: mongo:4.0
 19     restart: always
 20   frontend:
 21     container_name: frontend
 22     build:
 23       context: ./frontend
 24     volumes:
 25       - ./frontend:/app
 26       - /app/node_modules
 27     ports:
 28       - '8080:8080'
 29     environment:
 30       - BACKEND_URL=http://127.0.0.1/todos

frontend和backend应用中各自包含Dockerfile文件,如代码清单1-4和代码清单1-5所示。

程序清单1-4 frontend应用的Dockerfile文件


# frontend dockerfile
FROM node:12.2.0-alpine
# set working directory
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
# start app
CMD ["npm", "run", "serve"]

程序清单1-5 backend应用的Dockerfile文件


# backend dockerfile
FROM node:12.2.0-alpine 
# set working directory
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . . 
# start app
CMD [ "npm", "start" ]

这里,前端应用使用vue-cli-service serve命令启动,后端应用使用node app.js命令启动。关于前后端应用中的源码和细节,此处不再赘述,有兴趣的读者可以自行下载阅读。读者可以直接运行docker-compose up-d命令启动项目,启动完成后在浏览器中输入地址http://127.0.0.1:8080访问页面,如图1-10所示。

图1-10 todos页面

1.5.2 后端服务路由

在成功执行完第一个示例后,我们接下来对后端服务架构进行改造。整体架构改造如下。

项目目录结构调整为:


├── Readme.md
├── backend
├── docker-compose.yml
├── frontend
└── kong-gateway

这里新增了一个kong-gateway目录,首先修改docker-compose.yml启动文件,添加Kong的启动项配置,如代码清单1-6所示。

程序清单1-6 docker-compose.yml启动文件


29     ...
 30     ...
 31   kong:
 32     build:
 33       context: ./kong-gateway
 34     container_name: kong
 35     environment:
 36       KONG_DATABASE: 'off'
 37       KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/config.yml
 38       KONG_PROXY_ACCESS_LOG: /dev/stdout
 39       KONG_ADMIN_ACCESS_LOG: /dev/stdout
 40       KONG_PROXY_ERROR_LOG: /dev/stderr
 41       KONG_ADMIN_ERROR_LOG: /dev/stderr
 42       KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl
 43     ports:
 44       - '8000:8000'
 45       - '8443:8443'
 46       - '8001:8001'
 47       - '8444:8444'
 48     volumes:
 49       - ./kong-gateway:/usr/local/kong/declarative
 50     depends_on:
 51       - backend

新增的kong-gateway目录中包含两份配置文件:dockerfile和config.yml(Kong启动项配置文件)。其中,dockerfile配置文件指定了Kong服务器的版本,这里使用的是2.0.5版本。我们在之后的示例中同样基于这个版本进行介绍,以保证版本信息统一。Dockerfile配置文件如下。


1 # kong dockerfile
2 FROM kong:2.0.5

config.yml配置文件指定了网关层的路由配置以及路由对应的后端服务地址。读者这里可以先做一些简单了解,后续章节会对该配置文件做详细介绍。此处,网关层路由匹配路径是/kong/gateway,对应的后端服务地址为backend:80,即原应用后端服务地址。详细配置如代码清单1-7所示。

程序清单1-7 config.yml配置文件


  1 _format_version: "1.1"
  2
  3 services:
  4   - name: service_todolists
  5     host: host_todolists
  6     routes:
  7       - name: route_todolists
  8         paths:
  9           - /kong/gateway
 10
 11 upstreams:
 12   - name: host_todolists
 13     targets:
 14       - target: backend:80

在网关层配置好之后,我们还需要对之前的前端应用做一些简单修改:变更接口访问地址,将BACKEND_URL修改为http://127.0.0.1:8000/kong/gateway/todos。其中,127.0.0.1:8000为网关层入口地址,这样请求便可先抵达网关层,待匹配路由后再转发至原后端服务,如代码清单1-8所示。

程序清单1-8 前端应用修改


  1 import Vue from 'vue';
  2 import BootstrapVue from 'bootstrap-vue';
  3 import axios from 'axios';
  4 import App from './App.vue';
  5
  6 const http = axios.create({
  7   baser: process.env.BACKEND_URL ? process.env.BACKEND_URL : 'http://127.0.0.
     1:8000/kong/gateway/todos',
  8 });
  9
 10 Vue.prototype.$http = http;
 11
 12 Vue.use(BootstrapVue);
 13
 14 Vue.config.productionTip = false;
 15
 16 new Vue({
 17   render: (h) => h(App),
 18 }).$mount('#app');

至此,整个项目已改造完成。后端应用在这次改造过程中保持不变。重新运行docker-compose up-d命令,待容器重启后打开浏览器控制台,观察请求细节的变化。

原先的请求详情如图1-11所示。

引入Kong网关之后的请求详情如图1-12所示。

图1-11 原先的请求详情

图1-12 引入Kong网关之后的请求详情

1.5.3 静态页面代理

在完成上述步骤后,我们继续对部署方案进行升级。之前前端应用使用vue-cli-service serve启动,但其仅适用于本地开发环境或测试环境。在真实的生产环境中,我们会将前端应用打包成静态文件,然后部署在服务器中,或者上传至CDN。这里,我们对整体架构再做一些调整,让Kong服务器既作为Web服务器,又作为代理服务器。

项目目录结构与1.5.2节保持一致。


├── Readme.md
├── backend
├── docker-compose.yml
├── frontend
└── kong-gateway

我们还是从docker-compose.yml文件开始修改,主要新增第24~25行、第46~48行和第50~51行。这些配置的作用是将前端应用编译出来的静态文件通过Docker卷共享,以便直接被Kong服务器访问到。此处创建的卷名称为static,用户可以自定义名称。该Docker卷映射到前端应用和Kong服务器的路径分别为/app/dist和/static,如代码清单1-9所示。

程序清单1-9 docker-compose.yml文件


 19 ...
 20   frontend:
 21     container_name: frontend
 22     build:
 23       context: ./frontend
 24     volumes:
 25       - static:/app/dist
 26     environment:
 27       - BACKEND_URL=http://127.0.0.1:8000/kong/gateway/todos
 28   kong:
 29     build:
 30       context: ./kong-gateway
 31     container_name: kong
 32     environment:
 33       KONG_DATABASE: 'off'
 34       KONG_DECLARATIVE_CONFIG: /usr/local/kong/declarative/config.yml
 35       KONG_PROXY_ACCESS_LOG: /dev/stdout
 36       KONG_ADMIN_ACCESS_LOG: /dev/stdout
 37       KONG_PROXY_ERROR_LOG: /dev/stderr
 38       KONG_ADMIN_ERROR_LOG: /dev/stderr
 39       KONG_ADMIN_LISTEN: 0.0.0.0:8001, 0.0.0.0:8444 ssl
 40     ports:
 41       - '8000:8000'
 42       - '8443:8443'
 43       - '8001:8001'
 44       - '8444:8444'
 45       - '8080:8080'
 46     volumes:
 47       - ./kong-gateway:/usr/local/kong/declarative
 48       - static:/static
 49     depends_on:
 50       - backend
 51 volumes:
 52   static:

接下来,我们对kong-gateway项目进行改造,在原有目录结构下新增一个todolists.conf文件。


├── Dockerfile
├── config.yml
└── todolists.conf

先来看一下改造后的Dockerfile文件,如代码清单1-10所示。

程序清单1-10 改造后的Dockerfile文件


  1 FROM kong:2.0.5
  2 VOLUME ["/static"]
  3 ADD ./todolists.conf /etc/kong
  4 CMD ["kong","start","--nginx-conf","/etc/kong/todolists.conf","&"]

第2行代码:在容器内挂载之前在docker-compose.yml配置文件中创建的static卷。

第3行代码:将新增的todolists.conf文件添加到Docker容器内部的/etc/kong目录下备用。

第4行代码:执行kong start命令,并携带命令行参数--nginx-conf,指定Nginx配置文件,即之前的todolists.conf文件。

todolists.conf文件中的内容如代码清单1-11所示。

程序清单1-11 todolists.conf文件


  1 # ---------------------
  2 # custom_nginx.template
  3 # ---------------------
  4
  5 worker_processes ${{NGINX_WORKER_PROCESSES}}; 
  6 daemon ${{NGINX_DAEMON}};                     
  7
  8 pid pids/nginx.pid;                      
  9 error_log logs/error.log ${{LOG_LEVEL}}; 
 10
 11 events {
 12   use epoll; # custom setting
 13   multi_accept on;
 14 }
 15
 16 http {
 17   # 引入默认的Nginx配置文件
 18   include 'nginx-kong.conf';
 19   # 引入默认的mime.type配置文件
 20   include /usr/local/openresty/nginx/conf/mime.types;
 21   default_type application/octet-stream;
 22
 23   # 自定义server块
 24   server {
 25     server_name _;
 26     listen 8080;
 27     location / {
 28       default_type text/css;
 29       root /static;
 30       index index.html;
 31     }
 32   }
 33 }

我们将在第5章中详细讲解该文件内容的细节,此处仅需知道我们通过该配置文件,暴露了8080端口作为Kong Web服务器的入口地址。前端静态文件的根目录为/static。

最后,我们对前端应用进行改造,修改其中的dockerfile文件,如代码清单1-12所示。

程序清单1-12 修改前端应用中的Dockerfile文件


  1 FROM node:12.2.0-alpine
  2 WORKDIR /app
  3 VOLUME ["/static"]
  4 # set working directory
  5 COPY package*.json ./
  6
  7 RUN npm install
  8
  9 COPY . .
 10
 11 # build app
 12 CMD ["npm", "run", "build"]

第3行代码:与kong-gateway项目中的功能一致。

第12行代码:将CMD["npm","run","serve"]命令修改为CMD["npm","run","build"],之前是前端项目直接启动服务,现变更为编译成静态文件,供Web服务器使用。打包后的静态文件目录结构如下。


├── css
│   └── app.0305fdfa.css
├── favicon.ico
├── index.html
└── js
    ├── app.2a6813cb.js
    ├── app.2a6813cb.js.map
    ├── chunk-vendors.3c424d74.js
    └── chunk-vendors.3c424d74.js.map

至此,整个项目已经改造完毕,用户输入http://127.0.01:8080即可访问页面。此时,Kong服务器已兼具Web服务器和代理服务器的功能。