Kubernetes Gateway API v1.1 解读
几天前,K8s Network SIG 发布了 Gateway API(简称 gwapi)的 v1.1 版本,这个版本的发布包含了多项重要功能的 GA(一般可用),以及一些实验功能的引入。这两部分分别通过标准渠道和实验渠道发布。
发布渠道用于指示网关 API 内的功能的稳定性。所有新功能和资源都是先从实验发布渠道开始,在后续迭代演进的过程中可能会升级到标准发布渠道,也有可能完全从 API 中废除。
通过下图可以对 gwapi 的发布渠道有个清晰的了解。
在这些更新中,在我看来当属服务网格的支持 GA 最为重要,这意味着服务网格标准 API 向着统一又迈进了一步。差不多两年前,我曾写过 SMI 与 Gateway API 的 GAMMA 倡议意味着什么, 在 gwapi 差不多 1.0 的时候,SMI 在停止更新的几个月后归档了。
标准发布渠道
GRPCRoute GA
GRPCRoute
API 的 v1
版本发布,标志着其可以在生产环境中稳定使用,并得到长期的支持的维护。同时 v1alpha2
版本被标记为废弃,在未来的版本中将会被移除。
Service Mesh Support GA
gwapi 对服务网格的支持正式毕业,并进入标准发布渠道。实现了对网格的支持后,可以使用同样的 API 来管理东西向(服务间)的流量,也因此基于 gwapi 构建的策略可以在网格中复用。有兴趣的可以看一下去年写的 探索 Gateway API 在 Service Mesh 中的工作机制,也可参考 官方文档。
从 v1.1 开始 xRoute
的可以 attach 到(父资源) Gateway
和 Service
上,具体表现为 parentRef.kind
可以是 Gateway
(默认) 和 Service
。比如:
HTTPRoute
用于网关: 省略 kind: Gateway
。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: http-app-1
spec:
parentRefs:
- name: my-gateway
rules:
...
HTTPRoute
用于服务网格:
kind: HTTPRoute
metadata:
name: smiley-route
namespace: faces
spec:
parentRefs:
- name: smiley
kind: Service
group: ""
port: 80
rules:
...
一致性检查的配置文件和报告 GA
一致性报告 API 和相应的测试套件已升级为 GA v1
版本。
关于一致性报告:
符合 Gateway API 规范的实现是指通过每个 gwapi 捆绑版本(如
gateway.networking.k8s.io/bundle-version: v1.1.0
)发布中包含的一致性测试的实现。 所有的 gwapi 实现必须通过一致性测试,且不能跳过任何一个测试。
在 v1
版本中,ConformanceReport
API 扩展了 mode
和 gatewayAPIChannel
两个字段。前者用于指定实现的工作模式,后者标识该报告适用的发布渠道:标准发布 standard
或实验发布 experimental
。
报告也以更结构化的方式重新组织,实现现在可以添加有关测试运行方式的信息并提供复现步骤。
ParentRef 的 Port 字段 GA
之前,当一个 Gateway 上配置了多个监听器时,如果想要将路由 attach 到指定的端口,
listeners:
- name: foo
protocol: HTTP
port: 8080
...
- name: bar
protocol: HTTP
port: 8090
...
- name: baz
protocol: HTTP
port: 8090
...
可以使用 sectionName
指定监听器的名字,因此需要为监听器通过 name
字段设置名字。
spec:
parentRefs:
- name: acme-lb
sectionName: foo
现在可以通过 port
字段来实现了,因为端口在网关上也是唯一的,这样就无需使用 name
字段。
spec:
parentRefs:
- name: acme-lb
port: 8080
实验发布渠道
通过 BackendLBPolicy 支持会话持久性
通过 BackendLBPolicy
引入会话持久性(session persistence)支持,该功能来自 网关增强提案 GEP-1619。
会话持久性是指客户端请求在“会话”持续时间内定向到同一后端服务器。
当客户端直接提供信息(例如请求头中的 cookie)时,代理将其用作将流量定向到特定服务器的参考。持久性是负载均衡的一个例外:持久性客户端请求绕过代理的负载平衡算法,直接到达之前与之建立会话的后端服务器。
见官方的 会话持久性定义。
gwapi 的会话持久性,可以作用于服务粒度,也可以作用与单个路由。后者的优先级更高,会覆盖服务粒度的会话持久性配置。
路由粒度的会话持久性,通过路由规则中 sessionPersistence
配置。
kind: HTTPRoute
metadata:
name: routeX
spec:
rules:
- matches:
- path:
value: /a
backendRefs:
- name: servicev1
sessionPersistence:
name: session-a
服务粒度的会话持久性则是通过 BackendLBPolicy
来配置。
kind: BackendLBPolicy
metadata:
name: lbp
spec:
targetRef:
kind: Service
Name: servicev1
sessionPersistence:
sessionName: service-cookie
type: Cookie
注:核心 API 中的 type
是 Cookie
,在实现可以扩展支持任意请求头,类型为 Header
。
客户端证书校验
网关增强提案 GEP-91 讨论了如何验证前端客户端在 TLS 握手协议期间向服务器提供的 TLS 证书,可以看作是 mTLS 中的客户端认证。
在官方的核心 API 设计中,使用监听器的 tls.frontendValidation
指定的 ConfigMap
中的 CA 证书来对客户端进行认证。核心 API 只支持一个 ConfigMap
,在实现是可扩展支持多个 ConfigMap
或者其他类型如 Service
。
apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
metadata:
name: client-validation-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
frontendValidation:
caCertificateRefs:
- kind: ConfigMap
group: ""
name: foo-example-com-ca-cert
BackendTLSPolicy
BackendTLSPolicy 是 gwapi 中的一种类型,用于指定通过 Service API 对象从网关到后端 Pod(或多个 Pod)的连接的 TLS 配置。与客户端认证正好相反,是对后端服务的认证。
对后端服务的认证有两种:
- 由网关对后端服务进行认证,即在网关配置用于认证的 CA 证书。
- 有客户端进行认证,也就是网关的透传(passthrough)模式。
相比 v1.0 里的 v1alpha2
,v1.1 中的 v1alpha3
发生的重大变化:
targetRef
字段现在变为targetRefs
列表,并且这些引用不再包含命名空间字段。tls
字段已更名为validation
caCertRefs
字段已更名为caCertificateRefs
wellKnownCACerts
字段已更名为wellKnownCACertificates
apiVersion: gateway.networking.k8s.io/v1alpha3
kind: BackendTLSPolicy
metadata:
name: tls-upstream-auth
spec:
targetRefs:
- kind: Service
name: auth
group: ""
validation:
caCertificateRefs:
- kind: ConfigMap
name: auth-cert
group: ""
hostname: auth.example.com
网关参数
不同的 gwapi 实现使用了不同的负载均衡器,比如 Envoy Gateway 使用 Envoy,FSM Gateway 使用 Pipy。不同负载均衡器自身的配置各不相同,而 gwapi 无法提供通用的接口。因此在 GatewayClass
API 上通过 spec.parametersRef
字段提供了配置接口。
不过 GatewayClass
的配置是全局的,针对所有的 Gateway
实例,无法针对特定的 Gateway
实例进行配置,难以满足需求。然后就有了 网关增强提案 GEP-1867。
与 GatewayClass
类似的方式,该提案中 Gateway
API 通过 infrastructure.parametersRef
字段配置 LocalParametersReference
,具体由各 gwapi 实现来定义。
其他更新
除了两个发布渠道的功能外,还有其他的更新就不一一介绍了。
-
gwctl:
get
命令扩展以支持 gateways、gatewayclasses 和 namespaces。describe
命令现在支持描述 policycrds 和 namespaces。- 增加了使用标签过滤资源的能力(通过
-l
选项)。 - 修复了描述 gatewayclasses 时未描述的错误。
-
验证变更:不再需要在 Gateway Listeners 上配置 TLS,以实现更灵活的 TLS 配置。
-
一致性测试:一致性配置文件已重命名,并新增了
Mesh-GRPC
配置文件。 -
依赖项更新:Gateway API 升级到 Go v1.22 和 Kubernetes v1.30。
-
清理:删除了验证 webhook,CEL 验证现在内置在 CRDs 中替代 webhook。
更多内容可以参考 v1.1.0 更新说明。