几天前,K8s Network SIG 发布了 Gateway API(简称 gwapi)的 v1.1 版本[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 中的工作机制,也可参考 官方文档[2]。
从 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[3]。
会话持久性是指客户端请求在“会话”持续时间内定向到同一后端服务器。
当客户端直接提供信息(例如请求头中的 cookie)时,代理将其用作将流量定向到特定服务器的参考。持久性是负载均衡的一个例外:持久性客户端请求绕过代理的负载平衡算法,直接到达之前与之建立会话的后端服务器。
见官方的 会话持久性定义[4]。
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[5] 讨论了如何验证前端客户端在 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[6] 是 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[7]。
与 GatewayClass 类似的方式,该提案中 Gateway API 通过 infrastructure.parametersRef 字段配置 `LocalParametersReference`[8],具体由各 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 更新说明[9]。
参考资料
[1] v1.1 版本: https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0
[2] 官方文档: https://gateway-api.sigs.k8s.io/mesh/
[3] 网关增强提案 GEP-1619: https://gateway-api.sigs.k8s.io/geps/gep-1619
[4] 会话持久性定义: https://gateway-api.sigs.k8s.io/geps/gep-1619/?h=backendlbpolicy#defining-session-persistence
[5] 网关增强提案 GEP-91: https://gateway-api.sigs.k8s.io/geps/gep-91/
[6] BackendTLSPolicy: https://gateway-api.sigs.k8s.io/api-types/backendtlspolicy
[7] 网关增强提案 GEP-1867: https://gateway-api.sigs.k8s.io/geps/gep-1867
[8] LocalParametersReference: https://gateway-api.sigs.k8s.io/reference/spec/#gateway.networking.k8s.io/v1.LocalParametersReference
[9] v1.1.0 更新说明: https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.1.0