Kubernetes Gateway API v1.1 解读

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 到(父资源) GatewayService 上,具体表现为 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: core
      port: 80
  rules:
    ...

一致性检查的配置文件和报告 GA

一致性报告 API 和相应的测试套件已升级为 GA v1 版本。

关于一致性报告:

符合 Gateway API 规范的实现是指通过每个 gwapi 捆绑版本(如 gateway.networking.k8s.io/bundle-version: v1.1.0)发布中包含的一致性测试的实现。 所有的 gwapi 实现必须通过一致性测试,且不能跳过任何一个测试。

v1 版本中,ConformanceReport API 扩展了 modegatewayAPIChannel 两个字段。前者用于指定实现的工作模式,后者标识该报告适用的发布渠道:标准发布 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 中的 typeCookie,在实现可以扩展支持任意请求头,类型为 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 使用 EnvoyFSM Gateway 使用 Pipy。不同负载均衡器自身的配置各不相同,而 gwapi 无法提供通用的接口。因此在 GatewayClass API 上通过 spec.parametersRef 字段提供了配置接口。

不过 GatewayClass 的配置是全局的,针对所有的 Gateway 实例,无法针对特定的 Gateway 实例进行配置,难以满足需求。然后就有了 网关增强提案 GEP-1867

GatewayClass 类似的方式,该提案中 Gateway API 通过 infrastructure.parametersRef 字段配置 LocalParametersReference,具体由各 gwapi 实现来定义。

其他更新

除了两个发布渠道的功能外,还有其他的更新就不一一介绍了。

  1. gwctl

    • get 命令扩展以支持 gateways、gatewayclasses 和 namespaces。
    • describe 命令现在支持描述 policycrds 和 namespaces。
    • 增加了使用标签过滤资源的能力(通过 -l 选项)。
    • 修复了描述 gatewayclasses 时未描述的错误。
  2. 验证变更:不再需要在 Gateway Listeners 上配置 TLS,以实现更灵活的 TLS 配置。

  3. 一致性测试:一致性配置文件已重命名,并新增了 Mesh-GRPC 配置文件。

  4. 依赖项更新:Gateway API 升级到 Go v1.22 和 Kubernetes v1.30。

  5. 清理:删除了验证 webhook,CEL 验证现在内置在 CRDs 中替代 webhook。

更多内容可以参考 v1.1.0 更新说明

(转载本站文章请注明作者和出处乱世浮生,请勿用于任何商业用途)

comments powered by Disqus