首页 / 资讯中心 / 文章详情

Nginx应用与运维——Nginx在微服务架构中的应用(二)

Nginx应用与运维——Nginx在微服务架构中的应用(二) ★ FEATURED ARTICLE
Nginx在微服务架构中的应用2、基于Nginx的微服务网关2.1、Nginx产品组件2.2、开源微服务网关Kong2.2.1、消费者2.2.2、消费者接口2.2.3、管理接口2.2.4、操作对象2.3、安装部署2.4、微服务网关应用2、基于Nginx的微服务网关Nginx作为资深的代理负载服务器在微服务的全生态架构方案中动作还是比较慢的其在服务网格及无服务器化方面还在不断提升。Nginx官方也提供了相应的产品组件并在商业版本中提供了完整的微服务网关方案。在开源版本中很多人都基于开源Nginx扩展版OpenResty实现了不同版本的微服务网关应用本节将以已经商业化的开源微服务网关应用Kong为例介绍Nginx在微服务网关中的应用。Kong仍处在活跃开发的状态中其1.0以后的版本与早期版本有很大的不同本章以最新版本1.3为例进行介绍。2.1、Nginx产品组件微服务为软件生产带来了变革相对地也推动了Nginx应用产品的发展在应对微服务架构的解决方案中Nginx产品组件中主要有如下3款产品。(1)Nginx控制器Nginx控制器(Nginx Controller)是Nginx Plus的Web集中监控和管理平台提供了丰富的监控图表使用户可以轻松地监视应用程序的运行状况和性能。使用Nginx控制器可以通过Web界面直观地集中管理数百台Nginx Plus服务器其建立在模块化的架构体系上可管理Nginx Plus的所有功能包括其作为负载均衡、API网关及作为ServiceMesh环境中的代理服务等功能。负载均衡模块负责负载功能的配置、验证和故障诊断API模块允许用户定义、发布、保护、监视、分析API计划推出的Service Mesh模块将简化用户从Kubernetes的Ingress模式到ServiceMesh体系结构的转变以应对数百个或数千个微服务的管理。(2)交付网关Nginx将更注重成为其所代理后端的应用交付网关实现作为各种应用的统一入口实现访问入口路由、应用防火墙、内容缓存、负载均衡等功能。例如成为微服务架构中的API网关或作为Kubernetes架构中的Ingress组件。(3)Web应用服务器Nginx Unit是一个支持多种语言、可动态配置的开源Web应用服务器当前已经支持的语言有Go、Node.js、Perl、PHP、Python、Ruby和Java。它于2018年推出Nginx官方正积极推动该项目的发展也将提供对更多语言的解析支持。例如它支持Java语言的版本正在测试中可以使Java应用以Tomcat兼容的方式被添加进来实现代码解析。Nginx Unit提供了基于RESTful API的动态配置方法简化了复杂的配置内容标准化的JSON配置内容更便于阅读对Web服务的配置变更均在内存中完成无须中断服务。Nginx Unit的最终目标是为多种语言应用创建一个统一的运行平台并使应用程序代码以安全、可靠及最佳性能的方式运行。Nginx Unit将应用运行的网络通信层与应用代码拆分使应用代码可更专注于业务功能的实现并能更方便地以Service Mesh方式作为微服务架构中的基础设施。2.2、开源微服务网关KongKong是一款开源的API平台它是基于Nginx扩展版OpenResty的Lua应用其将Nginx的配置解构成多个Lua应用模块通过Lua应用实现了Nginx中各请求阶段的操作。Kong把Nginx操作的配置存储在外部数据库中并提供了REST风格的管理接口用户可以通过管理接口实现Kong所有功能的动态操作。Kong支持PostgreSQL和Cassandra两种数据库可以通过数据库的主从同步或分布式部署实现配置数据的高可用多台Kong服务器通过数据库共享配置数据实现对多台Kong服务器的统一配置管理。Kong提供了基于Lua脚本实现的多种功能插件在将用户请求转发给后端服务之前用户可使用这些插件实现用户请求的认证、访问限流、链路跟踪、日志处理等各种操作。Kong是一个微服务网关平台它作为微服务API的统一入口对外提供服务为方便API的管理定义了如下术语。2.2.1、消费者Kong系统中把访问微服务API的用户定义为消费者用户可以通过消费者对象定义消费者身份并可通过相关插件实现消费者访问路由规则或服务的授权。2.2.2、消费者接口消费者接口是消费者访问微服务API的接口用于实现后端被代理目标的访问转发。2.2.3、管理接口管理接口是进行Kong功能配置的接口可通过管理接口对操作对象进行配置其约定了REST风格的语法用户可以很容易地通过管理接口实现对Kong的功能配置。2.2.4、操作对象Kong为方便实现Nginx配置的动态管理定义了多个操作对象和对象参数通过管理接口对不同的操作对象按照该对象的对象参数进行配置可以非常快速地完成Kong的管理操作。Kong常用的操作对象有目标(target)对象、上游(upstream)对象、服务(service)对象、路由(route)对象、消费者(consumer)对象、插件(plugin)对象、证书(certificate)对象、CA证书(CA Certificate)对象、SNI对象。目标对象和上游对象构成真实的被访问服务器集群可通过上游对象实现目标对象的负载均衡、会话保持等配置。路由对象和服务对象构成了Nginx虚拟主机的访问入口路由和转发目标的配置服务对象可以直接代理一个外部主机域名也可以直接关联上游对象实现用户请求的转发。插件对象由不同的功能插件脚本组成其可以与路由对象、服务对象及消费者对象关联实现消费者对象请求转发给后端服务之前的各种功能操作。消费者对象用于描述客户端标识通过认证及ACL插件可以对其进行访问认证和访问路由对象或服务对象的授权。证书对象、CA证书对象、SNI对象均用于SSL相关配置。由于管理工具Konga基于管理接口提供了更加方便的Web化操作方式这里为方便读者理解和操作便直接使用Konga配置界面的对象参数介绍Kong的相关操作对象和对象参数。(1)目标对象目标对象等同于Nginx配置中上游服务器的主机一个上游对象可以关联多个目标对象目标对象的配置是动态即时生效的。由于上游对象需要维护目标对象的变更记录因此目标对象只能手动或通过管理接口DELETE方法设置权重为0。目标对象的对象参数说明如表所示。(2)上游对象Kong的上游对象用于描述Nginx配置指令域upstream的配置内容Kong支持对其所关联的目标对象进行主动或被动健康检测的设置。Kong为方便上游对象及其关联目标对象的管理通过Lua脚本实现了加权轮询(round-robin)、一致性哈希(consistent-hashing)、最少连接(least-connections)负载均衡算法默认为轮询。一个上游对象由多个目标对象组成可以通过管理接口实现目标对象的动态变更。通常在一致性哈希算法和加权轮询负载策略下目标对象数量的动态变化会引起负载策略的重新计算虽然这种影响无法避免但为了降低因负载算法重新计算产生的影响Kong为每个上游对象定义了一个环平衡器(ring-balancer)每个环平衡器有预先定义好数量的插槽(slot)上游对象中的每个目标对象将根据其权重被分配到相应数量的插槽当目标对象数量变化时只需对部分目标对象重新分配插槽而不需要负载策略的重新计算。环平衡器只有在上游对象更改总插槽数时才会进行负载策略的重新计算目标对象初始分配的插槽数官方建议至少为100个当上游对象预期为8个时即使初始时为两个目标也至少应将总插槽数定义为800。上游对象的对象参数说明如表所示。(3)服务对象Kong中的服务(Service)对象是指被代理的服务目标既可以是一个域名也可以是一个上游对象的名称区别在于是否由Kong实现负载均衡。每个服务对象可以关联多个路由对象。一个服务对象只能关联一个上游对象或被代理的主机域名。服务对象的对象参数说明如表所示。(4)路由对象路由(Route)对象用于表示Nginx配置中虚拟主机的配置对应Nginx的指令域Server及其包含的location配置。Kong配置结构中因为服务对象用于关联被代理的目标而路由对象单独存在没有意义所以其必须与服务对象关联使用。路由对象的对象参数说明如表所示。(5)插件对象插件对象用于对用户在消费接口的请求/响应闭环中的不同插件执行方法进行配置不同的插件与路由对象、服务对象及消费者对象关联实现对消费者对象在Nginx中各请求阶段的相关操作。Kong的插件对象既可以关联到服务对象实现所有该服务的请求控制也可以关联到路由对象仅对某些路由接口的请求进行控制甚至是更细粒度的仅对指定的消费者进行控制。一个插件在一个请求的生命周期中只运行一次当一个插件被与多个操作对象关联时与路由对象、服务对象及消费者对象这3个对象关联的越具体则执行优先级最高插件的全局配置优先级最低。(6)消费者对象消费者对象是描述用户身份的对象通过认证及ACL插件可以对其进行访问认证和访问路由对象或服务对象的授权。(7)证书对象证书对象表示HTTPS域名关联的证书证书对象用于存储SSL证书的公共证书/私钥对。Kong使用这些对象来处理加密请求的SSL终止。(8)CA证书对象CA证书对象表示受信任的CA。Kong使用这些对象来验证客户端或服务器证书的有效性。(9)SNI对象Kong的SNI(Server Name Indication)对象可与证书对象进行关联将证书/密钥对绑定到一个或多个域名。SNI是一种改善SSL/TLS的技术用于对客户端请头中Host字段进行处理通过对Host字段的识别解决了当一个服务器绑定多个域名时SSL证书选择的问题服务器将根据Host字段的域名返回该域名的SSL证书。2.3、安装部署Kong可以灵活地部署在用户的局域网中其同样支持多种部署方式官方在DockerHub上提供了Docker镜像方便用户快速实现Kong的Docker化部署。部署步骤如下。(1)首先初始化系统环境并安装Docker应用配置样例如下# 安装yum工具yuminstall-yyum-utils# 安装Docker官方yum源yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo# 安装Docker及docker-compose应用yuminstall-ydocker-cedocker-compose# 设置Docker服务开机自启动systemctlenabledocker# 启动Docker服务systemctl startdocker(2)Kong应用部署Kong将Nginx的配置存储在外部数据库可以通过自带的数据库初始化命令自动完成数据库表结构的创建和初始数据的添加为方便一次性创建该脚本会启动独立的容器kong-migrations来完成此项操作。此处脚本创建的Kong规划为主管理服务器管理接口不提供外部访问仅提供在同一虚拟网络内的Web工具的访问因此设置为固定IP。Docker-compose脚本内容如下version:2.1# 创建名为kong-net的虚拟网络networks: kong-net: ipam: config: - subnet:172.19.0.0/24 gateway:172.19.0.1 name: kong-net services:# 创建用于数据库初始化的独立容器kong-migrations: hostname: kong-migrations container_name: kong-migrations image: kong:latest command: kong migrations bootstrap depends_on: db: condition: service_healthy env_file: - .env_kong links: - db:db networks: - kong-net restart: on-failure# 创建Kong容器kong: hostname: kong-nginx container_name: kong-nginx image: kong:latest depends_on: db: condition: service_healthy env_file: - .env_kong networks: kong-net: ipv4_address:172.19.0.201 ports: -8000:8000/tcp# 用于监听HTTP协议的消费接口实现用户请求的接入# - 8001:8001/tcp # 用于监听HTTP协议的管理接口此处关闭外部访问-8443:8443/tcp# 用于监听HTTPS协议的消费接口实现用户请求的接入# - 8444:8444/tcp # 用于监听HTTPS协议的管理接口此处关闭外部访问# network_mode: host # 在高并发应用场景下可以将Docker容器以host模式运行# 提高传输效率healthcheck: test:[CMD,kong,health]interval: 10s timeout: 10s retries:10restart: on-failure# 创建Kong的postgreSQL数据库容器db: hostname: kong-postgres container_name: kong-postgres image: postgres:9.5 env_file: - .env_postgress healthcheck: test:[CMD,pg_isready,-U,kong]interval: 30s timeout: 30s retries:3restart: on-failure stdin_open:truetty:truenetworks: - kong-net ipv4_address:172.19.0.202 volumes: - /opt/data/apps/kong/postgresql/data:/var/lib/postgresql/data环境变量文件内容如下cat.env_kongEOF KONG_ADMIN_ACCESS_LOG/dev/stdout KONG_ADMIN_ERROR_LOG/dev/stderr KONG_ADMIN_LISTEN0.0.0.0:8001 KONG_CASSANDRA_CONTACT_POINTSdb KONG_PROXY_ACCESS_LOG/dev/stdout KONG_PROXY_ERROR_LOG/dev/stderr KONG_DATABASEpostgres KONG_PG_DATABASEkong-data KONG_PG_HOSTdb KONG_PG_PASSWORDkong KONG_PG_USERkong EOFcat.env_postgressEOF POSTGRES_DBkong-data POSTGRES_PASSWORDkong POSTGRES_USERkong EOF(3)Kong的Web管理工具KongaKonga是基于Node.js开发的Kong开源管理工具它不仅提供了Kong管理接口的全部操作对象的管理功能同时还可以对多个Kong节点进行管理包括Kong节点的备份、还原、健康监测等还提供了多用户的功能让Kong的日常管理操作可以更加方便灵活。Konga通过数据存储操作用户及Kong管理相关的配置此处与Kong共用PostgreSQL数据库可通过如下命令创建并初始化数据库实例kongadockerrun--networkkong-net--rmpantsel/konga-cprepare-apostgres-upostgresql://kong:kong172.19.0.202:5432/konga编写docker-compose脚本脚本内容如下version:2.1services:# 创建konga容器konga: hostname: konga container_name: konga image: pantsel/konga env_file: - .env_konga external_links: - kong-postgres:db ports: -1337:1337/tcpnetworks: - kong-net# 加入名为kong-net的虚拟网络networks: kong-net: external:truename: kong-net环境变量文件内容如下cat.env_kongaEOF DB_ADAPTERpostgres DB_HOSTdb DB_USERkong DB_PASSWORDkong DB_DATABASEkonga NODE_ENVproduction EOFKong集群只需在其他服务器部署Kong节点并连接到同一个PostgreSQL数据库即可Kong为避免频繁地进行数据库连接会将数据库的内容缓存在本机内存中管理接口修改数据库配置后Kong的配置会在同步周期下一次开始时生效同步周期可以通过配置文件kong.conf中的配置参数db_update_frequency进行修改默认时间为5秒。2.4、微服务网关应用作为一款微服务网关应用Kong通过插件功能实现了微服务网关的多种功能此处分别以访问认证、请求终止、数据整形为例为了方便读者理解和应用此处均使用管理接口直接操作功能参数仍以Konga页面显示的名称进行说明。(1)访问认证Kong提供了基本认证、密钥认证、OAuth2认证、HMAC认证、JWT认证、LDAP认证等多种方式的认证插件此处列举常见的密钥认证方式配置。密钥认证插件参数说明如表所示。接口认证是服务开发中常见的功能Kong插件的认证功能可以让开发工程师不必单独开发此功能仅需选择使用Kong的认证机制或通过认证转发使用内部的认证服务器让所有的接口服务很容易地实现统一认证的功能。在下面的配置样例中在Konga中按照参数配置添加密钥认证插件认证密钥名称为apikey。# 创建服务curl-i-XPOST\--urlhttp://10.10.4.8:8001/services/\--datanamebaidu\--dataurlhttps://www.baidu.com# 创建路由curl-i-XPOST\--urlhttp://10.10.4.8:8001/services/baidu/routes\--datanamebaidu\--datapaths[]/v1/baidu# 访问测试确认路由规则curl-i-XGET\--urlhttp://10.10.4.8:8000/v1/baidu# 关联插件到路由对象实例baiducurl-i-XPOST\--urlhttp://10.10.4.8:8001/routes/baidu/plugins\--datanamekey-auth\--dataconfig.key_namesapikey\# 创建消费者curl-dusernametest123http://10.10.4.8:8001/consumers/# 创建消费者密钥curl-XPOST http://10.10.4.8:8001/consumers/test123/key-auth-d# 查看并获得密钥curlhttp://10.10.4.8:8001/consumers/test123/key-auth# 消费者使用密钥访问curl-i-XGET\--urlhttp://10.10.4.8:8000\--headerapikey: xKgpAM6qBQE3e8nrR51dIrK89ggRdelf(2)请求终止请求终止(request-termination)插件原设计场景是进行请求熔断等安全管理但其同样适用于做依赖该接口的测试桩场景通过Kong的请求终止插件可以非常快速地实现该功能而且不需要做任何代码改动测试桩的创建和撤销也非常简单。插件参数说明如表所示。下面是一个测试桩的样例该插件可以对当前接口的请求返回固定格式的JSON数据该场景可以满足不同团队合作时在真实业务API代码开发完毕前让合作方、前端及测试人员进行代码升级或测试。# 创建服务curl-i-XPOST\--urlhttp://10.10.4.8:8001/services/\--datanamebaidu\--dataurlhttps://www.baidu.com# 创建路由curl-i-XPOST\--urlhttp://10.10.4.8:8001/services/baidu/routes\--datanamebaidu2\--datapaths[]/v2/baidu# 访问测试确认路由规则curl-i-XGET\--urlhttp://10.10.4.8:8000/v2/baidu# 关联插件到路由对象实例baiducurl-i-XPOST\--urlhttp://10.10.4.8:8001/routes/baidu2/plugins\--datanamerequest-termination\--dataconfig.status_code200\--dataconfig.content_typeapplication/json; charsetutf-8\--dataconfig.body{\status\: 200,\data\: {\status_code\: 403,\message\:\测试数据\},\message\:\专业测试桩\}# 测试结果curl-i-XGET\--urlhttp://10.10.4.8:8000/v2/baidu(3)数据整形通常一套服务提供的JSON格式数据是固定的但在多个团队的开发合作中可能需要对接口数据返回格式有不同的需求以往大家都希望用一个统一的标准进行规范化的JSON数据格式输出但执行起来则会遇到诸多现实问题。通过Kong的插件可以让使用方和供给方不必再为这种标准而纠结开发人员不需要修改代码仅需要简单进行Lua脚本编写就可以实现现有服务的供给或使用需求这里使用Kong的第三方插件API转换(API Transformer)插件做样例在中间进行数据整形大家也可以根据实际需求定制自己的Kong插件。API转换插件功能参数如表所示。此处演示将管理接口返回的JSON数据格式修改为前端jQuery插件DataTables的数据格式。因API转换插件的request_transformer参数为必选项即便不需要请求阶段数据整形也要为此参数指定文件如下样例中将创建一个返回空数据的req.lua文件。# 安装插件gitclone https://github.com/qnap-dev/kong-plugin-api-transformer.gitcdkong-plugin-api-transformer luarocksmake# 启用插件需要重启Kong才可生效sed-i/\session\,/a\\api-transformer\/usr/local/share/lua/5.1/kong/constants.lua# 创建服务代理目标为管理接口curl-i-XPOST\--urlhttp://10.10.4.8:8001/services/\--datanameadminapi\--dataurlhttp://10.10.4.8:8001# 创建路由curl-i-XPOST\--urlhttp://10.10.4.8:8001/services/adminapi/routes\--datanameadminapi\--datapaths[]/adminapi# 访问测试确认路由策略curl-i-XGET\--urlhttp://10.10.4.8:8000/adminapi# 关联插件到路由adminapicurl-XPOST http://10.10.4.8:8001/routes/adminapi/plugins\--datanameapi-transformer\--dataconfig.request_transformer/etc/kong/scripts/req.lua\--dataconfig.response_transformer/etc/kong/scripts/datatables.lua\--dataconfig.http_200_alwaystrue# 创建req.lua此处需要在Kong系统中进行操作mkdir-p/etc/kong/scriptsechoreturn true,\\/etc/kong/scripts/req.lua# 创建响应数据整形脚本datatables.lua此处需要在Kong系统中进行操作cat/etc/kong/scripts/datatables.luaEOF local return_body { data {} } local _resp_json_body ngx.ctx.resp_json_body return_body.data _resp_json_body.data local i 0; for _, obj in pairs(return_body.data) do # 此处可进行相关字段的变更或过滤 i i 1; end return_body[page_size] i return_body[recordsFiltered] i return_body[recordsTotal] i return true, _cjson_encode_(return_body) EOF# 访问测试确认返回数据curl-i-XGET\--urlhttp://10.10.4.8:8000/adminapi/routesKong的插件都是基于Lua脚本实现的通过Nginx可以实现用户请求过程中各阶段的数据操作此处不再举例大家可以根据实际需求灵活使用Kong的功能。
阅读完成 · 觉得有帮助?
咨询建站