作者: Mark Church(谷歌)、Harry Bagdi(Kong)、Daneyon Hanson(Red Hat)、Nick Young(VMware)、Manuel Zapf(Traefik Labs)
Ingress 资源是 Kubernetes 众多成功故事之一。它创建了一个不同的 Ingress 控制器生态系统,这些控制器以标准化和一致的方式在成千上万的集群中使用。这种标准化帮助用户采用 Kubernetes。然而,在 Ingress 创建 5 年后,有迹象表明,分裂为不同但惊人相似的 CRD 和超载的注释。使 Ingress 普及的可移植性同样也限制了它的未来。
在 2019 年圣地亚哥 Kubecon 大会上,一群热情的贡献者聚集在一起讨论 Ingress 的演变。讨论蔓延到了街对面的酒店大厅,结果就是后来被称为 Gateway API 的东西。这一讨论是基于以下几个关键假设:
这就引出了允许 Gateway API 在 Ingress 基础上改进的设计原则:
Gateway API 引入了一些新的资源类型:
好消息是,尽管 Gateway 是在Alpha[2]阶段,但已经有几个你可以运行的Gateway 控制器实现[3]。由于它是一个标准化的规范,下面的示例可以在它们中的任何一个上运行,并且应该以完全相同的方式工作。查看入门手册[4],了解如何安装和使用这些网关控制器之一。
在下面的例子中,我们将演示不同 API 资源之间的关系,并带你浏览一个常见的用例:
下面的 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
bar 团队在同一个 Kubernetes 集群的 bar 命名空间中操作,也希望将他们的应用程序暴露给互联网,但他们也希望控制自己的灰度和蓝绿发布。下面的 HTTPRoute 被配置为以下行为:
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
因此,我们有两个匹配的 HTTPRoutes,并将流量路由到不同的服务。你可能想知道,在哪里可以访问这些服务?它们通过哪些网络或 IP 暴露?
路由如何向客户端暴露由路由绑定[5]来管理,该绑定描述了路由和网关之间如何创建双向关系。当 Routes 被绑定到一个 Gateway 时,这意味着它们的集合路由规则被配置在底层的负载均衡器或代理上,并且路由可以通过网关访问。因此,网关是可以通过路由配置的网络数据平面的逻辑表示。
Gateway 和 Route 资源之间的分离允许集群管理员将一些路由配置委派给各个团队,同时仍然保持集中控制。以下网关资源在端口 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 展示了 Route 如何通过它的 kind(HTTPRoute)和资源标签(gateway=external-https-prod)来确保它匹配网关的选择器。
# 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 适应不同的组织模型和实现,直到未来。
有许多资源可以查看以了解更多。
[1]
灵活的一致性: https://gateway-api.sigs.k8s.io/concepts/guidelines/#conformance
[2]
Alpha: https://github.com/kubernetes-sigs/gateway-api/releases
[3]
Gateway 控制器实现: https://gateway-api.sigs.k8s.io/references/implementations/
[4]
入门手册: https://gateway-api.sigs.k8s.io/guides/getting-started/
[5]
路由绑定: https://gateway-api.sigs.k8s.io/concepts/api-overview/#route-binding
[6]
参与: https://gateway-api.sigs.k8s.io/contributing/community/