前言
Hango 是由网易公司开源的一个基于Envoy构建的高性能、可扩展功能丰富的云原生API网关,本文将从Hango的诞生背景、架构设计、功能特性、大规模落地等方面进行介绍。
诞生背景
Envoy起初在网易轻舟是作为服务网格Istio的数据面使用,承担了东西向、南北向全部数据流量的代理、治理与观测职责。随着服务网格在网易内部大规模落地,我们对 Envoy 的功能、性能、扩展性、可观测性等多方面有了全面的研究与实践,也深刻感受到 Envoy 优质的内在品质,及其在云原生时代巨大的发展潜力。
于是我们开始尝试基于 Envoy 建设网易的新一代 API 网关,目标是替换网易内部较多业务采用 Java 异步化网关、 Kong 网关,并能够满足业务逐步进入云原生时代的南北向流量治理需求。从结果上看,选型 Envoy 不仅让我们顺利实现了网易 API 网关全面升级,还推动了网易云原生、微服务技术栈整体的统一与向前发展。
架构设计
Hango 基于云原生理念构建,数据面基于Envoy进行扩展,增强插件链,提供 Rider 模块用于自定义插件扩展;控制面组件包括 Slime,Istio,API Plane以及Portal模块。其架构图如下所示:
组件说明:
- Envoy: Hango网关的数据面流量入口,通过XDS模式获取Istiod配置
- Istiod: Hango网关对接Envoy的适配层,监听指定CRD并通过XDS向Envoy下发配置
- Slime: 提供指定Slime CRD,以支持Hango支持插件、限流、服务发现等特性
- Hango Portal: Hango对接前端界面的Web层模块,存储Hango业务数据
- Hango Api-plane: 对接Hango Portal,管理Hango CR声明周期
- Hango UI: Hango前端界面,提供Hango配置、观测、调试等功能
Hango UI将Envoy的功能进行了可视化的配置,与Hango Portal进行交互,Hango Portal将业务信息存于DB,并调用Hango Api-plane生成服务路由相应的CR,Istiod在Watch到API-plane生成的CR会通过XDS协议下发给数据面Envoy,Envoy将配置信息应用到数据面。
对于插件的能力的扩展,我们使用自定义的CRD(EnvoyPlugin)来承载插件信息,Slime模块监听Slime CRD,将Slime CRD转换为EnvoyFilter的插件配置对数据面envoy进行扩展。
下面是Hango的数据流向:
功能特性
虚拟网关
虚拟网关
在L7层通用网关中,一组Envoy网关集群可以表现出不同的形态,如API网关、L7负载均衡、ingress。网关集群在部署时已确定的一组网关实例,称之为网关,不同表现形态称之为虚拟网关。 依托于网关,可通过不同场景进行配置。网关数据层采用Envoy作为底层代理,通过不同的Listener配置开放Envoy不同的监听端口,对应不同形态的虚拟网关。在L7层通用网关中,一组Envoy网关集群可以表现出不同的形态,如API网关、L7负载均衡、ingress。网关集群在部署时已确定的一组网关实例,称之为网关,不同表现形态称之为虚拟网关。 依托于网关,可通过不同场景进行配置。网关数据层采用Envoy作为底层代理,通过不同的Listener配置开放Envoy不同的监听端口,对应不同形态的虚拟网关。
以下为虚拟网关的功能架构图:
一组Envoy网关实例部署在Kubernetes集群中,用户通过配置服务在网关生成Listener(虚拟网关),Listener(虚拟网关)监听对应的服务,当有请求访问该监听端口时,进行流量转发。
Kubernetes Gateway
Gateway API作为Kubernetes入口网关的最新成果,得到行业的广泛支持。它代表了Ingress功能的一个父集,定义了一系列以Gateway资源为中心的资源集合。与Ingress类似,Kubernetes 中没有内置Gateway API默认实现,需要依赖基础设施商提供Gateway Class。
官方文档见:https://gateway-api.sigs.k8s.io
作为Ingress资源的升级,Gateway API提供了一系列治理能力更强、表达性更优、可扩展性更高的资源集合,其中GatewayClass、Gateway和HTTPRoute已经进入Beta阶段,其他CRD还处于实验阶段。 此处只需要关注Gateway和xRoute资源,详细的API定义可参考Gateway API
以下图片为Gateway API的相关组件:
GatewayClass:GatewayClass是由基础架构提供商定义的集群范围的资源,该资源用于指定对应的Gateway Controller。目前已实现的Gateway Controller的产品包括Envoy Gateway(beta)、Istio(beta)、Kong(beta)等,详情可参考Gateway Controller
Gateway: 核心网关资源,主要规范了以下三部分内容:
Listeners:网关监听器列表,每个监听器都代表了一组主机名、端口、协议配置。
GatewayClassName:用于指定生效的GatewayClass。
Address:定义网关代理的请求地址。
xRoute: 代表需要不同特性协议的路由资源,每种协议路由都有特定的语义,这种模式具有较好的扩展性,例如可以定义DubboRoute、gRPCRoute等。每种资源都定义了基本的匹配、过滤和路由规则,这些规则只有被绑定到相应的Gateway资源上才可以生效。目前只有HTTPRoute进入Beta阶段。
以下为Kubernetes Gateway在hango的功能实现架构图,Gateway API在控制台被创建之后会被开源的Istio控制面将Gateway API对象转换为Istio API对象,最终下发至Envoy数据面。 hango在此基础之上对HttpRoute做了插件上的增强,提供了更多丰富的插件能力。
Kubernetes Ingress
Ingress是K8s生态中定义流量入口的一种资源,但其只是个规则,仅创建Ingress资源本身是没有任何效果的,想让其生效,就需要有一个Ingress Controller去监听K8s中的ingress资源, 并对这些资源进行规则解析,转换为其数据面中的代理规则,并由数据面来进行流量转发。当前K8s默认的Ingress Controller实现是Nginx,本次方案描述如何将通用网关纳管Ingress的流量。
Ingress资源是对集群中服务的外部访问进行管理的 API 对象,可以将集群内部服务通过HTTP或HTTPS暴露出去,流量路由规则由Ingress资源定义。
目前只支持Ingress v1版本流量纳管,v1版本的Ingress资源定义如下:
##ingress v1
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"istio"},"name":"test","namespace":"hango-system"},"spec":{"ingressClassName":"istio","rules":[{"http":{"paths":[{"backend":{"service":{"name":"istio-e2e-app","port":{"number":80}}},"path":"/get","pathType":"Prefix"}]}}]}}
kubernetes.io/ingress.class: hango
skiff.netease.com/project: hango
creationTimestamp: "2023-07-14T07:33:17Z"
generation: 7
name: test
namespace: hango-system
resourceVersion: "9320368"
labels:
istio.io/rev: gw-1.12
uid: 1ba7e839-da43-4c00-afeb-85d173911003
spec:
rules:
- http:
paths:
- backend:
service:
name: istio-e2e-app
port:
number: 80
path: /get
pathType: Prefix
status:
loadBalancer:
ingress:
- ip: xxx.xxx.xxx.xxx
Ingress v1版本的资源定义中,主要包含以下几个重要注解:
- istio.io/rev:指定网关版本,目前只支持gw-1.12
- kubernetes.io/ingress.class:指定ingress的class,目前固定为hango
- skiff.netease.com/project:指定项目ID,目前固定为hango
- spec.rules:指定ingress的路由规则,目前只支持http协议
- status.loadBalancer.ingress:指定ingress的访问地址
服务发现
目前Istio1.8之后只保留了对接Kubernetes注册中心的逻辑,但是在实际生产实践中,我们发现大量用户只是将Kubernetes作为部署和管理的平台,服务信息依旧注册在第三方服务注册中心,如Nacos和Zookeeper,因此我们必须解决对接第三方注册中心的问题,以满足用户的需求。
我们采用的方案是网易开源的slime组件作为服务发现的适配层,slime组件支持对接多种第三方注册中心,如Nacos、Zookeeper、Eureka、Consul等,同时支持对接Kubernetes注册中心,将服务发现的逻辑统一抽象为slime CRD,通过slime CRD将服务发现的逻辑下发至Envoy数据面。
slime组件的相关介绍见:Slime化解服务网格多注册中心兼容之痛
可观测
基于Envoy良好的观测性,Hango网关在网易集团内部进行规模落地过程中,结合服务网格场景,提供丰富的观测能力,整体架构如下
- 日志
Envoy中事件的详细记录,Hango网关基于Envoy进行数据面扩展,提供了灵活易配置的AccessLog,支持自定义格式,自定义顾虑规则以及输出。
基于filebeat以及elastic的能力,构建一体化日志审计平台。
- 监控
基于Envoy cluster mertic等信息,利用Promethues构建网关/服务等多维度指标体系。同时,针对网关容器化部署模式,基于Kubernetes 容器对应的 metrics构建容器维度的指标监控,涵盖CPU/内存/带宽等多维度监控。
- 链路追踪
基于Envoy开箱即用的多种tracing接入,拓展力强,目前已完成线上SkyWalking等tracing的接入。
写在最后
Hango作为一名开源领域的新生儿,我们会秉承拥抱云原生的理念,继续跟进Istio/Envoy的演进,发挥更大的领域价值。下一阶段,我们会在多语言扩展,LB融合等多场景进行发力,也期待更多关注云原生、API网关的同学能够加入Hango开源社区建设。
诚挚的欢迎大家关注Hango Gateway