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

9
背景:我目前在一些kubernetes pod中运行pgbouncer sidecar容器。我遇到了有关sidecar的烦人问题(这将在k8s 1.18中得到解决),但这带来了一个早期问题,即在k8s内部运行pgbouncer。
许多人建议使用pgbouncer的sidecar方法,但我不明白为什么在k8s群集中针对每个机器运行一个pgbouncer不会更好?我承认我对pgbouncer或k8s网络没有足够深入的理解,无法理解任何方法的影响。
编辑:
添加上下文,因为似乎我的问题不够清楚。
我正试图在kubernetes集群中选择两种运行pgbouncer的方法。 PostgreSQL服务器未在此群集中运行。这两种方法是:
1.在所有我的pod中作为sidecar容器运行pgbouncer。我有许多pod:Web服务器部署上的一些副本,异步作业部署以及几个cron作业。
2.将pgbouncer作为单独的部署运行。我计划在k8s群集中每个节点上运行1个pgbouncer实例。
我担心(1)不会很好地扩展。如果我的PostgreSQL主服务器最大连接数为100,并且每个池的最大连接数为20,则可能很早就面临饱和连接的风险。此外,我在推送期间面临饱和主服务器连接的风险,因为新的pgbouncer sidecars存在并行于删除旧镜像。
然而,我几乎从未见过(2)被推荐。似乎每个人都推荐(1),但是对我来说缺点非常明显。如果在我的pod之外连接到pgbouncer会产生网络惩罚,这个惩罚足够大吗? pgbouncer能否聪明地处理许多其他可能使连接饱和的pgbouncer实例?

Kubernetes服务没有“本地优先”的概念,因此更难将流量路由到Pod外的本地服务。您可以在网络延迟和容错之间选择(也许需要一些复杂性来修复容错)。 - Matt
如果您可以添加有关您的应用程序如何使用PgBouncer和应用程序部署结构的原因和方式的一些信息,可能会更有指导性。 - Matt
@SirensOfTitan 这个问题有任何更新吗? - Will R.O.F.
@willrof:抱歉,我刚刚更新了!我意识到我的初始问题非常不清楚。我不是在问为什么我不能在节点上运行pgbouncer,而是为什么我会选择将其作为我的pod的旁车运行,而不是运行一个pgbouncer部署,其副本数>=集群中的节点数。我担心在前一种情况下连接饱和,随着副本数量的增加。 - SirensOfTitan
1个回答

15
我们在Kubernetes中生产环境中运行pgbouncer。我认为最好的方法是基于用例的。我们没有采用旁路(sidecar)方法,而是将pgbouncer作为单独的“deployment”运行,并通过“service”被应用程序访问。这是因为对于我们的用例,我们有1个Postgres实例(即一个物理数据库服务器),许多副本的同一应用程序访问该实例(但在该实例内使用不同的数据库)。Pgbouncer用于管理活动连接资源。我们独立地为每个应用程序池化连接,因为我们的应用程序的性质是具有许多并发连接和不太多的事务。我们目前使用1个pod(无副本),因为如果pgbouncer快速重启,则对于我们的用例来说这是可以接受的。许多应用程序都运行自己的pgbouncers,每个应用程序都有多个需要访问数据库的组件(因此每个pgbouncer正在池化一个应用程序实例的连接)。实现方式如下: https://github.com/astronomer/airflow-chart/tree/master/templates/pgbouncer 以上内容不包括正确设置访问数据库的凭据。上面链接的模板期望已经存在秘钥。我认为您需要根据自己的用例调整模板,但它应该帮助您理解。我们最近遇到了一些生产问题。主要是我们还需要进一步研究如何在不中断现有连接的情况下替换或移动pgbouncer。我们发现应用程序与pgbouncer的连接是有状态的(当然,因为它正在汇集事务),因此如果将pgbouncer容器(pod)在服务后面替换为新容器,则从应用程序的角度来看,现有的连接会被中断。如果您有一个可以确保很少中断连接并使用Kubernetes粘性会话的服务,则即使运行pgbouncer副本,这也应该是可以接受的。我们的组织仍需要进行更多的调查,以使其完美地运作。

一种运行单个副本的方法是设置 poddisruptionbudget,并将 minAvailable 设置为 1。这种方法有些 hacky,但可以防止 Pod 被重新调度以保护其免受自动缩放操作的影响。然而,这也可能意味着一个不健康的节点会导致 Pod 无法重新调度。 - Derek Williams
你有没有找到一种方法使其能够抵御Pod重启的影响?我们在Kubernetes设置中有类似的配置,但我们只将其用于后台进程,而不是处理Web请求的用户面向型Pod,因为有时所在节点会死机,导致大量连接丢失。虽然这并非世界末日,但如果能避免出现成千上万的连接错误,并使其足够强大以用于Web请求,那就太好了。 - mscrivo
我们将图表移动到OSS apache/airflow存储库中:https://github.com/apache/airflow/tree/main/chart/templates/pgbouncer - Andrii Soldatenko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接