为特定的应用部署 Kubernetes 集群时,我们通常需要实现来自应用程序本身、业务和开发人员的需求。了解这些后,我们就可以进行架构选择,并为 Kubernetes 选择合适的 Ingress 控制器。
为了方便工程师高效选用合适的 Ingress 控制器,本文对业内的 Ingress 控制器做了整理和功能梳理,最后总结成一篇综述。借助这篇文章,希望读者能找到一个好的起点,然后开始自己的实践。
选择标准
为了进行客观对比并得到有用的结果,首先我们需要一套特定的标准来确定研究方向。注意,以下评测并不能涵盖所有 Kubernetes Ingress、API 网关、服务网格用例,但会尽可能覆盖常见要求。如果读者希望把评测结果用于自己的案例,建议结合自己的实践再研究一下细节和特殊性。
首先是一些非常普遍的功能,所有解决方案都已实现了它们,所以你不需要对它们过多关注:
开源;
动态服务发现;
SSL 终止;
对 WebSocket 的支持。
支持的协议
这就像是工程师选择 Ingress 控制器时的基本“参数”。常规的 HTTP(S) 代理能够满足软件要求吗?还是需要通过 gRPC、HTTP/2.0?或是需要 TCP(带有 SNI)、UDP?如果你的情况不是特别常规,建议仔细考虑这些问题,防止以后需要重新配置集群。每个控制器都有自己的一组受支持的协议。
基于(基础软件)
控制器的核心可以有几种类型的应用程序,比如最受欢迎的 NGINX、Traefik、HAProxy 和 Envoy 等。通常情况下,这些选择不会对你的流量处理方式产生巨大影响,但是了解“底层”的潜在特性和习惯总是有用的。
流量路由
将流量路由到特定服务的决策依据是什么?通常你可以用 host 和 path,但也有其他的可能性。匹配这些值是否也支持 RegEx(正则表达式)?
命名空间限制
命名空间提供了一种逻辑上分离 Kubernetes 中资源的方法。有些 Ingress 控制器必须被装在不同的命名空间中,它们的作用是仅允许流量进入属于该命名空间的 Pod。而大多数 Ingress 控制器是针对整个集群进行全局操作的,在这种情况下,流量可以到达任何 Pod,而无需考虑其命名空间。
上游探针
如何将流量定向到应用程序及其服务的正常实例?通常你有主动和被动检查、重试、断路器、自定义运行状况检查等解决方案。如果你对可用性有严格的要求,并希望迅速从负载均衡中删除失败的服务,这个功能非常重要。
负载均衡算法
对于负载均衡我们有很多选择,从传统的 round-robin 到非传统的 rdp-cookie。粘滞会话(Sticky Sessions)在这里也很常见。
认证方式
控制器支持哪些认证方式?Basic、digest、OAuth、external auth……如果你为开发人员使用了许多环境(层),或仅通过 Ingress 访问的私有层,这是个值得注意的功能。
流量分配
控制器是否支持常用的流量分配机制,如金丝雀部署、A/B 测试、镜像?对于需要精确流量管理、高效测试、最小影响进行错误调试、流量管理的应用来说,这个功能非常敏感。
付费订阅
控制器是否有带扩展功能或技术支持的付费版本?
图形用户界面(Web UI)
有用于控制器配置的图形界面吗?这个功能对于那些喜欢简单方便,或是需要对 Ingress 配置做一些更改的人很有用。如果开发人员希望“即时”测试流量,它也非常有用。
JWT 验证
是否有内置的 JSON Web 令牌验证,用于对最终应用程序的用户进行验证和确认?
定制配置
模板是否具备可扩展性,允许你将自己的指令、参数等添加到标准配置模板上?
基本的 DDOS 保护机制
基本请求速率,或基于地址、白名单、国家/地区等的流量过滤的更复杂变体。
请求跟踪
能够通过 OpenTracing 或其他选项监视、跟踪、调试从 Ingress 到特定服务、Pod(最好是在服务和 Pod 之间)的请求。
WAF
支持 Web 应用程序防火墙。
Ingress 控制器
这一节将从 Kubernetes 官方控制器开始,逐渐扩展到其他广为人知的 Ingress 控制器。
Kubernetes Ingress Controller
Kubernetes 的“官方”控制器(之所以称为官方,是想把它区别于 NGINX 公司的控制器)。这是社区开发的控制器,它基于 nginx Web 服务器,并补充了一组用于实现额外功能的 Lua 插件。
由于 NGINX 十分流行,再加上把它用作控制器时所需的修改较少,它对于 Kubernetes 普通工程师来说,可能是最简单和最直接的选择。
NGINX Ingress Controller
这是 NGINX 公司开发的官方产品,它也有一个基于 NGINX Plus 的商业版。NGINX 的控制器具有很高的稳定性、持续的向后兼容性,且没有任何第三方模块。
由于消除了 Lua 代码,和官方控制器相比,它保证了较高的速度,但也因此受到较大限制。相较之下,它的付费版本有更广泛的附加功能,如实时指标、JWT 验证、主动健康检查等。
NGINX Ingress 重要的优势是对 TCP/UDP 流量的全面支持,最主要缺点是缺乏流量分配功能。
Kong Ingress
Kong Ingress 由 Kong Inc 开发,有两个版本:商业版和免费版。它基于 NGINX 构建,并增加了扩展其功能的 Lua 模块。
最初,Kong Ingress 主要用作 API 网关,用于 API 请求的处理和路由。现在,它已经成为成熟的 Ingress 控制器,主要优点是拥有大量易于安装和配置的附加模块、插件(包括第三方插件)。它开启了控制器具备大量附加功能的先河,其内置函数也提供了许多可能性。Kong Ingress 配置是用 CRD 执行的。
Kong Ingress 的一个重要特性是它只能在一个环境中运行(而不支持跨命名空间)。这是一个颇有争议的话题:有些人认为这是一个缺点,因为必须为每个环境生成实例;而另一些人认为这是一个特殊特性,因为它是更高级别的隔离,控制器故障的影响仅限于其所在的环境。
Traefik
最初,这个代理是为微服务请求及其动态环境的路由而创建的,因此具有许多有用的功能:连续更新配置(不重新启动)、支持多种负载均衡算法、Web UI、指标导出、对各种服务的支持协议、REST API、Canary 版本等。
支持开箱即用的 Let's Encrypt 是它的另一个不错的功能,但它的主要缺点也很明显,就是为了控制器的高可用性,你必须安装并连接其 Key-value store。
在 2019 年 9 月发布的 Traefik v2.0 中,虽然它增加许多不错的新功能,如带有 SNI 的 TCP/SSL、金丝雀部署、流量镜像/shadowing 和经过改进的 Web UI,但一些功能(如 WAF 支持)还在策划讨论中。
与新版本同期推出的还有一个名叫 Maesh 的服务网格,它建在 Traefik 之上。
HAProxy Ingress
HAProxy 是众所周知的代理服务器和负载均衡器。作为 Kubernetes 集群的一部分,它提供了“软”配置更新(无流量损失)、基于 DNS 的服务发现和通过 API 进行动态配置。HAProxy 还支持完全自定义配置文件模板(通过替换 ConfigMap)以及在其中使用 Spring Boot 函数。
通常,工程师会把重点放在已消耗资源的高速、优化和效率上。而 HAProxy 的优点之一正是支持大量负载均衡算法。值得一提的是,在今年 6 月发布的 v2.0 中,HAProxy 增加了许多新功能,其即将推出的 v2.1 有望带来更多新功能(包括 OpenTracing 支持)。
Voyager
Voyager 基于 HAProxy,并作为一个通用的解决方案提供给大量供应商。它最具代表性的功能包括 L7 和 L4 上的流量负载均衡,其中,TCP L4 流量负载均衡称得上是该解决方案最关键的功能之一。
在今年早些时候,尽管 Voyager 在 v9.0.0 中推出了对 HTTP/2 和 gRPC 协议的全面支持,但总的来看,对证书管理(Let's Encrypt 证书)的支持仍是 Voyager 集成的最突出的新功能。
Contour
Contour 和 Envoy 由同一个作者开发,它基于 Envoy。它最特别的功能是可以通过 CRD(IngressRoute)管理 Ingress 资源,对于多团队需要同时使用一个集群的组织来说,这有助于保护相邻环境中的流量,使它们免受 Ingress 资源更改的影响。
它还提供了一组扩展的负载均衡算法(镜像、自动重复、限制请求率等),以及详细的流量和故障监控。对某些工程师而言,它不支持粘滞会话可能是一个严重缺陷。
Istio Ingress
Istio 是 IBM、Google 和 Lyft 的联合开发项目,它是一个全面的服务网格解决方案——不仅可以管理所有传入的外部流量(作为 Ingress 控制器),还可以控制集群内部的所有流量。
Istio 将 Envoy 用作每种服务的辅助代理。从本质上讲,它是一个可以执行几乎所有操作的大型处理器,其中心思想是最大程度的控制、可扩展性、安全性和透明性。
通过 Istio Ingress,你可以对流量路由、服务之间的访问授权、均衡、监控、金丝雀发布等进行优化。
Ambassador
Ambassador 也是一个基于 Envoy 的解决方案,它有免费版和商业版两个版本。
Ambassador 被称为“Kubernetes 原生 API 微服务网关”,它与 Kubernetes 原语紧密集成,拥有你所期望的从 Ingress controller 获得的功能包,它还可以与各种服务网格解决方案,如 Linkerd、Istio 等一起使用。
顺便提一下,Ambassador 博客日前发布了一份基准测试结果,比较了 Envoy、HAProxy 和 NGINX 的基础性能。
Gloo
github.com/solo-io/gloo
实现:Go
许可证:Apache 2.0
Gloo 是在 Envoy 之上构建的新软件(于 2018 年 3 月发布),由于它的作者坚持认为“网关应该从功能而不是服务中构建 API”,它也被称为“功能网关”。其“功能级路由”的意思是它可以为后端实现是微服务、无服务器功能和遗留应用的混合应用路由流量。
由于拥有可插拔的体系结构,Gloo 提供了工程师期望的大部分功能,但是其中一些功能仅在其商业版本(Gloo Enterprise)中可用。
Skipper
Skipper 是 HTTP 路由器和反向代理,因此不支持各种协议。从技术上讲,它使用 Endpoints API(而不是 Kubernetes Services)将流量路由到 Pod。它的优点在于其丰富的过滤器集所提供的高级 HTTP 路由功能,工程师可以借此创建、更新和删除所有 HTTP 数据。
Skipper 的路由规则可以在不停机的情况下更新。正如它的作者所述,Skipper 可以很好地与其他解决方案一起使用,比如 AWS ELB。
其他
文章介绍了 Traefik 和 Istio,却没有详细介绍另一个流行的服务网格解决方案 Linkerd。这是为什么呢?
为简单起见,Linkerd 没有提供自己的 Ingress 控制器,而是旨在和工程师选用的控制器兼容使用。
总结
下表是各种 Ingress 控制器的摘要:
本文旨在尽可能让读者对 Ingress 控制器形成更完整的理解,因为每种控制器都有其优点和缺点。
社区官方的 Ingress 控制器成熟、易于使用,并提供了足以满足大多数情况的出色功能;
如果对可靠性和功能实现的质量有很高的要求,NGINX Ingress 的商业版会是一个合适的选择;
Kong 拥有最丰富的插件集,在其商业版本中也提供了更多功能,它还拥有基于自定义资源的动态配置;
如果比较关注负载均衡和授权,请看看 Traefik 和 HAProxy。它们是开源项目,功能已经经过社区多年验证,非常稳定,而且还在不断发展;
Contour 虽然只有两岁,但它已经具备 Envoy 之上的基础功能;
基于 Envoy 的解决方案拥有最丰富的功能集,尤其是 Istio。但这是一个复杂的解决方案,意味着工程师需要具备更多相关经验来配置、运行、操作它们;
在某些其他情况下,Gloo 的许多功能可能只在付费版本中提供;
如果你的应用程序需要高级或经常更改的 HTTP 路由表,那么 Skipper 可能是一个很合适的解决方案。
如果比较的是全球社区的选择趋势,那么 Istio(20k+⭐)和 Traefik(超过 25k⭐)的优势就显而易见了。即使是社区官方控制器,它也明显处于下风(不到 6k⭐)。相对的,Kong Ingress 和 HAProxy Ingress 最不热门,只有不到 1k⭐。
Kubernetes入门与实战培训
Kubernetes入门与实战培训将于2019年11月22日在北京开课,3天时间带你系统掌握Kubernetes,学习效果不好可以继续学习。本次培训包括:Docker基础、容器技术、Docker镜像、数据共享与持久化、Docker实践、Kubernetes基础、Pod基础与进阶、常用对象操作、服务发现、Helm、Kubernetes核心组件原理分析、Kubernetes服务质量保证、调度详解与应用场景、网络、基于Kubernetes的CI/CD、基于Kubernetes的配置管理等等,点击下方图片或者阅读原文链接查看详情。