背景
Gateway API 的意义和价值:
-
支持更丰富的流量协议,适用于服务网格等更复杂的场景,不仅限于 HTTP。可以作为 Kubernetes 的流量入口 API 进行统一。
-
可以实现细粒度的流量控制,精确到服务级别的路由,提供更强大的流量管理能力。
发展现状
版本现状
Gateway API 目前还处于开发阶段,尚未发布正式版本。其版本发展现状如下:
-
v1.0: 首个正式GA版本,API稳定,可以用于生产环境。但功能还会持续完善。
可用场景
-
动态路由:HTTPRoute 支持基于路径、请求头、请求参数和请求体等条件的动态路由。这使得您可以根据请求的不同属性将流量路由到不同的后端服务,以满足不同的需求。
多版本部署:如果您的应用程序有多个版本,您可以使用 HTTPRoute 来将流量路由到不同的版本,以便测试和逐步升级。例如,您可以将一部分流量路由到新版本进行测试,同时保持旧版本的运行。
周边生态
目前,尽管 Gateway API 还处于开发阶段,但已经有部分项目表示支持或计划支持Gateway API。主要包括:
-
Linkerd 是另一个流行的服务网格项目,Linkerd 2.10 版本添加了 Gateway API 支持。用户可以使用 Gateway API 资源来配置 Linkerd 的代理。
-
Flagger 是一款 Kubernetes 的蓝绿部署和 A/B 测试工具,Flagger 0.25版本添加了对Gateway API的支持,可以使用Gateway和HTTPRoute构建Flagger的流量路由。
-
Traefik是著名的开源边缘路由器,Traefik 2.5版本开始支持Gateway API并逐步淘汰Ingress支持。
未来规划
-
增强安全性:加强 Gateway API 的安全性,包括在传输过程中的加密、身份验证等方面,以确保网络流量的安全性。
完善功能和稳定性:继续完善 Gateway API 的功能和稳定性,以确保其能够应对不同场景的需求。
Gateway API 规范解读
基础概念
Kubernetes Gateway API 定义了三种基本资源类型:GatewayClass、Gateway、Route 。
-
Gatewayclass: 一组共享通用配置和行为的 Gateway 集合,与 IngressClass、StorageClass 类似,需要知道 Gateway API 并不会创建真正的网关,真正的网关是由一些支持 Gateway API 的社区(基础设备提供商)所提供的 Controller 所创建,如 Envoy 、Istio、Nginx。GatewayClass,Gatewayclass 的作用就是绑定一个 Controller 定义一种网关类型。
- Gateway: 可以说成 GatewayClass 的具体实现,声明后由 GatewayClass 的基础设备提供商提供一个具体存在的 Pod,充当了进入 Kubernetes 集群的流量的入口,负责流量接入以及往后转发,同时还可以起到一个初步过滤的效果。
- Route: 真实的路由,定义了特定协议的规则,用于将请求从 Gateway 映射到 Kubernetes 服务。目前只有 HTTPRoute 进入了v1beta 版本,是比较稳定的版本,后续 TCPRoute、UDPRoute、GRPCRoute、TLSRoute 等也会陆续进入 beta 版本达到生产可用,这里将只对 HTTPRoute 进行介绍。
工作原理
结构图
GatewayClass
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller #绑定的 Controller 名称
Gateway
Gateway 资源是一个中间层,需要定义所要监听的端口、协议、TLS 配置等信息,可以将网络流量的管理和控制集中到一个中心化的位置,提高集群的可用性和安全性。配置完成后,由 GatewayClass 绑定的 Controller 为我们提供一个具体存在 Pod 作为流量入口,需要注意的是,各家实现在此处还是略有不同,比如说 Envoy 当你创建 Gateway 资源后,Envoy Controller 会创建一个 Deployment 资源为你提供入口流量 Pod,然而 Nginx 则是自己本身就是流量入口 Pod 不会创建新的。
spec:
gatewayClassName: envoy #绑定的 GatewayClass 名称。
listeners: # 定义了一些监听项,供 Route 进行绑定
- allowedRoutes: #定义流量转发范围
namespaces:
from: All #允许 Gateway 往所有的 Namespace 的 Pod 转发流量。
name: http #监听项名称。
port: 8088 #监听项所占用的端口
hostname: www.gateway.*.com #定义一个域名,一般为泛域名、匹配来自该域名的流量。
protocol: HTTP #定义协议,HTTP或者HTTPS
- allowedRoutes:
namespaces:
from: All
name: https
port: 8443
protocol: HTTPS
tls: #为 HTTPS 配置加密协议
mode: Terminate #加密协议类型,Terminate 或 Passthrough
certificateRefs:
- kind: Secret
name: cafe-secret
namespace: default
协议类型:
-
Terminate:将加密的流量解密并将明文流量转发到后端服务。这种模式需要在网关处配置证书和密钥,以便对客户端和服务器之间的流量进行加密和解密,确保数据安全性。
- Passthrough:将加密的流量原样转发到后端服务。这种模式不需要在网关处配置证书和密钥,因为 TLS 连接只在后端服务处终止。这种模式适用于需要将 TLS 流量直接传递到后端服务的场景,如需要对后端服务进行更细粒度的访问控制或流量监控的情况。
HTTPRoute
#HTTPRoute A
spec:
parentRefs: #绑定 Gateway 监听项
- name: gateway #Gateway 资源名称
namespace: envoy #Gateway所在命名空间
sectionName: http #监听项名称
hostnames: #为路由配置域名
- "www.gateway.example.com" #可配置泛域名,可配置多个
rules: #配置详细的路由规则,可配置多个,下面有对各种规则类型的详细解析
- matches: #匹配条件
- path: #路径匹配
type: PathPrefix #路径类型:Exact 完全匹配/PathPrefix 前缀匹配/RegularExpression 正则匹配
value: /gateway
filters: #高级设置
- type: requestHeaderModifier #加工请求头
requestHeaderModifier: #支持 set 覆盖/add 添加/remove 删除
set:
- name: service
value: goodrain
- type: RequestRedirect #请求重定向
requestRedirect:
scheme: https # 重定向所使用的协议,http/https
hostname: www.baidu.com #重定向的域名
port: 8443 #重定向所使用的端口
statusCode: 301 #重定向状态码:301 永久的重定向/302 临时重定向
-----------------
#HTTPRoute B
spec:
parentRefs:
- name: gateway
namespace: envoy
sectionName: https
hostnames:
- "www.gateway.example.com"
rules:
- matches:
- headers: #请求头匹配
- name: service
value: goodrain
backendRefs: #后端路由
- name: goodrain-v1 # service 名称
port: 80 #service 端口
weight: 80 #权重
- name: goodrain-v2
port: 80
weight: 20
规则类型:
-
matches: 由一个或多个匹配条件组成,这些匹配条件可以基于HTTP请求的各种属性(如请求方法、路径、头部、查询参数等)进行匹配,从而确定哪些请求应该被路由到该规则对应的后端服务。
- filters: 对传入请求进行更细粒度的控制,例如修改请求的头部、转发请求到其他服务、将请求重定向到不同的URL等。它们由一组规则组成,每个规则都包含一个或多个过滤器。这些过滤器可以在请求被路由到后端服务之前或之后进行处理,以实现各种不同的功能。
- backendRefs: 用来指定后端服务的引用,它包含一个后端服务的列表,每个服务由名称和端口号组成,可以使用不同的负载均衡算法,将请求路由到后端服务的其中一个实例中,实现负载均衡。
需要注意的是,规则集有优先级,当同时存在多个规则(rule)的时候,流量会从上往下进行匹配,只要有匹配上流量会直接代理到其对应的后端或重定向到对应的路由。
Gateway API 快速上手
- Kubernetes Gateway API 基础 CRD。安装网关 API CRD地址。
- Gateway API 下游实现,即基础设备供应商。(包含 GatewayClass 资源)下游实现地址。
- 创建 Gateway,定义基础的路由方式供 HTTPRoute 选择。根据上面的字段解释自行编写。
- 创建 HTTPRoute 设置规则绑定自己的业务。根据上面的字段解释自行编写。
下面以 Envoy 提供的 demo 为例,串一下整体流程
安装Gateway API CRD 和 Envoy Controller
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v0.3.0/install.yaml
查看安装效果
# 查看安装的 CRD 资源
kubectl get crd |grep networking.k8s.io
# 查看安装的 envoy controller
kubectl get pod -n envoy-gateway-system
安装 Gateway、HTTPRoute 及示例应用
kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v0.3.0/quickstart.yaml
内部 GatewayClass 资源
资源的 controllerName 属性字段配置绑定了 envoy 的 controller
apiVersion: gateway.networking.k8s.io/v1beta1
kind: GatewayClass
metadata:
name: eg
spec:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
内部 Gateway 资源
资源的 gatewayClassName 属性字段配置绑定了 gatewayclass 资源名称 eg,同时提供了一个 对内监听端口为 80,协议类型为 http 的监听项。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: eg
spec:
gatewayClassName: eg
listeners:
- name: http
protocol: HTTP
port: 80
内部的 HTTPRoute 资源
资源的 parentRefs 属性字段配置绑定了 gateway 资源名称 eg。域名为 www.example.com,代理的后端服务类型选择了 service,名称为 backend,服务端口为 3000。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: backend
spec:
parentRefs:
- name: eg
hostnames:
- "www.example.com"
rules:
- backendRefs:
- group: ""
kind: Service
name: backend
port: 3000
weight: 1
matches:
- path:
type: PathPrefix
value: /
查看安装效果
# 查看安装的 gatewayclass 资源
kubectl get gatewayclass
# 查看安装的 gateway 资源
kubectl get gateway
# 查看安装的 httproute 资源
kubectl get httproute
#查看由 Controller 提供的流量入口 Pod。
kubectl get pod -n envoy-gateway-system
#查看路由解析地址,其中 nodeport 类型的 svc 便是你的解析地址。
kubectl get svc -n envoy-gateway-system|grep LoadBalancer
#访问
curl --resolve www.example.com:31830:xx.xxx.xx.xxx --header "Host: www.example.com" http://www.example.com:31830/get
Gateway API 生产指南
Gateway API使用到生产需要考虑易用性、可管理性和稳定性因素:
-
易用性:Gateway API扩展了很多配置内容,如果直接写yaml上手难度较大,而且容易出错,所以需要有一个基于UI的管理工具。
- 可管理性:Gateway API支持分角色管理和使用,跟平台工程的思路一致,但要用到生产需要有一个分权限和角色的平台。
- 稳定性:Gateway API当前的实现中,Envoy 和 Nginx可以用到生产环境。
具体落地过程:
在Kubernetes上安装Rainbond
管理员安装Gateway API的网关实现
通过Rainbond提供的应用市场,搜索 GatewayAPI会出来三个应用,先安装GatewayAPI-Base,再安装GatewayAPI-Envoy或Gateway-Nginx,当然也可以两个都装。
管理员配置 Gateway API的资源
平台管理 / 扩展 / 能力 点击对应资源的编辑,配置Gateway 和 GatewayClass资源。
开发者配置业务路由
补充说明:
-
从Rainbond应用市场只能安装 Envoy和Nginx两种网关实现,要支持更多网关实现需要Rainbond先支持或自己制作插件;
-
资料参考:Rainbond 的 Gateway API 插件制作实践。