42.Gateway API
Gateway API
注意
除了直接使用
GatewayClass
、Gateway
、HTTPRoute
、TCPRoute
等。
目标
GatewayClass
、Gateway
、HTTPRoute
、TCPRoute
等。使用这些资源共同为各种网络用例建模。
下图中展示的是
Gateway API 与Ingress 有什么不同?
Gateway 相较于Ingress 做了哪些改进?
以下是
更具表现力
更具扩展性
面向角色
它们被分离成不同的
通用性
这不是一种改进,而是应该保持不变。正如
共享网关
它们允许独立的路由资源绑定到同一个网关,从而实现负载均衡器和
类型化后端引用
通过类型化后端引用,
跨命名空间引用
跨越不同
类
GatewayClass
将负载均衡实现的类型形式化。这些类使用户可以很容易和明确地了解资源模型本身有什么样的能力。
在了解了
角色划分
- 基础设施提供方:如
AWS 、GKE 等 - 集群运维:管理整个集群的计算、存储、网络、安全等
- 应用程序开发者:为自己开发的应用负责,管理应用的健壮性
- 应用管理员:不是所有的公司都有,通常在一些复杂系统中会有专门的应用管理员

集群运维人员创建从 GatewayClass 派生的 Gateway 资源。此
这种灵活性技能保持
资源模型
注意:资源最初将作为networking.x-k8s.io
GatewayClass
:定义了一组具有共同配置和行为的网关。Gateway
:流量请求端点,流量从这里被翻译成集群内的服务。Route
:描述了通过Gateway 而来的流量如何映射到服务。
GatewayClass
GatewayClass
定义了一组共享共同配置和行为的GatewayClass
由一个控制器处理,但控制器可以处理多个 GatewayClass
。
GatewayClass
是一个集群范围的资源。必须至少定义一个 GatewayClass
,Gateway
才能够生效。实现GatewayClass
资源来实现,用户可以在自己的 Gateway
中引用该资源。
这类似于 Ingress
的 IngressClass
和 PersistentVolumes
的 StorageClass
。在Ingress
GatewayClass
的是 ingress-class
注解,而在IngressClass
一样。
下面是一个 GatewayClass
的配置示例。
kind: GatewayClass
metadata:
name: cluster-gateway
spec:
controllerName: "example.net/gateway-controller"
GatewayClass
一般由基础设施提供商来创建,用户不需要关注控制器如何实现,只需要了解该 GatewayClass
创建的对应 Gateway
的属性即可。
GatewayClass.spec.parametersRef
字段来配置:
kind: GatewayClass
metadata:
name: internet
spec:
controllerName: "example.net/gateway-controller" # 该字段的值应为集群唯一的
parametersRef:
group: example.net/v1alpha1
kind: Config
name: internet-gateway-config
---
apiVersion: example.net/v1alpha1
kind: Config
metadata:
name: internet-gateway-config
spec:
ip-address-pool: internet-vips
...
建议使用 GatewayClass.spec.parametersRef
自定义资源配置,不过你也可以使用
在刚部署GatewayClass.status
中的状态类型为 Accepted
但是 status
为 False
,控制器处理完配置后 status
将变为 True
,如果在该过程中出现错误,那么会显示在状态中,如下所示。
kind: GatewayClass
...
status:
conditions:
- type: Accepted
status: False
Reason: BadFooBar
Message: "foobar" is an FooBar.
Gateway
Gateway
描述了如何将流量翻译到集群内的服务。它定义了一个将流量从不了解
Gateway
定义了对实现 GatewayClass
配置和行为约定的特定负载均衡器配置的请求。该资源可以由运维人员直接创建,也可以由处理 GatewayClass
的控制器创建。
由于 Gateway
规范捕获了用户意图,它可能不包含规范中所有属性的完整规范。例如,用户可以省略地址、端口、GatewayClass
的控制器可以为用户提供这些缺省设置,从而使规范更加可移植。这种行为将通过 GatewayClass
状态对象来明确。
一个 Gateway
可以包含一个或多个 Route
引用,这些 Route
引用的作用是将一个子集的流量引导到一个特定的服务上。
Gateway
规范中定义了以下内容:
GatewayClassName
:定义此网关使用的GatewayClass
对象的名称。Listeners
:定义主机名、端口、协议、终止、TLS 设置以及哪些路由可以附加到监听器。Addresses
:定义为此Gateway 请求的网络地址。
如果以上规范中的配置无法实现,
下面展示的是使用 Envoy Gateway 生成的
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"gateway.networking.k8s.io/v1beta1","kind":"Gateway","metadata":{"annotations":{},"name":"eg","namespace":"default"},"spec":{"gatewayClassName":"eg","listeners":[{"name":"http","port":8080,"protocol":"HTTP"}]}}
creationTimestamp: "2022-10-22T07:03:28Z"
generation: 1
name: eg
namespace: default
resourceVersion: "326707757"
uid: 20f37614-1814-4c4a-b3ee-8d923a1a78f8
spec:
gatewayClassName: eg
listeners:
- allowedRoutes:
namespaces:
from: Same
name: http
port: 8080
protocol: HTTP
status:
addresses:
- type: IPAddress
value: 11.11.11.11 # 如果 Envoy Gateway 部署在云上,云会创建一个 LoadBalancer 实例从而获得一个外部 IP,该 IP 为网关 IP
conditions:
- lastTransitionTime: "2022-10-22T07:03:28Z"
message: The Gateway has been scheduled by Envoy Gateway
observedGeneration: 1
reason: Scheduled
status: "True"
type: Scheduled
- lastTransitionTime: "2022-10-22T07:04:17Z"
message: Address assigned to the Gateway, 1/1 envoy Deployment replicas available
observedGeneration: 1
reason: Ready
status: "True"
type: Ready
listeners:
- attachedRoutes: 1
conditions:
- lastTransitionTime: "2022-10-22T07:03:30Z"
message: Listener is ready
observedGeneration: 1
reason: Ready
status: "True"
type: Ready
name: http
supportedKinds:
- group: gateway.networking.k8s.io
kind: HTTPRoute
从上面的示例中我们可以看到 status
中显示了
Route
Route
对象定义了特定协议的规则,用于将请求从 Gateway
映射到
从Route
资源类型。对于其他协议,鼓励使用特定于实现的自定义路由类型。未来可能会向
注意
HTTPRoute
HTTPRoute
用于多路复用
parentRefs
:定义此路由要附加到的Gateway 。hostnames
(可选) :定义用于匹配HTTP 请求的主机头的主机名列表。rules
:定义规则列表以针对匹配的HTTP 请求执行操作。每条规则由matches
、 filters
(可选)和backendRefs
(可选)字段组成。
下图展示了流量经过网关和
TLSRoute
TLSRoute
用于多路复用
TCPRoute 和UDPRoute
TCPRoute
(和 UDPRoute
)旨在用于将一个或多个端口映射到单个后端。在这种情况下,没有可用于在同一端口上选择不同后端的鉴别器(DiscriminatorTCPRoute
确实需要监听器上的不同端口。你可以终止
GRCPRoute
GRPCRoute
用于路由GRPCRoute
的网关需要支持
Route 类型列表
下面的「路由鉴别器」一栏是指可以使用哪些信息来允许多个
对象 | 路由鉴别器 | 目的 | ||
---|---|---|---|---|
HTTPRoute |
第 |
仅终止 | ||
TLSRoute |
第 |
直通或终止 | ||
TCPRoute |
第 |
目的端口 | 直通或终止 | 允许将 |
UDPRoute |
第 |
目的端口 | 没有任何 | 允许将 |
GRPCRoute |
第 |
仅终止 | 基于 |
请注意,通过 HTTPRoute
和 TCPRoute
路由的流量可以在网关和后端之间进行加密(通常称为重新加密
ReferenceGrant
注意
ReferenceGrant
资源仍在实验阶段,更多信息请参考版本文档。
ReferenceGrant
可用于在
过去,我们已经看到跨命名空间边界转发流量是一种理想的功能,但如果没有 ReferenceGrant
之类的保护措施, 就会出现漏洞。
如果从其命名空间外部引用一个对象,则该对象的所有者必须创建一个 ReferenceGrant
资源以显式允许该引用,否则跨命名空间引用是无效的。
将路由添加到网关
将
如何将
- 一对一:
Gateway 和Route 可以由单个所有者部署和使用,具有一对一的关系。 - 一对多:
Gateway 可以绑定许多Route ,这些Route 由来自不同命名空间的不同团队拥有。 - 多对一:
Route 也可以绑定到多个Gateway ,允许单个Route 同时控制跨不同IP 、负载均衡器或网络的应用程序。
路由绑定
当 Route
绑定到 Gateway
时,代表应用在 Gateway
上配置了底层的负载均衡器或代理。哪些 Route
如何绑定到 Gateway
是由资源本身控制的。Route
和 Gateway
资源具有内置的控制,以允许或限制它们之间如何相互选择。这对于强制执行组织策略以确定 Route
如何暴露以及在哪些 Gateway
上暴露非常有用。请看下面的例子。
一个Infra
命名空间中部署了一个名为 shared-gw
的 Gateway
,供不同的应用团队使用,以便将其应用暴露在集群之外。团队Route
绑定到这个 Gateway
。它们互不相识,只要它们的 Route
规则互不冲突,就可以继续隔离运行。团队Gateway
来代理。团队Gateway
specialive-gw
,该
不同命名空间及 Gateway
与 Route
的绑定关系如下图所示。

将路由附加到网关包括以下步骤:
Route 需要在其parentRefs
字段中引用Gateway 的条目;Gateway 上至少有一个监听器允许其附加。
策略附件
策略附件(Policy Attachment)是一种自定义策略资源,例如超时、重试、健康检查等,这些功能在不同的网关实现中的细节各不相同个,为了
附加到
- 将策略附加到资源的标准化方法。
- 支持在策略资源中配置默认值和覆盖值。
- 用于说明默认值和覆盖值应如何交互的层次结构。
这种标准化不仅可以实现一致的模式,还可以让未来的工具(例如
你可以使用 targetRef
字段指定策略附件附加到的资源对象,例如下所示:
apiVersion: networking.acme.io/v1alpha1
kind: RetryPolicy
metadata:
name: foo
spec:
default:
maxRetries: 5
targetRef:
group: networking.acme.io
kind: ExternalService
name: foo.com
该在例子中,为一个外部服务配置了一个重试策略。你可以给几乎任何可以发送、接收流量的对象附加策略,例如 GatewayClass
、Gateway
、Service
、Route
、Namespace
,不过附加策略的时候,需要注意其优先级。
策略优先级
你可以给策略附件指定 override
和 default
值,其在入口和网格内不同资源上的覆盖值和默认值的优先级是如下图所示。
从图中我们可以看到:
-
覆盖值:上层覆盖下层
-
默认值:下层覆盖上层
引用网关
parentRef
中指定命名空间(如果parentRef
中的以下字段进一步选择
- SectionName:当设置了
sectionName
时,Route 选择具有指定名称的监听器; - Port:当设置了
port
时,Route 会选择所有指定的监听端口且协议与此类Route 兼容的监听器。
当设置了多个 parentRef
字段时,sectionName
和 port
两者都设置时,
限制路由附加
每个
- Hostname:如果监听器上设置了
hostname
,附加路由的hostnames
中必须至少有一个重叠值。 - Namespace:监听器上的
allowedRoutes.namespaces
字段可用于限制可以附加路由的位置。该namespaces.from
字段支持以下值:SameNamespace
是默认选项。只有与该网关相同的命名空间中的路由才会被选择。All
可选择来自所有命名空间的Route
。Selector
意味着该网关将选择由Namespace 标签选择器选择的Namespace 子集的Route 。当使用Selector 时,那么listeners.route.namespaces.selector
字段可用于指定标签选择器。All
或SameNamespace
不支持该字段。
- Kind:监听器上的
allowedRoutes.kinds
字段可用于限制可能附加的路由种类。
如果未指定上述任何一项,网关监听器将信任从支持监听器协议的同一命名空间附加的路由。
Gateway - Route 附加示例
在下面的例子中 gateway-api-example-ns1
命名空间中的my-route
foo-gateway
中,不会附加到任何其他foo-gateway
位于与foo-gateway
必须允许来自 gateway-api-example-ns2
命名空间中的
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: my-route
namespace: gateway-api-example-ns2
spec:
parentRefs:
- kind: Gateway
name: foo-gateway
namespace: gateway-api-example-ns1
rules:
- backendRefs:
- name: foo-svc
port: 8080
foo-gateway
允许my-route
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: foo-gateway
namespace: gateway-api-example-ns1
spec:
gatewayClassName: foo-lb
listeners:
- name: prod-web
port: 80
protocol: HTTP
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
# 该 label 在 Kubernetes 1.22 中自动添加到所有命名空间中
kubernetes.io/metadata.name: gateway-api-example-ns2
对于一个更宽松的示例,下面的网关将允许所有expose-apps: true
标签的命名空间附加。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: prod-gateway
namespace: gateway-api-example-ns1
spec:
gatewayClassName: foo-lb
listeners:
- name: prod-web
port: 80
protocol: HTTP
allowedRoutes:
kinds:
- kind: HTTPRoute
namespaces:
from: Selector
selector:
matchLabels:
expose-apps: "true"
组合类型
GatewayClass
、Gateway、xRoute
和 Service
的组合将定义一个可实现的负载均衡器。下图说明了不同资源之间的关系。

请求流程
使用反向代理实现的网关的一个典型的客户端
- 客户端向
http://foo.example.com
发出请求。 DNS 将该名称解析为Gateway
地址。- 反向代理在
Listener
上接收请求,并使用Host
header 来匹配HTTPRoute
。 - 可选地,反向代理可以根据
HTTPRoute
中的match
规则执行请求header 和/ 或路径匹配。 - 可选地,反向代理可以根据
HTTPRoute
中的filter
规则修改请求,即添加/ 删除header 。 - 最后,反向代理可以根据
HTTPRoute
中的forwardTo
规则,将请求转发到集群中的一个或多个对象,即Service
。
TLS 配置
我们可以在 Gateway
监听器上配置
首先我们先说明几个术语:
- 下游:客户端和网关之间的链接。
- 上游:网关与路由器指定的后端服务之间的链接。
其关系如下图所示。
通过
根据监听器协议,支持不同的
监听器协议 | 支持的路由类型 | |
---|---|---|
TLS | 直通 | TLSRoute |
TLS | 终止 | TCPRoute |
HTTPS | 终止 | HTTPRoute |
请注意,在Passthrough
(直通)
下游TLS
下游
监听器和TLS
监听器基于每个域或子域公开hostname
条件的所有域。
在以下示例中,default-cert
listeners:
- protocol: HTTPS # Other possible value is `TLS`
port: 443
tls:
mode: Terminate # If protocol is `TLS`, `Passthrough` is a possible mode
certificateRef:
kind: Secret
group: ""
name: default-cert
如果 hostname.match
设置为Exact
,则hostname.name
中设置的特定主机名。
示例
具有不同证书的监听器
在下面的示例中,配置foo.example.com
和 bar.example.com
域。这些域的证书在
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: tls-basic
spec:
gatewayClassName: acme-lb
listeners:
- name: foo-https
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: foo-example-com-cert
- name: bar-https
protocol: HTTPS
port: 443
hostname: bar.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: bar-example-com-cert
通配符TLS 监听器
在下面的示例中,*.example.com
和 foo.example.com
域配置了不同的通配符证书。由于特定匹配具有优先权,所有对 foo.example.com
的请求将使用 foo-example-com-cert
,所有对 exmaple.com
的其他请求使用 wildcard-example-com-cert
证书。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: wildcard-tls-gateway
spec:
gatewayClassName: acme-lb
listeners:
- name: foo-https
protocol: HTTPS
port: 443
hostname: foo.example.com
tls:
certificateRefs:
- kind: Secret
group: ""
name: foo-example-com-cert
- name: wildcard-https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
certificateRefs:
- kind: Secret
group: ""
name: wildcard-example-com-cert
跨命名空间证书引用
在此示例中,配置ReferenceGrant
以允许跨命名空间引用。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: cross-namespace-tls-gateway
namespace: gateway-api-example-ns1
spec:
gatewayClassName: acme-lb
listeners:
- name: https
protocol: HTTPS
port: 443
hostname: "*.example.com"
tls:
certificateRefs:
- kind: Secret
group: ""
name: wildcard-example-com-cert
namespace: gateway-api-example-ns2
---
apiVersion: gateway.networking.k8s.io/v1alpha2
kind: ReferenceGrant
metadata:
name: allow-ns1-gateways-to-ref-secrets
namespace: gateway-api-example-ns2
spec:
from:
- group: gateway.networking.k8s.io
kind: Gateway
namespace: gateway-api-example-ns1
to:
- group: ""
kind: Secret
扩展
网关options
映射来为特定于实现的功能添加额外的
扩展点
以下是
BackendRefs
:此扩展点应用于将流量转发到核心Kubernetes 服务资源以外的网络端点。例如S3 存储桶、Lambda 函数、文件服务器等。HTTPRouteFilter
:HTTPRoute
中的这种API 类型提供了一种挂钩HTTP 请求的请求/ 响应生命周期的方法。- 自定义路由:如果上述扩展点都不能满足用例的需要,实施者可以选择为
API 当前不支持的协议创建自定义路由资源。自定义路由类型需要共享与核心路由类型相同的字段。这些包含在CommonRouteSpec
和RouteStatus
中。