9

我有一个工作集群,其中所有服务都响应在 Azure AKS 上运行的 helm 安装的 Ingress nGinx。这最终是特定于 Azure 的。

我的问题是:为什么我与此集群中的服务/pod 的连接会定期断开(显然是由于某种空闲超时),为什么连接断开似乎也与我的 Az AKS Browse UI 连接被切断一致?

这是为了获得关于究竟是什么触发了导致本地“浏览”代理 UI 与我的集群断开连接的超时的最终答案(关于我为什么要求关注的更多背景信息)。

从 Az CLI 使用 Azure AKS 时,您可以使用以下命令从终端启动本地浏览 UI:

az aks browse --resource-group <resource-group> --name <cluster-name>

这工作正常并弹出一个看起来像这样的浏览器窗口(耶):

Azure AKS 断开连接进入 pod

在您的终端中,您将看到以下内容:

  1. 在http://127.0.0.1:8001/上运行的代理按 CTRL+C 关闭隧道...
  2. 从 127.0.0.1:8001 转发 -> 9090 转发自
  3. [::1]:8001 -> 9090 8001 处理连接 8001 处理连接 8001 处理连接

如果您让集群的连接闲置几分钟(即您不与 UI 交互),您应该看到以下打印,表明连接已超时:

E0605 13:39:51.940659 5704 portforward.go:178] 失去与 pod 的连接

我仍然不明白的一件事是集群内的其他活动是否可以延长此超时时间,但无论您看到上面的内容,您基本上都在同一个地方......这意味着我们可以谈论它看起来的事实就像我从该服务器中的 pod 发出的所有其他连接一样,也已通过负责切断与 AKS 浏览 UI 联系的任何超时过程关闭。

那么问题是什么?

这对我来说是个问题的原因是我有一个运行 Ghost 博客 pod 的服务,该 pod 使用名为“Knex”的 npm 包连接到远程 MySQL 数据库。碰巧的是,较新版本的 Knex 有一个错误(尚未解决),如果 Knex 客户端和远程数据库服务器之间的连接被切断并需要恢复 - 它不会重新连接,只是无限负载。

nGinx 错误 503 网关超时

在我的情况下,导致 nGinx Ingress 给我一个错误 503 网关超时。这是因为在空闲超时切断 Knex 连接后 Ghost 没有响应——因为 Knex 没有正常工作并且没有正确恢复与服务器断开的连接。

美好的。 我回滚了 Knex,一切都很好。

但是为什么我的 pod 连接从我的数据库开始就被切断了呢?

因此,这个问题有望节省未来一些人尝试解决与 Kubernetes 相关的幻象问题(可能是 Azure 特定的,也许不是)在服务/pod 空闲一段时间后切断连接。

4

1 回答 1

10

简短的回答:

当您添加新入口(nGinx / Traefik...任何入口)时,Azure AKS 会自动部署 Azure 负载均衡器(具有公共 IP 地址)——负载均衡器的设置配置为“基本”Azure LB,有 4 分钟空闲连接超时。

该空闲超时既是标准的也是必需的(尽管您可以修改它,请参见此处:https ://docs.microsoft.com/en-us/azure/load-balancer/load-balancer-tcp-idle-timeout )。话虽如此,对于从负载均衡器 IP 向外流出的任何流量,都无法完全消除它——目前支持的最长持续时间是 30 分钟。

没有本机 Azure 方法可以绕过被切断的空闲连接。

因此,根据最初的问题,处理此问题的最佳方法(我觉得)是将超时保留在 4 分钟(因为它必须存在),然后设置您的基础设施以优雅的方式断开连接(空闲时)在达到负载均衡器超时之前。

我们的解决方案

对于我们的 Ghost 博客(访问 MySQL 数据库),我能够如上所述回滚,这使得 Ghost 进程能够处理数据库断开/重新连接情况。

铁轨呢?

是的。同样的问题。

对于一个单独的基于 Rails 的应用程序,我们还在 AKS 上运行,该 AKS 连接到远程 Postgres DB(不在 Azure 上),我们最终将 PGbouncer(https://github.com/pgbouncer/pgbouncer)作为我们集群上的附加容器通过在这里找到了很棒的方向:https ://github.com/edoburu/docker-pgbouncer/tree/master/examples/kubernetes/singleuser

通常,任何尝试从 AKS 访问远程数据库的人都可能需要实施中间连接池解决方案。池服务位于中间(对我们来说是 PGbouncer)并跟踪连接空闲的时间,这样您的工作进程就不需要关心这些了。

如果您开始接近负载均衡器超时,则连接池服务将丢弃旧连接并建立一个新连接(重置计时器)。这样,当您的客户端通过管道发送数据时,它会按预期落在您的数据库服务器上。

结束时

这是一个非常令人沮丧的错误/案例。我们花费了至少 2 天的开发运营时间来找出第一个解决方案,但即使知道这可能是同一个问题,我们这次又花费了 2 天时间。

即使将计时器延长到默认的 4 分钟以上也无济于事,因为这只会使问题更容易排除故障。我想我只是希望任何在从 Azure AKS / Kubernetes 连接到远程数据库时遇到问题的人都比我更擅长谷歌搜索,并且可以为自己节省一些痛苦。

感谢 MSFT 支持(Kris 你是最好的)关于 LB 计时器的提示以及将 PGbouncer 放在一个容器中的家伙,所以我不必重新发明轮子。

于 2018-07-19T22:27:34.723 回答