在第一部分中,我们概述了Kubernetes中的PostgreSQL Pods在生产就绪的PostgreSQL安装中需要如何表现。 今天,我们将探讨如何协调这些行为。
在较高的层次上,PostgreSQL应用程序是由控制层编排的。 控制层由中央存储("真相的来源")和分布式代理组成,这些代理根据中央存储的状态进行决策,并将馈送状态的更改反馈回中央存储。
控制器
就像Kubernetes本身的一部分一样,PostgreSQL应用程序具有一个集中的控制器,该控制器代表应用程序整体的行为方式。 应用程序级别的行为,例如扩展,升级到新的PostgreSQL版本,选择新的主节点(主节点)以启动故障转移或初始部署本身,这些都是控制器的责任。
如果您想像一个单一进程那样处理分布式PostgreSQL应用程序,那就是控制器允许您执行的操作。
到底是什么?
从外部看,该控制器使PostgreSQL看起来像一个进程,但在内部则更为复杂。
首先,控制器本身不仅仅是一个过程。 如果控制器发生故障,则会创建一个新实例来替换它。 一种方法是使用单副本Kubernetes部署资源。 Kubernetes将尽最大努力确保始终有一个控制器在运行。 此外,在单个进程将其状态保存在内存中的情况下,控制器使用中央存储,通常是跨多个计算机运行的分布式数据库。
像控制器和中央存储相结合的分布式系统如何为PostgreSQL提供统一的应用程序级接口? 答案在于对PostgreSQL应用程序的可能状态进行分类。 例如:
· 预先部署:PostgreSQL尚未运行。
· 正常:在1个主要和N个备用数据库上运行
· 需要故障转移:使用N个备用数据库但没有主数据库运行。
考虑以下情况:主服务器出现故障,控制器必须选择一个备用服务器进行升级。 状态更改可能如下所示:
· 正常:1个主要和2个备用
· 需要故障转移:0个主备和2个备用
· 健康:1个主用和1个备用
· 正常:1个主要和2个备用
如果灾难杀死了整个PostgreSQL部署,我们可能会看到:
· 正常:1个主要和2个备用
· 预先部署:PostgreSQL已不再运行。
· 正常:1个主用和0个备用
· 正常:1个主要和2个备用
这些示例提出了一些重要问题:控制器如何决定在给定状态下要做什么? 如何填充状态-它基于什么外部信息? 这些状态在商店中如何表示?
控制器如何决定要做什么?
Kubernetes遵循一种保留单独的规范和状态字段的模式。 规格表示所需状态,而状态为实际状态。 Kubernetes中的控制器的作用是使状态更接近规范。
PostgreSQL控制器执行相同的操作。 中央存储保存由应用程序管理员指定的所需状态,以及由控制器和其他代理(例如PostgreSQL Pod sidecars)收集的实际状态。 控制器作为循环运行,连续执行动作以将实际状态与所需状态统一起来。
控制器实际如何执行操作?
控制器通过修改中央存储触发对应用程序其余部分的更改。 为了创建一个新的PostgreSQL实例,控制器在Kubernetes API(一种中央存储)中创建一个PostgreSQL Pod。 为了将备用数据库提升为主要数据库,控制器将该实例的所需状态更新为"主要数据库"。 那个PostgreSQL实例的sidecar实际上执行了提升。
接下来的是
弄清楚如何表示分布式应用程序的状态是一个复杂的设计问题。 值得特别注意。 本系列的下一篇文章将解决我们今天悬而未决的问题:
· 中央存储中的PostgreSQL应用程序状态如何表示?
· 这种表示形式如何与应用程序的真实状态保持同步?
感谢您的阅读,第三部分将与大家见面!
> PostgreSQL (src)
(本文翻译自Kynan Rilee的文章《PostgreSQL on Kubernetes the Right Way: Part Two》,参考:https://medium.com/kokster/postgresql-on-kubernetes-the-right-way-part-two-1a981d5fb747)