问题一:Ingress-Nginx TCP 代理 主动断开
背景
大数据方反馈通过TCP访问的服务,会出现偶发性的请求过程中TCP断连。这些后台服务部署在K8s中,通过ingress-nginx进行TCP代理暴露服务
排查过程
错误排查方向
基础知识:一开始以为是http层的长连接在达到默认的1000次请求后nginx会主动断开方便负载,实际沟通之后确认数据库这种通过TCP协议传输的服务不存在这种http层的长连接机制
业务特点:执行SQL,可能发起长达数十分钟的请求
问题分析
目前海外国际的K8s中的,nginx的worker数是4,worker的优雅关闭时间是240s
从日志里看确实有一直发生一些 nginx -s reload,可能导致tcp链接被断开
类似的websockets链接被断开的issue:https://github.com/kubernetes/ingress-nginx/issues/2461
结论
默认240s的优雅停机策略,但是Spark这边的一些服务请求可能会超过240s才能返回。可参考下面这篇文档的分析过程:
解决方案
方案1:调大worker的优雅关闭时间
优点:变更快捷,将超时时间设置的较大,能快速解决99%的问题
缺点:还是有可能(SQL执行超过优雅关闭的超时时间)出现断连的情况;内存可能上涨(出现比较多的待终止的worker)
方案2:隔离ingress-nginx,减少其他ingress变更造成的影响
优点:可避免其他ingress变更导致的reload,配合调大worker的优雅关闭时间,能更好的规避类似的问题
缺点:后端发布时,依然会出现reload,但这时依靠后端自行做优雅关闭,也可规避这种问题
方案3:引入其他 Ingress 实现
Apache APISIX
https://apisix.apache.org/docs/ingress-controller/concepts/apisix_route/#tcp-route
Apache APISIX 是一个动态、实时、高性能的 API 网关,提供了丰富的流量管理功能,如负载均衡、动态上游、灰度发布、服务熔断、身份验证等。以下是一些关于 Apache APISIX 的主要特点:
高性能:Apache APISIX 是基于 Nginx 和 OpenResty 的,因此它可以利用 Nginx 的高性能和 OpenResty 的灵活性。
动态配置和热加载:Apache APISIX 支持动态配置和热加载,这意味着你可以在不重启服务的情况下更新配置。
丰富的插件:Apache APISIX 提供了丰富的插件,包括身份验证、安全、流量控制、观察性等。
多语言支持:Apache APISIX 支持多种语言编写插件,包括 Lua、Java、Python 等。
服务网格:除了作为 API 网关使用,Apache APISIX 也可以作为服务网格的数据平面,提供微服务之间的流量管理。
社区和支持:Apache APISIX 是 Apache 基金会的顶级项目,有一个活跃的社区和商业支持。
官网博客对nginx和kong的局限性的描述,申明是解决了nginx无法热加载配置问题
Traefik
https://github.com/traefik/traefik
Traefik 是一个现代的 HTTP 反向代理和负载均衡器,它可以自动发现和配置服务。以下是一些关于 Traefik 的主要特点:
动态配置:Traefik 可以自动发现和配置服务,这使得它非常适合用在微服务和容器化的环境中。
多协议支持:Traefik 支持多种协议,包括 HTTP、HTTPS、TCP、UDP。
易用性:Traefik 的配置比较简单,特别是对于简单的用例。它提供了一个 Web UI,可以方便地查看和管理服务。
Let’s Encrypt 集成:Traefik 集成了 Let’s Encrypt,可以自动为你的服务获取和更新 SSL 证书。
服务网格:除了作为反向代理和负载均衡器使用,Traefik 也可以作为服务网格的数据平面,提供微服务之间的流量管理。
社区和支持:Traefik 有一个活跃的社区和商业支持。
Github 上的 stars 数达到了 4.7w,自带 UI,有一些特色的新功能,是一个成熟完善的网关方案
Envoy
Envoy 是一个开源的边缘和服务代理,设计用于云原生应用。以下是一些关于 Envoy 的主要特点:
- 高性能:Envoy 是用 C++ 编写的,因此它具有很高的性能。
- 动态服务发现:Envoy 可以动态发现上游服务,这使得它非常适合用在微服务和容器化的环境中。
- 多协议支持:Envoy 支持多种协议,包括 HTTP/1.1, HTTP/2, gRPC, TCP 等。
- 详细的度量和日志:Envoy 提供了详细的度量和日志,可以帮助你理解和调试你的服务。
- 先进的负载均衡:Envoy 提供了一些先进的负载均衡特性,如熔断、重试、超时、健康检查等。
- 过滤器链:Envoy 的过滤器链允许你在请求和响应路径上插入自定义的过滤器,以实现复杂的行为。
- 社区和支持:Envoy 由 Lyft 开发,现在是 CNCF 的项目,有一个活跃的社区和广泛的商业支持。
比较各种以 Envoy 为核心的 ingress 实现
- Contour:由 VMware 维护,提供了一个简单的、直观的方式来管理 Envoy。Contour 提供了一些基本的流量管理功能,如路由、重试和超时,但不如 Istio 或 Ambassador 全面。Contour 的主要优点是它的简单性和易用性。
- Istio:是一个全功能的服务网格,提供了流量管理、安全、观察性等功能。Istio 使用 Envoy 作为数据平面,但它的配置比 Contour 更复杂。Istio 的主要优点是它的功能丰富和灵活性。
- Ambassador:是一个 API 网关,也可以作为 Kubernetes Ingress 控制器使用。Ambassador 提供了一些高级功能,如认证、速率限制和熔断。Ambassador 的主要优点是它的功能丰富和易用性。
- Gloo:由 Solo.io 开发,是一个功能丰富的 API 网关。Gloo 提供了一些高级功能,如函数级路由、请求转换和安全策略。Gloo 的主要优点是它的功能丰富和灵活性。
附上各种ingress controller实现的对比:
https://docs.google.com/spreadsheets/d/191WWNpjJ2za6-nbG4ZoUMXMpUK8KlCIosvQB0f-oq3k/edit?pli=1#gid=907731238
总结
如上主要的 3 种 ingress 实现均支持各种协议的代理(https、tcp、websocket 等),均支持路由(按 host、path 等)、负载均衡策略(Round robin、Sticky sessions等)等各种代理服务器的核心功能。理论上都可以满足大数据的使用场景,但从组件轻量性、简单易用性和内部相关使用经验考虑,决定采用 Contour + Envoy 作为最终的方案
Contour优势:
- 目前是CNCF的孵化项目,其他上述ingress实现均未进入名单(Envoy是CNCF毕业的项目)
https://landscape.cncf.io/?group=projects-and-products&view-mode=grid&project=incubating&item=orchestration-management--service-proxy--contour - 全面支持 Ingress v2版本,Gateway API(https://gateway-api.sigs.k8s.io/),支持到最新正式的v1.0版本。后续可考虑将现有的 ingress 资源切换到 Gateway API,或者更高阶的网关能力,社区提供了详细的迁移文档
内部使用经验:
- Serverless 的 Knative 里的网关用的是 Envoy
- 阿里云的 ServiceMesh 用的是 Isito,网关也是 Envoy
问题二:Ingress-Nginx端口满导致502
现象
同步调用的Serverless集群,在客户端出现502报错
网络架构
要点:
Serverless网关使用的 Kourier 网关挂到了流量入口的Ingress-nginx后面,ingress-nginx 与 serverless 的网关是点对点访问,所有 serverless 的集群必须经过 envoy 转发。TCP 连接的 5 元组下,如果同步请求不及时返回,目标 IP 是唯一(所有Serverless服务Service的externalName均指定为了:kourier-internal.kourier-system.svc.cluster.local)的情况下,会占用越来越多的 nginx 源端口。
关键日志:
直接原因: 找一个出现报错的服务,查看它的Serverless扩缩容配置
最大副本是 10,扩容指标阈值是 200,也就是只能支持 2000 的并发度,但出问题时有 QPS 达到了 4500+,服务无法承受这样的流量请求,只能由 Activator hold住请求,一直占用着 Nginx 的源端口
改进措施
方案1:新部署Envoy网关暴露服务出来,作为 serverless 的入口
好处:
- 与 ingress-nginx 隔离,避免互相影响
- 链路性能更好
劣势:
- 机器成本:准备独立机器部署Envoy
- 域名切换 —— 可以把重要的集群做下切换,调整范围缩小
方案2:内部管理平台通过新的 Consul+Nginx 暴露服务
团队调整后,没人继续维护Ingress-nginx链路,建议通过其他方式暴露服务,比如注册Pod到 Consul,Nginx从Consul拉取IP,实现服务的自动发现,因是内部方案,不继续做详细介绍