我有一个小的爱好网站,我想在我的服务器上发布。我选择使用kubernetes,因为我在工作中也部分使用它,所以我想熟悉一下。我买了hetzner debian服务器并安装了k3 s。现在正在部署PostgreSQL容器(版本15.2,不是集群)按照这个tutorial。(我做了一些小的修改,我从其他教程中看到的,应该不相关)。
它运行良好,我很高兴。但我试图重新启动部署,以确保数据不会丢失,如果服务器出于某种原因下降。几次重新启动后,数据库被损坏。
有一次我看到:
PANIC: invalid magic number 0000 in log segment 000000010000000000000000, offset 0
另一次:
invalid contrecord length 1174 (expected 48430224) at 0/195BC90
另一次:
PANIC: could not locate a valid checkpoint record
当我试图谷歌如何恢复从这一点,我没有找到任何安全的选项,大多数建议是恢复备份。
所以我的问题是,我如何安全地重启/关闭PostgreSQL容器?我是否在k8s中丢失了PostgreSQL pod的一些关闭配置?
更新1:
我使用r
命令从k9 s重新启动部署。我认为UI使它看起来像是立即旋转的,但可能需要一些时间。所以我认为我每10秒触发多次重新启动,这可能损坏了数据库。无论如何,我添加了terminationGracePeriodSeconds: 60
并使用了preStop
从应答钩子。谢谢
更新2:我导入了DB,重新启动并再次出现相同的问题:
找不到有效的检查点记录
更新3:我用StatefulSet
替换了Deployment
,它似乎能更好地处理重启。尝试了10多次重启,没有问题。而在第四次重启时崩溃了。
1条答案
按热度按时间db2dz4w81#
当然,最好的做法是使用像cloudnative-pg或postgres-operator这样的操作符,但它们非常大,对于简单的工作负载可能有更多的功能。
溶液
将以下内容添加到您的pod规格
解释
基本上,当你杀死一个pod时,Kubernetes会给你的pod发送
SIGTERM
信号,并给你30秒的时间,之后它会发送SIGKILL
。当postgres接收到SIGTERM
时,它不会接受网络连接,但它不会终止现有的终止,所以任何客户端都会阻止db的终止,30秒后,pod将收到SIGKILL
,这对postgres doc来说非常糟糕。所以你需要以某种方式安全地关闭postgres,使用preStop
钩子可以。Kubernetes
这是您的pod的确切时间顺序:
1.从Pod控制器设置
state=Terminating
terminationGracePeriodSeconds
计时器启动(默认值为30秒)preStop
挂钩:pg_cli ...
SIGTERM
发送:Postgres不接受新连接terminationGracePeriods
(可从yaml配置)1.如果应用程序仍处于活动状态,则发送
SIGKILL
波斯格雷斯
对于
pg_cli
命令,您可以参考此摘要,对您最有用的命令看起来像-m fast
。SIGTERM
:SIGINT
:SIGTERM
到现有的服务器进程(?)他们会立即退出SIGQUIT
:SIGQUIT
发送给所有子进程,如果它们在5秒内没有终止,则发送SIGKILL