Kubernetes Ingress Controller 概览

本文比较了目前市面上比较流行的 Kubernetes Ingress Controller,并列出了选择一个适合的方案需要考量的因素。

Image for post

尽管 Kubernetes 早在 2014 年 6 月就发布了第一个版本,但读者可能会惊讶地发现都迭代到 Kubernetes v1.18 版本了,Kubernetes Ingress API仍处于beta版本。自 2016 年初(Kubernetes v1.2)进入 beta 迭代以来,Ingress API 一直都非常注重可移植性,并且始终保持轻量。在去年的 KubeCon North America 2019 上,IBM 的 Christopher Luciano 和 Google 的 Bowei Du 在“Evolving the Kubernetes Ingress APIs to GA and Beyond”上作了详细介绍,Ingress API 进行了多项改进(例如,更好的路径匹配,新的 IngressClass 资源定义,主机名通配符)。随着 Ingress API 在 v1.19 中逐步升级到 GA,笔者对市面上较常见的 Ingress Controller 进行了全面的比较,并给出了在选择解决方案时的要注意的关键事项。

免责声明本文是是基于个人经验,公开信息和博客文章的总结。并没有完整列出市面上所有Ingress Controller。另外,由于技术发展迅速,本文的信息可能会过时。如果您发现任何不正确的地方,请在文后发表评论,笔者会尽快进行更新。

Ingress vs. Ingress Controller

在深入各种 Ingress Controller 之前,我们先快速回顾一下 Kubernetes Ingress 的概念以及 Ingress Controller 的作用。为了暴露业务应用给外部访问,Kubernetes 提供了三种服务类型:

  1. ClusterIP:为方便应用在集群内通信创建的 IP
  2. NodePort:为应用在每个工作节点上映射一个固定端口,以将集群外的调用路由到集群内的应用上
  3. LoadBalancer:创建外部负载均衡器以将外部请求路由到集群内服务

Ingress 有别于 Kubernetes Service,它主要用于将服务公开给外部请求。与 LoadBalancer 或 NodePort 相比,Ingress 的优势在于可以将路由规则合并到单个资源中,从而暴露多个业务应用。严格来说,Ingress 是定义流量路由规则(例如,负载均衡,SSL 卸载,基于路径的路由,网络协议)的 API 对象,而 Ingress Controller 是负责处理这些规则变化的组件。

Image for post

Ingress Controller

Kubernetes 项目官方目前维护了GLBC(GCE L7 Balancer)和 ingress-nginx 控制器。除非你在像 GKE 这样的环境中安装集群(默认情况下集成安装 GLBC),一般来说需要单独安装 Ingress Controller。本文会比较市面上常见的选项,先着重介绍特定云服务商的 Ingress Controller,然后探讨其他开源的方案。

云服务商提供的 Ingress Controller

目前三个主流的云服务商都积极支持和维护与自家的负载均衡器产品兼容的 Ingress Controller:

使用特定云服务商的 Ingress Controller 的优势,主要体现在可以比较容易地与服务商的其他云服务产品集成。例如,GCE Ingress Controller 支持Cloud IAP for Google Kubernetes Engine,一键启用身份识别代理,从而保护 Kubernetes 内部应用程序(如 Vault,Prometheus,Grafana,请参阅此处的监控设置教程)。ALB Ingress Controller 在默认情况下会创建一个 Application Load Balancer(与用于其他开源 Ingress Controller 的 Network Load Balancer 类似),并且可与 Route 53,Cognito 和 AWS WAF 可以很好地集成。同样,如果用户使用了 Azure Pipelines 在 Azure 上管理 DevOps 流程,则 AKS Application Gateway Ingress Controller 非常适用于 Azure CI/CD 工作流。

另一方面,如果用户采用混合或多云部署环境,则使用下文列出的开源的 Ingress Controller 解决方案,会比在不同云环境中维护多个不同的 Ingress Controller 要容易。除 AKS AGIC 外,其他两家都不支持跨命名空间 Ingress,这就意味着必须为每个命名空间创建一个新的 GCE Ingress 或 ALB Ingress。如果集群中有多个不同的租户且包含了多个命名空间,那 Ingress 资源(即外部 L7 负载平衡器)加上静态 IP 就是一笔不菲的开销。最后一点,由于这些 ingress 在创建时会涉及到全局(或多区域)的负载均衡器(尤其是在 GKE 中)变更,往往附带了更严格的健康状态检查逻辑,因此创建和更新这些 ingress 资源耗时更长。

总体而言,Azure 上的 AGIC,AWS 上的 ALB 和 GKE 上的 GLBC/GCE 提供了出色的性能,原生的 L7 路由以及与自家其他云产品的良好集成。GLBC 在 GKE 上是开箱即用的,因此,如果用户只是在寻找 HTTP/S 路由解决方案,这是个不错的第一选择。

开源的Ingress Controller

除了特定于云服务商的入口控制器外,Kubernetes 网站还维护了一个常用的第三方解决方案列表:

  • Ambassador: 基于 Envoy 的 API 网关,开源版有社区维护,商业版则由Datawire提供支持
  • Voyager: 来自 AppsCode的基于 HAProxy 的 Ingress Controller
  • Contour: 来自 VMWare旗下 Heptio 公司,基于 Envoy 的 Ingress Controller
  • Gloo: 基于 Envoy 的 API 网关, solo.io提供企业支持
  • Citrix: 服务于 MPX, VPX, and CPX ADC 产品的 Ingress Controller
  • F5: 提供 F5’s BIG-IP Container Ingress 服务的 Ingress Controller
  • HAProxy: 社区驱动的 HAProxy Ingress Controller ,同时由 HAProxy Tech提供企业支持
  • Istio: 适用于启用了 Istio 的 Ingress 网关
  • Kong: 基于 nginx 的 API 网关, 由 KongHQ](https://konghq.com/solutions/kubernetes-ingress/)提供社区和企业支持
  • NGINX: 官方的 NGINX 和 NGINX Plus Ingress Controller
  • Skipper: 来自 Zalando 的 路由和反向代理控制器
  • Traefik: Containous提供商业支持的 http 方向代理控制器

根据 CNCF Survey 2019 的调查,在市场份额方面,nginx 和 HAProxy 在 2019 年继续保持领先地位,Envoy 超过 F5 排名第三。目前尚不清楚该调查是否按将 Ingress 底层的实现技术分组(例如,Ambassador,Contour 和 Gloo 都归属于 Envoy 实现),但随着 Istio 的普及率进一步提升,Envoy 可能会成为 Ingress Controller 事实上的首选。

Image for post

在下文中,笔者把列表中 Ingress Controller 根据底层实现技术(nginx,HAProxy,Envoy 等)分组介绍,并根据个人经验或其他博客文章的点评,提出一些想法。

基于NGINX实现的Ingress Controller

ingress-nginx

这是唯一一个由 Kubernetes 团队维护的开源 Ingress Controller,底层是 NGINX。得益于官方背书,它同时具备 HTTP/S 路由和 SSL 卸载的功能,是目前最受欢迎的方案之一。由于其在业内被广泛采用,ingress-nginx 的配置和相关工具(例如 cert-manager 和 external-dns)可参考文档非常多。

如果用户不需要复杂的功能,希望使用一款简单的反向代理,那么 ingress-nginx 是一个安全靠谱的选项。另外,如果用户需要更高性能的表现或是额外的附加功能(例如 JWT 验证,OpenTracing),也可以考虑改用 NGINX 官方维护的 Ingress Controller。最后,使用 ngress-nginx 的默认配置,在集群规模变大之后可能会带来性能问题,因此用户应该花些心思研究 NGINX 如何正确设置(请参阅 Eric Liu 的文章,深入了解ingress-nginx。)

NGINX & NGINX Plus Ingress Controller

这是NGINX公司(现属 F5)的官方 Ingress Controller,支持开源和商业(NGINX Plus)两种版本。在Github链接上详细记录了 Nginxinc/kubernetes-ingress 和 kubernetes/ingress-nginx 之间的差异。

如您所料,免费版本缺少一些关键特性(例如端点的动态配置),因为它没包含 Lua 插件。付费版本 NGINX Plus 则提供基于了 cookies 会话持久性,主动健康检查,JWT 身份验证(OpenID SSO),实时监视和高可用。如果用户原先就有丰富的 NGINX 使用经验,可以很轻松地过渡到 Kubernetes 的场景。

Kong

Kong 以作为 API 网关而被大多数开发者所熟知,被用于处理和路由 API 请求。近年来,Kong 也在逐渐丰富其功能,例如原生的 gRPC 支持,请求/响应转换,身份验证。同时也是一款 Ingress 解决方案,提供了对负载均衡器的主动健康检查。与 ingress-nginx 不同,Kong 坚持不实现跨命名空间的 Ingress Controller,并指出特权提升(privilege escalation)在某些场景下会成为被攻击的目标。笔者早在一年前为 GCE 上的集群寻找 ingress 替代方案时,就拜读过 Bouwe Ceunen 的“为什么要从Traefik切换到Kong”这篇文章,但到目前还没有亲自实践过 Kong。

基于HAProxy实现的Ingress Controller

HAProxy Ingress

HAProxy 和 NGINX 类似,是一款早于 Kubernetes 问世的,久经考验的 TCP/HTTP 反向代理解决方案。因此,如果配置各种负载均衡策略是首要考量因素,那 HAProxy Ingress 作为一个行之有效的高性能解决方案,是个不错的选择。作为集群的 Ingress Controller,HAProxy Ingress 通过 API 提供动态配置更新,以避免 HAProxy 对静态配置文件的依赖。

Voyager

Voyager 是另一款带有企业支持的基于 HAProxy 的 Ingress Controller,其官方网站上着重强调了 HTTP/TCP 的 L4 和 L7 负载均衡的特性,以及可以与 LetsEncrypt 和 AWS Certificate Manager 的 SSL 方案无缝集成。

基于Envoy实现的Ingress Controller

Istio Ingress

Istio 大量使用 Envoy 代理来中转服务网格内的所有流量。如果用户已经在集群中使用 Istio 作为服务网格解决方案,则使用默认的 Istio Ingress/Gateway 最有意义。它提供了流量路由,可观察性,安全性和部署模型,可与现有 Istio 结构和服务实现了最佳集成。但是,Istio 并不是轻量级的方案,学习曲线很大,因此,如果用户只是想使用 Envoy 代理的特性,以下方案可以优先考虑。

Ambassador

从技术上讲,Ambassador 是 Kubernetes Ingress 支持的 API 网关和 L7 负载均衡器。不过它特性更完备:支持各种协议(gRPC,HTTP/2,TCP,WebSockets),安全性(自动 HTTPS,速率限制,自定义过滤器),高可用性(粘性会话,断路器)甚至是与 Knative Serverless 无缝集成。它基于 Envoy,但可以与 Istio 以外的其他服务网格解决方案(例如 Consul,Linkerd)很好兼容。benchmark results的博客上发布了 Ambassador 的基准测试结果,与 NGINX 和 HAProxy 相比的,其性能还是不错的,尽管已经有好几个月没有更新了。

Contour

Contour 是最早使用自定义资源定义(CRD)来扩展 Kubernetes Ingress API 功能的 Ingress 控制器之一。 CRD(HTTPProxy——由 IngressRoute 重命名而来)主要解决了原生 Kubernetes Ingress API 在多租户环境中的局限性。如今,IngressRoute 已在 Kubernetes v1.18 +中被正式定义,Contour 的原先方案可能会与 Kubernetes 的总体演进方向很好地融合在一起。

Gloo

Gloo 通过提供所谓的“功能级路由”而与其他基于 Envoy 的 Ingress Controller 有所不同。这意味着 Gloo 充当 Ingress 和 API 网关时,不仅可以将流量路由到微服务,还可以路由到 Serverless 服务(例如 AWS Lambda,Google Cloud Functions,OpenFaaS,Knative)。它还对传统/混合架构的应用程序提供了出色的支持,在这些应用程序中,流量必须调用内部 API(REST,SOAP,XML)或与消息队列进行交互(例如 NATS,AMQP)。

其他

Skipper

Skipper 是 HTTP 路由器和反向代理,其起源于 2015 年的Project Mosaic。其最初的设计目标是作为依赖于静态配置文件的 NGINX 和 HAProxy 的替代方案,并实现新特性支持,例如金丝雀或蓝绿色部署以及流量镜像等。作为“旧”项目,上面提到的其他 Ingress Controller 已经支持许多 Skipper 之前提出的功能。但是,由于 Skipper 专注于 HTTP 路由,因此精简了其他负载均衡器实现的许多功能(例如 SSL 终止,自动证书轮换,WAF 集成),并可与 AWS ALB 很好地集成。对于那些希望迁移到 Kubernetes 的 AWS 用户而言,Skipper 是一个值得考虑的选项。

Traefik

最后来谈谈 Traefik,这是一个用 Go 编写的特性完备的 HTTP 反向代理和负载均衡器。 Traefik 最初是为解决微服务的流量路由问题而编写的,以支持全自动和实时动态更新配置路由。因此,它支持包括 Kubernetes 在内一系列基础设施平台(Docker,Docker Swarm,Marathon,Consul 等,Rancher,Amazon ECS)。Traefik 支持 HTTP/2,gRPC 和 WebSocket,以及多种负载均衡算法和断路器。

最初吸引我使用 Traefik 的原因是,它对 Let’s Encrypt 开箱即用的集成,有界面精美的 Web UI,将 Traefik 的运行状况和性能可视化,而这无需将指标收集到 Prometheus 或 Datadog(尽管也支持这些集成)。 Traefik v2 版本(于 2019 年 11 月发布)新增了对 TCP 的支持,以及 SNI 路由,金丝雀部署,流量镜像和 IngressRoute CRD 等新特性。

(有关快速入门指南,请查阅Traefik v2 on Kubernetes。)

如何选择

市场的可供选择的方案很多,用户如何选择一款合适的 Ingress Controller?一般来说,用户如果需要简单易上手的解决方案,那ingress-nginx会是个靠谱同时也是最主流的选择之一。如果考虑将 Istio 用作服务网格,则Istio Ingress会是不二之选;其他情况,则可以尝试基于 Envoy 的解决方案,能和 Consul 或 Linkerd 比较好协同。就个人而言,我将Traefik和云服务商的 ingress 解决方案结合使用,这种方案可以降低延迟,方便全球/多区域部署。笔者还没有尝试过 Gloo,但是随着容器和 Serverless 更进一步集成,它的路由功能似乎颇有吸引力。

其他考量因素:

  • 协议支持:用户是否需要 TCP/UDP 或是 gRPC 集成。
  • 企业支持:用户是否需要企业支持以保证核心系统的稳定运行。
  • 高级功能:用户是否需要定制化的需求,如轻量级的解决方案,或是金丝雀部署或断路器。
  • API 网关:用户是否需要某些 API 网关功能(例如速率限制)还是一款单纯的 Kubernetes Ingress 解决方案。

如果您需要更详细的对比详情,可以查看Kubedex上的比较表或 Flant 工程师的博客

Ingress on kubedex.com

Comparing Ingress controllers for Kubernetes