跳至内容

跨命名空间路由

网关 API 核心支持跨命名空间路由。当多个用户或团队共享底层网络基础设施时,这很有用,但必须对控制和配置进行细分以最大限度地减少访问和故障域。

网关和路由可以部署到不同的命名空间,并且路由可以跨命名空间边界附加到网关。这允许用户访问控制在命名空间之间针对路由和网关应用不同的方式,有效地将对集群范围路由配置的不同部分的访问和控制进行隔离。路由跨命名空间边界附加到网关的能力受 路由附件 控制。路由附件在本指南中进行了探讨,并演示了独立团队如何安全地共享同一个网关。

在本指南中,有两个独立的团队,storesite,在 store-nssite-ns 命名空间中在同一个 Kubernetes 集群中运行。这些是他们的目标以及他们如何使用网关 API 资源来实现它们

  • 站点团队有两个应用程序,homelogin。该团队希望尽可能地隔离其应用程序之间的访问和配置,以最大限度地减少访问和故障域。他们使用附加到同一个网关的单独 HTTPRoute 来隔离路由配置,例如金丝雀发布,但仍然共享相同的 IP 地址、端口、DNS 域名和 TLS 证书。
  • store 团队在 store-ns 命名空间中部署了一个名为 store 的服务,该服务也需要在相同的 IP 地址和域名后面公开。
  • Foobar 公司在所有应用程序中都使用 foo.example.com 域名运行。这是由在 infra-ns 命名空间中运行的中央基础设施团队控制的。
  • 最后,安全团队控制着 foo.example.com 的证书。通过通过单个共享网关管理此证书,他们能够集中控制安全性,而无需直接涉及应用程序团队。

网关 API 资源之间的逻辑关系如下所示

Cross-Namespace routing

跨命名空间路由附件

路由附件 是一项重要概念,它决定了路由如何附加到网关以及如何为其编程路由规则。当有多个跨命名空间的路由共享一个或多个网关时,这一点尤其重要。网关和路由附件是双向的 - 只有在网关所有者和路由所有者都同意关系的情况下,附件才能成功。这种双向关系存在两个原因

  • 路由所有者不希望通过他们不知道的路径过度暴露他们的应用程序。
  • 网关所有者不希望某些应用程序或团队在未经许可的情况下使用网关。例如,内部服务不应通过互联网网关访问。

网关支持附件约束,这是网关侦听器上的字段,可以限制哪些路由可以附加。网关支持命名空间和路由类型作为附件约束。任何不满足附件约束的路由都无法附加到该网关。类似地,路由通过路由的 parentRef 字段显式引用它们想要附加到的网关。这些共同创建了基础设施所有者和应用程序所有者之间的握手,使他们能够独立地定义应用程序如何通过网关公开。这实际上是一个减少管理开销的策略。应用程序所有者可以指定他们的应用程序应该使用哪些网关,而基础设施所有者可以限制网关接受的命名空间和路由类型。

共享网关

基础设施团队将 shared-gateway 网关部署到 infra-ns 命名空间

apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: shared-gateway
  namespace: infra-ns
spec:
  gatewayClassName: shared-gateway-class
  listeners:
  - name: https
    hostname: "foo.example.com"
    protocol: HTTPS
    port: 443
    allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            shared-gateway-access: "true"
    tls:
      certificateRefs:
      - name: foo-example-com

上面网关中的 https 侦听器匹配 foo.example.com 域名的流量。这允许基础设施团队管理域名的所有方面。下面的 HTTPRoute 不需要指定域名,并且如果未设置 hostname,默认情况下将匹配所有流量。这使得管理 HTTPRoute 变得更容易,因为它们可以是与域名无关的,这在应用程序域名不是静态时非常有用。

此网关还使用 infra-ns 命名空间中的 foo-example-com 密钥配置 HTTPS。这允许基础设施团队代表应用程序所有者集中管理 TLS。foo-example-com 证书将终止所有发送到其附加路由的流量,而无需在 HTTPRoute 本身进行任何 TLS 配置。

此网关使用命名空间选择器来定义允许附加哪些 HTTPRoute。这允许基础设施团队通过允许列出一些命名空间来限制谁或哪些应用程序可以使用此网关。

apiVersion: gateway.networking.k8s.io/v1beta1
kind: Gateway
spec:
  listeners:
  - allowedRoutes:
      namespaces:
        from: Selector
        selector:
          matchLabels:
            shared-gateway-access: "true"
...

只有 标有 shared-gateway-access: "true" 的命名空间才能将它们的路由附加到 shared-gateway。在以下命名空间集中,如果在 no-external-access 命名空间中存在一个 HTTPRoute,并且其 parentRefinfra-ns/shared-gateway,它将被网关忽略,因为附件约束(命名空间标签)未满足。

apiVersion: v1
kind: Namespace
metadata:
  name: infra-ns
  labels:
    shared-gateway-access: "true"
---
apiVersion: v1
kind: Namespace
metadata:
  name: site-ns
  labels:
    shared-gateway-access: "true"
---
apiVersion: v1
kind: Namespace
metadata:
  name: store-ns
  labels:
    shared-gateway-access: "true"
---
apiVersion: v1
kind: Namespace
metadata:
  name: no-external-access

请注意,网关上的附件约束不是必需的,但如果在具有许多不同团队和命名空间的集群中运行,它们是一种最佳实践。在集群中所有应用程序都有权附加到网关的环境中,listeners[].routes 字段不必配置,所有路由都可以自由地使用网关。

路由附件

store 团队在 store-ns 命名空间中部署了 store 服务的路由

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: store
  namespace: store-ns
spec:
  parentRefs:
  - name: shared-gateway
    namespace: infra-ns
  rules:
  - matches:
    - path:
        value: /store
    backendRefs:
    - name: store
      port: 8080

此路由具有简单的路由逻辑,因为它只匹配 /store 流量,并将其发送到 store 服务。

站点团队现在为他们的应用程序部署路由。他们将两个 HTTPRoute 部署到 site-ns 命名空间

  • home HTTPRoute 充当默认路由规则,匹配所有发送到 foo.example.com/* 的流量(未被现有路由规则匹配),并将流量发送到 home 服务。
  • login HTTPRoute 将 foo.example.com/login 的流量路由到 service/login-v1service/login-v2。它使用权重来细粒度地控制流量在它们之间的分配。

这两个路由都使用相同的网关附件配置,该配置指定 infra-ns 命名空间中的 gateway/shared-gateway 作为这些路由要附加到的唯一网关。

apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: home
  namespace: site-ns
spec:
  parentRefs:
  - name: shared-gateway
    namespace: infra-ns
  rules:
  - backendRefs:
    - name: home
      port: 8080
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: login
  namespace: site-ns
spec:
  parentRefs:
  - name: shared-gateway
    namespace: infra-ns
  rules:
  - matches:
    - path:
        value: /login
    backendRefs:
    - name: login-v1
      port: 8080
      weight: 90
    - name: login-v2
      port: 8080
      weight: 10

部署这三个路由后,它们都将附加到 shared-gateway 网关。网关将这些路由合并到单个扁平路由规则列表中。这些路由规则之间的路由优先级 由最具体的匹配决定,冲突将根据 冲突解决 处理。这提供了独立用户之间路由规则的可预测且确定性的合并。

借助跨命名空间路由,Foobar 公司可以更均匀地分配基础设施所有权,同时保留集中控制。 这使他们能够兼得两全其美,所有这些都通过声明式和开源 API 提供。