Pgbouncer:如何在 kubernetes 集群中正确 运行

Pgbouncer: how to run within a kubernetes cluster properly

背景:我目前 运行 一些带有 pgbouncer sidecar 容器的 kubernetes pods。我一直 运行 发现带有变通办法的边车(将在 k8s 1.18 中解决)的烦人行为,但提出了一个关于 运行 在 k8s 中使用 pgbouncer 的早期问题。

很多人推荐 pgbouncer 的 sidecar 方法,但我想知道为什么 运行每个人都说一个 pgbouncer:k8s 集群中的机器不会更好?我承认我对 pgbouncer 或 k8s 网络的理解不够深入,无法理解这两种方法的含义。


编辑:

添加上下文,好像我的问题不够清楚。

我正在尝试在 kubernetes 集群中 运行ning pgbouncer 的两种方法之间做出决定。 PostgreSQL 服务器未 运行 在此集群中。这两种方法是:

  1. 运行 pgbouncer 作为我所有 pods 的边车容器。我有很多 pods:网络服务器部署上的一些副本、异步作业部署和几个 cron 作业。
  2. 运行 pgbouncer 作为单独的部署。我计划 运行在 k8s 集群上为每个节点配置 1 个 pgbouncer 实例。

我担心 (1) 无法很好地扩展。如果我的 PostgreSQL master 最多有 100 个连接,而每个池最多有 20 个连接,我可能会冒着过早饱和连接的风险。此外,由于新的 pgbouncer sidecars 与被删除的旧图像一起存在,因此我冒着在推送期间使 master 上的连接饱和的风险。

然而,我几乎从未看到 (2) 被推荐。似乎每个人都推荐(1),但缺点对我来说似乎很明显。通过连接到我的 pod 外部的 pgbouncer 我会招致的网络惩罚是否大到足以引起注意? pgbouncer 是否足够聪明来处理许多其他可能使连接饱和的 pgbouncer 实例?

我们 运行 在 Kubernetes 上生产的 pgbouncer。我希望最好的方法取决于用例。我们不采用 sidecar 方法,而是将 运行 pgbouncer 作为一个单独的 "deployment",应用程序通过 "service" 访问它。这是因为对于我们的用例,我们有 1 个 postgres 实例(即一台物理数据库机器)和访问同一实例的同一应用程序的许多副本(但在该实例中使用不同的数据库)。 Pgbouncer 用于管理活动连接资源。我们为每个应用程序独立地汇集连接,因为我们的应用程序的性质是有许多并发连接而不是太多事务。我们目前是 运行 1 个 pod(无副本),因为如果 pgbouncer 快速重启,这对我们的用例来说是可以接受的。许多应用程序都 运行 它们自己的 pgbouncer,并且每个应用程序都有多个需要访问数据库的组件(因此每个 pgbouncer 都在汇集应用程序一个实例的连接)。这样做的 https://github.com/astronomer/airflow-chart/tree/master/templates/pgbouncer

以上内容不包括为访问数据库设置凭据。上面的链接模板需要一个已经存在的秘密。我希望您需要根据您的用例调整模板,但它应该可以帮助您理解。

我们遇到了一些生产问题。主要是我们仍然需要做更多的研究如何在不中断现有连接的情况下更换或移动 pgbouncer。我们发现应用程序与 pgbouncer 的连接是有状态的(当然是因为它正在汇集事务),因此如果 pgbouncer 容器(pod)在服务后面换出新容器,那么从应用程序的角度来看,现有连接将被删除。如果您有一个应用程序可以确保很少丢失的连接重试并在 "service" 上使用 Kubernetes 粘性会话,那么即使 运行ning pgbouncer 副本也应该没问题。我们的组织仍需要进行更多调查才能使其完美运行。