2023 年 1 月,我们发布了 NGINX Ingress Controller 3.0 版本,该版本提供了许多重要的新特性以及功能强化。其中,基于 NGINX Plus 的 NGINX Ingress Controller 提供的新特性 Deep Service Insight 是一个非常有价值的功能。
当路由决策系统(如负载均衡器)位于一个或多个 Kubernetes 集群的前面时,会遇到一个棘手的问题,即系统无法获取在 Ingress controller 后面集群中运行的各个 service 的健康状态信息,这对于路由决策系统来说是致命的缺陷。这会造成系统无法将流量只路由到具有健康服务的集群,从而可能导致用户遇到服务中断以及服务器返回 404 和 500 等错误。而 Deep Service Insight 就是为了解决这个问题而生。
为了解决这个问题,Deep Service Insight 在一个专用的 endpoint 上暴露后端服务 pod 的健康状态(由 NGINX Ingress Controller 收集),以供您的系统访问并用于做出更好的路由决策。
本文将深入探讨 Deep Service Insight 如何解决该问题,阐释了它在一些常见用例中的工作原理,并介绍了其配置方法。
为何使用 Deep Service Insight ?
Kubernetes 原生的存活性探测(Liveness)、就绪性探测(Readiness)和启动探针(Startup probe)可为您提供一些关于在集群中运行的后端服务的信息,但还不足以支持您在整个堆栈中做出更明智的路由决策。随着您的 Kubernetes 部署日趋复杂,以及您对业务无中断正常运行的需求变得更加紧迫,缺乏准确的信息将会带来诸多麻烦。
在扩展 Kubernetes 环境时,提高系统连续可用时间的一种常见方法是在集群的前面部署负载均衡器、DNS 管理器或其他自动决策系统。然而,由于 Ingress controller 的工作原理,位于 Kubernetes 集群之前的负载均衡器通常无法获取集群中 Ingress controller 后端服务的状态信息,只能验证 Ingress controller pod 本身是否健康以及能否接收流量。
另一方面,NGINX Ingress Controller 能够提供关于服务健康状态的信息。它通过定期发送 HTTP、 TCP、 UDP、和 gRPC 服务的被动健康检查,监控请求响应能力并跟踪成功响应代码及其他指标,从而监控集群中上游 pod 的健康状态。它利用这些信息来决定如何在服务的 pod 中分配流量,以确保一致且可预测的用户体验。通常情况下,NGINX Ingress Controller 在后台默默地执行所有这些操作,而您可能从未认真考虑过究竟发生了什么。现在,Deep Service Insight 可以将这些宝贵的信息暴露出来,以至于您可以在更多的网络层及环境中更有效地使用这些信息。
Deep Service Insight 的工作原理
Deep Service Insight 可用于使用 NGINX VirtualServer 和 TransportServer 自定义资源(分别面向 HTTP 和 TCP/UDP)部署的服务。Deep Service Insight 通过 NGINX Plus API 在 Deep Service Insight 特有的专用 endpoint 上共享 NGINX Ingress Controller 所收集的后端服务中各个 pod 的状态信息:
- 对于 VirtualServer – <IP_address> :<port> /probe/<hostname>
- 对于 TransportServer – <IP_address> :<port> /probe/ts/<service_name>
其中
- <IP_address> 属于 NGINX Ingress Controller
- <port> 是 Deep Service Insight 端口号(默认 9114)
- <hostname> 是 VirtualServer 资源的
spec.host
字段中定义的服务域名 - <service_name> 是 TransportServer 资源的
spec.upstreams.service
字段中定义的服务名称
输出结果包括两类信息:
-
主机名或服务名称的 HTTP 状态代码:
200
OK
– 至少一个 pod 是健康的418
I’m
a
teapot
– 所有 pod 都不健康404
Not
Found
– 没有 pod 与指定的主机名或服务名称相匹配
-
与指定的主机名或服务名称相关的三个数值:
- 服务实例 (pod) 的总数
- 处于 Up(健康)状态的 pod 数量
- 处于 Unhealthy(不健康)状态的 pod 数量
下例显示了一个服务的三个 pod 都处于健康状态:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Date: Day, DD Mon YYYY hh:mm:ss TZ
Content-Length: 32
{"Total":3,"Up":3,"Unhealthy":0}
如欲了解更多详细信息,请查看 NGINX Ingress Controller 文档。
您可以通过配置主动健康检查,进一步自定义 NGINX Ingress Controller 用于判断 pod 是否健康的标准。您可配置健康检查发送路径及目标端口、在指定时间段内必须发生多少次检查失败才能将 pod 视为不健康、预期状态码以及连接或接收响应的超时时间等。如有需要,可在 VirtualServer 或 TransportServer 资源中添加 Upstream.Healthcheck 字段。
Deep Service Insight 的用例示例
让我们来看这样一个场景,两个 k8s 集群中运行同样服务,通过前端的负载均衡器将流量在两个集群间路由,需要确保业务的高可用性。在这个场景下,Deep Service Insight 将会变的至关重要。在每个集群内,NGINX Ingress Controller 跟踪上游 pod 的健康状况,如上所述。当您启用 Deep Service Insight 时,有关健康和不健康上游 pod 数量的信息会被暴露在专用的 endpoint 上。您的路由决策系统可以访问该路径,并根据这些信息将应用流量路由至健康的 pod 而非不健康的 pod。
下图显示了 Deep Service Insight 在这种场景中的工作原理。
在高可用性场景中对集群进行维护时,您也可以利用 Deep Service Insight。您只需要将正在维护的集群中的服务 pod 数量缩减到零即可。Deep Service Insight 为接受到该集群没有健康的 pod,并将该信息展现在 endpoint 上,您的路由决策系统将基于该信息将流量发送至其他集群的健康 pod 上。您无需改变 NGINX Ingress Controller 或系统的配置即可有效地实现自动故障切换,而且您的客户也不会遭遇服务中断。
启用 Deep Service Insight
如要启用 Deep Service Insight,在 Kubernetes 配置清单中添加 -enable-service-insight
命令行参数,或者如果使用 Helm,则将 serviceInsight.create
参数设置为 true
。
共有两个可选参数,您可以添加这些参数以针对您的环境调整 endpoint:
-service-insight-listen-port
<port>
– 更改 Deep Service Insight 端口号(默认为 9114, (<port>
是 1024–65535 之间的一个整数)。Helm 等效参数是serviceInsight.port
。-service-insight-tls-string
<secret>
– Kubernetes secret(TLS 证书和密钥)用于 Deep Service Insight endpoint 的 TLS 卸载(<secret>
是一个字符串,格式为<namespace>/<secret_name>
)。Helm 等效参数是serviceInsight.secret
。
示例:为 Cafe 应用启用 Deep Service Insight
如欲了解 Deep Service Insight 的实际应用,您可为 Cafe 应用(经常用作 NGINX Ingress Controller 文档中的示例)启用 Deep Service Insight。
-
安装 NGINX Ingress Controller 的 NGINX Plus 版本,该版本支持 NGINX 自定义资源并启用了 Deep Service Insight:
- 如果使用 Helm, 则将
serviceInsight.create
参数设置为true
。 - 如果使用 Kubernetes 配置清单 (Deployment 或 DaemonSet), 则在清单文件中添加
-enable-service-insight
参数。
- 如果使用 Helm, 则将
-
检查 NGINX Ingress Controller 是否正在运行:
$ kubectl get pods -n nginx-ingress NAME READY ... ingress-plus-nginx-ingress-6db8dc5c6d-cb5hp 1/1 ... ... STATUS RESTARTS AGE ... Running 0 9d
- 根据 README 中的说明部署 Cafe 应用。
-
验证是否已为 Cafe 应用部署 NGINX VirtualServer 自定义资源(为方便阅读,省略了 IP 地址):
$ kubectl get vs NAME STATE HOST IP PORTS AGE cafe Valid cafe.example.com ... [80,443] 7h1m
-
验证在 cafe.example.com 上运行的 Cafe 服务是否有三个上游 pod:
$ kubectl get pods NAME READY STATUS RESTARTS AGE coffee-87cf76b96-5b85h 1/1 Running 0 7h39m coffee-87cf76b96-lqjrp 1/1 Running 0 7h39m tea-55bc9d5586-9z26v 1/1 Running 0 111m
-
访问 Deep Service Insight 端点:
$ curl -i <NIC_IP_address>:9114/probe/cafe.example.com
200
OK
响应代码表明,服务已经准备好接收流量(至少有一个健康的 pod)。在本例中,三个 pod 都处于 Up 状态。HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Date: Day, DD Mon YYYY hh:mm:ss TZ Content-Length: 32 {"Total":3,"Up":3,"Unhealthy":0}
418
I’m
a
teapot
状态代码表明,该服务不可用(所有 pod 都不健康)。HTTP/1.1 418 I'm a teapot Content-Type: application/json; charset=utf-8 Date: Day, DD Mon YYYY hh:mm:ss TZ Content-Length: 32 {"Total":3,"Up":0,"Unhealthy":3}
404
Not
Found
状态代码表明,指定的主机名上没有运行任何服务。HTTP/1.1 404 Not Found Date: Day, DD Mon YYYY hh:mm:ss TZ Content-Length: 0
更多资源
有关 NGINX Ingress Controller 3.0.0 版的完整变更日志,请查看版本说明。
如欲试用基于 NGINX Plus 的 NGINX Ingress Controller 和 NGINX App Protect,请立即下载30 天免费试用版或者联系我们讨论您的用例。