跳到内容

从 Ingress 迁移

Gateway API 项目是 Ingress API 的继任者。但是,它不包含 Ingress 资源(最接近的平行是 HTTPRoute)。因此,需要对现有 Ingress 资源进行一次性转换,将其转换为相关的 Gateway API 资源。

本指南将帮助您进行转换。它将

  • 解释您可能想要切换到 Gateway API 的原因。
  • 描述 Ingress API 和 Gateway API 之间的关键差异。
  • 将 Ingress 功能映射到 Gateway API 功能。
  • 展示一个将 Ingress 资源转换为 Gateway API 资源的示例。
  • 提及 ingress2gateway 以进行自动转换。

同时,它不会为您准备实时迁移或解释如何转换 Ingress 控制器的一些特定于实现的功能。此外,由于 Ingress API 仅涵盖 HTTP/HTTPS 流量,因此本指南不涵盖 Gateway API 对其他协议的支持。

切换到 Gateway API 的原因

Ingress API 是 Kubernetes 配置外部 HTTP/HTTPS 负载均衡服务的标准方法。它被 Kubernetes 用户广泛采用,并得到供应商的良好支持,提供了许多实现(Ingress 控制器)。此外,一些云原生项目与 Ingress API 集成,例如 cert-managerExternalDNS

但是,Ingress API 存在一些限制

  • 功能有限。Ingress API 仅支持 TLS 终止和基于内容的 HTTP 流量请求路由,该路由基于请求的主机头和 URI。
  • 依赖注释进行扩展。注释方法进行扩展导致可移植性有限,因为每个实现都有自己支持的扩展,这些扩展可能无法转换为任何其他实现。这限制了 Ingress API 的可移植性。
  • 权限模型不足。Ingress API 不适合在具有共享负载均衡基础设施的多团队集群中使用。

Gateway API 解决这些限制,如下一节所示。

阅读有关 Gateway API 的设计目标 的更多信息。

Ingress API 和 Gateway API 之间的关键差异

Ingress API 和 Gateway API 之间存在三个主要差异

  • 角色
  • 可用功能
  • 可扩展性方法(特定于实现的功能)

角色

最初,Ingress API 只有一个资源类型 Ingress。因此,它只有一个角色——用户——Ingress 资源的所有者。Ingress 功能让用户可以对应用程序如何向其外部客户端公开进行很多控制,包括 TLS 终止配置和负载均衡基础设施的配置(某些 Ingress 控制器支持)。这种控制级别称为自助服务模型。

同时,Ingress API 还包括两个隐式角色,用于描述负责配置和管理 Ingress 控制器的人员:基础设施提供商(用于提供商管理的 Ingress 控制器)和集群运营商(或管理员)(用于自托管的 Ingress 控制器)。随着 IngressClass 资源的后期添加,基础设施提供商和集群运营商成为该资源的所有者,因此也是 Ingress API 的明确角色。

Gateway API 包括 四个明确角色:应用程序开发人员、应用程序管理员、集群运营商和基础设施提供商。这使您可以摆脱自助服务模型,将用户角色的责任分散到这些角色(除了基础设施提供商)

  • 集群运营商/应用程序管理员为外部客户端流量定义入口点,包括 TLS 终止配置。
  • 应用程序开发人员为其应用程序定义路由规则,这些规则附加到这些入口点。

这种拆分符合常见的组织结构,其中多个团队共享相同的负载均衡基础设施。同时,也不必放弃自助服务模型——仍然可以配置一个单一的 RBAC 角色,以履行应用程序开发人员、应用程序管理员和集群运营商的职责。

下表总结了 Ingress API 和 Gateway API 角色之间的映射

Ingress API 角色 Gateway API 角色
用户 应用程序开发人员、应用程序管理员、集群运营商
集群运营商 集群运营商
基础设施提供商 基础设施提供商

可用功能

Ingress API 仅提供基本功能:TLS 终止和基于内容的 HTTP 流量路由,该路由基于请求的主机头和 URI。为了提供更多功能,Ingress 控制器通过 注释 支持 Ingress 资源,这些注释是 Ingress API 的特定于实现的扩展。

注释方法进行扩展对 Ingress API 用户有两个负面影响

  • 可移植性有限。由于如此多的功能通过注释提供,因此在 Ingress 控制器之间进行切换变得困难甚至不可能,因为需要将一种实现的注释转换为另一种实现(另一种实现甚至可能不支持第一种实现的一些功能)。这限制了 Ingress API 的可移植性。
  • API 笨拙。由于注释是键值字符串(而不是 Ingress 资源的规范等结构化方案)并在资源的顶部应用(而不是在规范的相关部分中应用),因此 Ingress API 使用起来可能很笨拙,尤其是在将大量注释添加到 Ingress 资源时。

Gateway API 支持 Ingress 资源的所有功能,以及许多仅通过注释才能获得的功能。因此,Gateway API 比 Ingress API 更具可移植性。此外,如下一节所示,您无需使用任何注释,这解决了笨拙问题。

可扩展性方法

Ingress API 有两个扩展点

  • Ingress 资源上的注解(在上一节中描述)
  • 资源后端,即指定除 Service 之外的后端的能力

与 Ingress API 相比,Gateway API 功能更丰富。但是,要配置一些高级功能(如身份验证)或在数据平面之间不可移植的通用功能(如连接超时和健康检查),您需要依赖 Gateway API 的扩展。

Gateway API 具有以下主要扩展点

  • 外部引用。 Gateway API 资源的某个功能(字段)可以引用特定于 Gateway 实现的自定义资源,以配置该功能。例如
  • 自定义实现。 对于某些功能,由实现来定义如何支持它们。这些功能对应于特定于实现的(自定义)一致性级别。例如
  • 策略。 Gateway 实现可以定义称为策略的自定义资源,以公开数据平面功能,如身份验证。Gateway API 不会规定这些资源的详细信息。但是,它规定了标准 UX。有关更多详细信息,请参阅 策略附加指南。与上面的外部引用相反,Gateway API 资源不会引用策略。相反,策略必须引用 Gateway API 资源。

扩展点不包括 Gateway API 资源上的注解。强烈建议 API 实现不要使用这种方法。

将 Ingress API 功能映射到 Gateway API 功能

本节将把 Ingress API 功能映射到相应的 Gateway API 功能,涵盖三个主要领域

  • 入口点
  • TLS 终止
  • 路由规则

入口点

粗略地说,入口点是数据平面可供外部客户端访问的 IP 地址和端口的组合。

每个 Ingress 资源都有两个隐式入口点——一个用于 HTTP 流量,另一个用于 HTTPS 流量。Ingress 控制器提供这些入口点。通常,它们要么由所有 Ingress 资源共享,要么每个 Ingress 资源都会获得专用的入口点。

在 Gateway API 中,入口点必须在 Gateway 资源中明确定义。例如,如果您希望数据平面处理端口 80 上的 HTTP 流量,您需要定义一个用于该流量的 监听器。通常,Gateway 实现会为每个 Gateway 资源提供一个专用数据平面。

Gateway 资源由集群操作员和应用程序管理员拥有。

TLS 终止

Ingress 资源通过 TLS 部分 支持 TLS 终止,其中 TLS 证书和密钥存储在 Secret 中。

在 Gateway API 中,TLS 终止是 Gateway 监听器 的属性,与 Ingress 相似,TLS 证书和密钥也存储在 Secret 中。

由于监听器是 Gateway 资源的一部分,因此集群操作员和应用程序管理员拥有 TLS 终止。

路由规则

Ingress 资源的 基于路径的路由规则 直接映射到 HTTPRoute路由规则

基于主机头的路由规则 映射到 HTTPRoute 的 主机名。但是,请注意,在 Ingress 中,每个主机名都有单独的路由规则,而在 HTTPRoute 中,路由规则适用于所有主机名。

Ingress API 使用术语主机,而 Gateway API 使用主机名。本指南将使用 Gateway API 术语来指代 Ingress 主机。

HTTPRoute 的 主机名 必须与 Gateway 监听器主机名 相匹配。否则,监听器将忽略与不匹配主机名对应的路由规则。请参阅 HTTPRoute 文档

HTTPRoute 由应用程序开发人员拥有。

接下来的三节将映射 Ingress 路由规则的附加功能。

规则合并和冲突解决

通常,Ingress 控制器会合并来自所有 Ingress 资源的路由规则(除非它们为每个 Ingress 资源配置一个数据平面)并解决规则之间可能发生的冲突。但是,Ingress API 并没有规定合并和冲突解决,因此 Ingress 控制器可能会以不同的方式实现它们。

相反,Gateway API 指定了如何合并规则和解决冲突

  • Gateway 实现必须合并附加到监听器的所有 HTTPRoute 的路由规则。
  • 冲突必须按照 此处 规定的方式进行处理。例如,路由规则中更具体的匹配将胜过不太具体的匹配。

默认后端

Ingress 默认后端 配置一个后端,该后端将响应与该 Ingress 资源相关的所有未匹配 HTTP 请求。Gateway API 没有直接等效项:您需要明确定义这样的路由规则。例如,定义一个规则,将路径前缀为 / 的请求路由到与默认后端相对应的 Service。

选择要附加到的数据平面

Ingress 资源必须指定一个 来选择要使用的 Ingress 控制器。HTTPRoute 必须通过 parentRef 指定要附加到的 Gateway(或 Gateways)。

特定于实现的 Ingress 功能(注解)

Ingress 注解配置特定于实现的功能。因此,将它们转换为 Gateway API 依赖于 Ingress 控制器和 Gateway 实现。

幸运的是,一些通过注解支持的功能现在已成为 Gateway API(HTTPRoute)的一部分,主要是

  • 请求重定向(包括 TLS 重定向)
  • 请求/响应操作
  • 流量拆分
  • 基于标头、查询参数或方法的路由

但是,其余功能在很大程度上仍然特定于实现。要转换它们,请查阅 Gateway 实现文档,以查看要使用哪个 扩展点

示例

本节展示了如何将 Ingress 资源转换为 Gateway API 资源的示例。

假设

示例包含以下假设

  • 所有资源都属于同一个命名空间。
  • Ingress 控制器
    • 在集群中具有相应的 IngressClass 资源 prod
    • 通过 example-ingress-controller.example.org/tls-redirect 注解支持 TLS 重定向功能。
  • Gateway 实现具有在集群中具有相应的 GatewayClass 资源 prod

此外,为了简洁起见,省略了引用 Secret 和 Service 以及 IngressClass 和 GatewayClass 的内容。

Ingress 资源

以下 Ingress 定义了以下配置

  • 使用 example-ingress-controller.example.org/tls-redirect 注解,为 foo.example.combar.example.com 主机名的任何 HTTP 请求配置 TLS 重定向。
  • 使用来自 Secret example-com 的 TLS 证书和密钥,为 foo.example.combar.example.com 主机名终止 TLS。
  • foo.example.com 主机名上 URI 前缀为 /orders 的 HTTPS 请求路由到 foo-orders-app Service。
  • foo.example.com 主机名上任何其他前缀的 HTTPS 请求路由到 foo-app Service。
  • bar.example.com 主机名上任何 URI 的 HTTPS 请求路由到 bar-app Service。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    some-ingress-controller.example.org/tls-redirect: "True"
spec:
  ingressClassName: prod
  tls:
  - hosts:
    - foo.example.com
    - bar.example.com
    secretName: example-com
  rules:
  - host: foo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: foo-app
            port:
              number: 80
      - path: /orders
        pathType: Prefix
        backend:
          service:
            name: foo-orders-app
            port:
              number: 80
  - host: bar.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: bar-app
            port:
              number: 80

接下来的三节将把该 Ingress 转换为 Gateway API 资源。

转换步骤 1 - 定义 Gateway

以下 Gateway 资源

  • 属于我们的 GatewayClass prod
  • 配置负载均衡基础设施(这取决于 Gateway 实现)。
  • 配置 HTTP 和 HTTPS 监听器(入口点),Ingress 资源隐式包含这些监听器
    • 端口 80 上的 HTTP 监听器 http
    • 端口 443 上的 HTTPS 监听器 https,具有使用 cert 和 key 存储在 example-com Secret 中的 TLS 终止,这是 Ingress 中使用的同一个 Secret

此外,请注意,两个监听器都允许来自同一命名空间的所有 HTTPRoute(这是默认设置),并将 HTTPRoute 主机名限制为 example.com 子域(允许 foo.example.com 等主机名,但不允许 foo.kubernetes.io)。

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: example-gateway
spec:
  gatewayClassName: prod
  listeners:
  - name: http
    port: 80
    protocol: HTTP
    hostname: "*.example.com"
  - name: https
    port: 443
    protocol: HTTPS
    hostname: "*.example.com"
    tls:
      mode: Terminate
      certificateRefs:
      - kind: Secret
        name: example-com
  - name: https-default-tls-mode
    port: 8443
    protocol: HTTPS
    hostname: "*.foo.com"
    tls:
      certificateRefs:
      - kind: Secret
        name: foo-com

转换步骤 2 - 定义 HTTPRoute

Ingress 被分成两个 HTTPRoute——一个用于 foo.example.com 主机名,另一个用于 bar.example.com 主机名。

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: foo
spec:
  parentRefs:
  - name: example-gateway
    sectionName: https
  hostnames:
  - foo.example.com
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: foo-app
      port: 80
  - matches:
    - path:
        type: PathPrefix
        value: /orders
    backendRefs:
    - name: foo-orders-app
      port: 80
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: bar
spec:
  parentRefs:
  - name: example-gateway
    sectionName: https
  hostnames:
  - bar.example.com
  rules:
  - matches:
    - path:
        type: PathPrefix
        value: /
    backendRefs:
    - name: bar-app
      port: 80

两个 HTTPRoute

  • 附加到步骤 1 中 Gateway 资源的 https 监听器。
  • 为相应主机名定义与 Ingress 规则相同的路由规则。

步骤 3 - 配置 TLS 重定向

以下 HTTPRoute 配置 TLS 重定向,Ingress 资源通过注解配置了 TLS 重定向。下面的 HTTPRoute

  • 附加到我们 Gateway 的 http 监听器。
  • foo.example.combar.example.com 主机名的任何 HTTP 请求发出 TLS 重定向。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: tls-redirect
spec:
  parentRefs:
  - name: example-gateway
    sectionName: http
  hostnames:
  - foo.example.com
  - bar.example.com
  rules:
  - filters:
    - type: RequestRedirect
      requestRedirect:
        scheme: https
        port: 443

Ingress 的自动转换

Ingress to Gateway 项目有助于将 Ingress 资源转换为 Gateway API 资源,尤其是 HTTPRoute。转换结果应始终经过测试和验证。