本文发表时间已超过一年。较旧的文章可能包含过时的内容。请检查页面中的信息自发布以来是否已变得不正确。
使用 Gateway API 发展 Kubernetes 网络
Ingress 资源是 Kubernetes 众多成功案例之一。它创建了一个多样化的 Ingress 控制器生态系统,这些控制器以标准化和一致的方式在数十万个集群中使用。这种标准化帮助用户采用了 Kubernetes。然而,在 Ingress 创建五年后,出现了碎片化的迹象,出现了不同的但惊人相似的 CRD 和过载的注解。使 Ingress 普及的相同可移植性也限制了它的未来。
在 2019 年圣地亚哥的 Kubecon 大会上,一群充满热情的贡献者聚集在一起讨论 Ingress 的演变。讨论蔓延到街对面的酒店大堂,最终形成了一个后来被称为 Gateway API 的东西。此讨论基于以下几个关键假设
- 路由匹配、流量管理和服务暴露的底层 API 标准是商品化的,并且作为自定义 API 对其实现者和用户几乎没有价值
- 可以通过公共核心 API 资源来表示 L4/L7 路由和流量管理
- 可以以不牺牲核心 API 用户体验的方式为更复杂的功能提供可扩展性
介绍 Gateway API
这导致了允许 Gateway API 改进 Ingress 的设计原则
- 表达性 - 除了 HTTP 主机/路径匹配和 TLS 之外,Gateway API 还可以表达诸如 HTTP 标头操作、流量加权和镜像、TCP/UDP 路由以及其他只能通过自定义注解在 Ingress 中实现的功能。
- 面向角色的设计 - API 资源模型反映了路由和 Kubernetes 服务网络中常见的职责分离。
- 可扩展性 - 这些资源允许在 API 内的各个层附加任意配置。这使得可以在最合适的地方进行细粒度的自定义。
- 灵活的一致性 - Gateway API 定义了不同的符合性级别 - 核心(强制支持)、扩展(如果支持则可移植)和自定义(不保证可移植性),它们共同被称为灵活的一致性。这促进了高度可移植的核心 API(如 Ingress),同时仍为 Gateway 控制器实现者提供了灵活性。
Gateway API 是什么样子的?
Gateway API 引入了一些新的资源类型
- GatewayClasses 是集群范围的资源,充当模板,显式定义从中派生的 Gateway 的行为。这在概念上类似于 StorageClasses,但用于网络数据平面。
- Gateways 是 GatewayClasses 的已部署实例。它们是执行路由的数据平面的逻辑表示,它们可以是集群内代理、硬件 LB 或云 LB。
- 路由 不是单个资源,而是表示许多不同的协议特定的路由资源。HTTPRoute 具有匹配、过滤和路由规则,这些规则应用于可以处理 HTTP 和 HTTPS 流量的 Gateway。同样,还有 TCPRoutes、UDPRoutes 和 TLSRoutes,它们也具有特定于协议的语义。此模型还允许 Gateway API 在未来逐步扩展其协议支持。
Gateway 控制器实现
好消息是,尽管 Gateway 处于 Alpha 阶段,但已经有几个可以运行的 Gateway 控制器实现。由于它是标准化规范,以下示例可以在其中任何一个上运行,并且应该以完全相同的方式运行。请查看 入门指南,了解如何安装和使用这些 Gateway 控制器之一。
动手使用 Gateway API
在以下示例中,我们将演示不同 API 资源之间的关系,并引导您完成一个常见的用例
- foo 团队将其应用程序部署在 foo 命名空间中。他们需要控制其应用程序不同页面的路由逻辑。
- bar 团队在 bar 命名空间中运行。他们希望能够对其应用程序进行蓝绿部署,以降低风险。
- 平台团队负责管理 Kubernetes 集群中所有应用程序的负载均衡器和网络安全。
以下 foo-route 对 foo 命名空间中的各种服务进行路径匹配,并且还具有到 404 服务器的默认路由。这分别通过 foo.example.com/login
和 foo.example.com/home
公开了 foo-auth 和 foo-home 服务。
kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
name: foo-route
namespace: foo
labels:
gateway: external-https-prod
spec:
hostnames:
- "foo.example.com"
rules:
- matches:
- path:
type: Prefix
value: /login
forwardTo:
- serviceName: foo-auth
port: 8080
- matches:
- path:
type: Prefix
value: /home
forwardTo:
- serviceName: foo-home
port: 8080
- matches:
- path:
type: Prefix
value: /
forwardTo:
- serviceName: foo-404
port: 8080
在同一 Kubernetes 集群的 bar 命名空间中运行的 bar 团队也希望将其应用程序暴露给 Internet,但他们也希望控制自己的金丝雀和蓝绿部署。以下 HTTPRoute 配置为以下行为
对于到
bar.example.com
的流量- 将 90% 的流量发送到 bar-v1
- 将 10% 的流量发送到 bar-v2
对于带有 HTTP 标头
env: canary
的到bar.example.com
的流量- 将所有流量发送到 bar-v2
kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
name: bar-route
namespace: bar
labels:
gateway: external-https-prod
spec:
hostnames:
- "bar.example.com"
rules:
- forwardTo:
- serviceName: bar-v1
port: 8080
weight: 90
- serviceName: bar-v2
port: 8080
weight: 10
- matches:
- headers:
values:
env: canary
forwardTo:
- serviceName: bar-v2
port: 8080
路由和 Gateway 绑定
因此,我们有两个 HTTPRoute 匹配和路由到不同服务的流量。您可能想知道,这些服务在哪里可以访问?它们通过哪些网络或 IP 地址暴露?
路由如何暴露给客户端由 路由绑定 管理,它描述了路由和 Gateway 如何彼此建立双向关系。当路由绑定到 Gateway 时,意味着它们的集体路由规则配置在底层负载均衡器或代理上,并且路由可以通过 Gateway 访问。因此,Gateway 是一个网络数据平面的逻辑表示,可以通过路由进行配置。
管理委托
Gateway 和 Route 资源之间的拆分允许集群管理员将一些路由配置委托给各个团队,同时仍然保留集中控制。以下 Gateway 资源在端口 443 上暴露 HTTPS,并使用集群管理员控制的证书终止端口上的所有流量。
kind: Gateway
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
name: prod-web
spec:
gatewayClassName: acme-lb
listeners:
- protocol: HTTPS
port: 443
routes:
kind: HTTPRoute
selector:
matchLabels:
gateway: external-https-prod
namespaces:
from: All
tls:
certificateRef:
name: admin-controlled-cert
以下 HTTPRoute 显示了路由如何通过其 kind
(HTTPRoute) 和资源标签 (gateway=external-https-prod
) 来确保它与 Gateway 的选择器匹配。
# Matches the required kind selector on the Gateway
kind: HTTPRoute
apiVersion: networking.x-k8s.io/v1alpha1
metadata:
name: foo-route
namespace: foo-ns
labels:
# Matches the required label selector on the Gateway
gateway: external-https-prod
...
面向角色的设计
当您将它们放在一起时,您将拥有一个可以由多个团队安全共享的单一负载均衡基础设施。Gateway API 不仅是用于高级路由的更具表达力的 API,而且还是面向角色的 API,专为多租户基础设施而设计。它的可扩展性确保它将在未来用于案例时不断发展,同时保留可移植性。最终,这些特性将使 Gateway API 能够在未来很好地适应不同的组织模型和实现。
尝试一下并参与其中
有很多资源可以查看以了解更多信息。
- 查看用户指南,了解可以解决哪些用例。
- 尝试其中一个 现有的 Gateway 控制器
- 或者 参与其中,帮助设计和影响 Kubernetes 服务网络的未来!