11. 调试 502s

Linkerd 代理在处理请求时遇到连接错误时,它通常会返回 HTTP 502(Bad Gateway)响应。 由于缺乏可用信息,很难弄清楚为什么会发生这些错误。

为什么只有在注入 Linkerd 时才会出现这些错误?

Linkerd连接错误转换为 HTTP 502 响应。 这可能会使以前未检测到的问题突然可见。 这是一件好事。 Linkerd 还改变了管理应用程序连接的方式:它重用持久连接并建立额外的连接跟踪层。 以这种方式管理连接有时会暴露底层应用程序或基础设施问题, 例如错误配置的连接超时,这可能表现为连接错误

为什么 Linkerd 不能提供更多信息性错误消息?

Linkerd 代理的角度来看,它只是看到它与应用程序的连接被拒绝或关闭,而无需解释。 这使得 Linkerd 几乎不可能在 502 响应中报告任何错误消息。 但是,如果这些错误与 Linkerd 的引入同时发生,则确实表明问题与连接重用连接跟踪有关。 以下是应用程序可能拒绝终止连接的一些常见原因。

连接错误的常见原因

连接空闲超时

一些服务器配置了连接空闲超时例如 Go HTTP 服务器中的这个超时)。 这意味着服务器将关闭任何在指定时间段内没有收到任何流量的连接。 如果任何请求已经在传输时启动连接关闭,这些请求将失败。 如果您的流量具有固定周期(例如活动检查)并且空闲超时等于该周期, 则可能会发生这种情况。

要解决此问题,请确保您的服务器的空闲超时足够长,以便它们不会关闭正在使用的连接。

半关闭连接超时

在关闭 TCP 连接期间,连接的每一端都必须独立关闭。 当一侧关闭而另一侧未关闭时,连接被称为“半关闭(half-closed)”。 连接处于这种状态是有效的,但是,操作系统的连接跟踪器可能会丢失对长时间保持半关闭状态的连接的跟踪。 在建立表现为 502 响应的新连接时,这可能会导致无法传递响应和端口冲突。

您可以使用 脚本来检测 Kubernetes 集群上的半关闭连接。 如果您检测到大量半关闭的连接,则有几种方法可以解决这种情况。

一种解决方案是更新您的应用程序,以免连接长时间处于半关闭状态或停止使用执行此操作的软件。 不幸的是,这并不总是一种选择。

另一种选择是增加连接跟踪器对半关闭连接的超时时间。 此超时的默认值取决于平台,但通常为 1 分钟或 1 小时。 您可以通过查看任何注入容器中的文件 /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait 来查看当前值。 要增加此值,您可以将 --close-wait-timeout flaglinkerd inject 一起使用。 但是请注意,设置此 flag 也会将代理初始化容器的 privileged 字段设置为 true。 将此超时设置为 1 小时通常就足够了,并且与 kube-proxy 使用的值匹配。