如何在Kubernetes中安全重启PostgreSQL容器?

js4nwp54  于 2023-03-29  发布在  Kubernetes
关注(0)|答案(1)|浏览(186)

我有一个小的爱好网站,我想在我的服务器上发布。我选择使用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多次重启,没有问题。而在第四次重启时崩溃了。

db2dz4w8

db2dz4w81#

当然,最好的做法是使用像cloudnative-pgpostgres-operator这样的操作符,但它们非常大,对于简单的工作负载可能有更多的功能。
溶液
将以下内容添加到您的pod规格

preStop:
  exec:
    command: ["/usr/local/bin/pg_ctl stop -D /var/lib/postgresql/data -w -t 60 -m fast"]

解释

基本上,当你杀死一个pod时,Kubernetes会给你的pod发送SIGTERM信号,并给你30秒的时间,之后它会发送SIGKILL。当postgres接收到SIGTERM时,它不会接受网络连接,但它不会终止现有的终止,所以任何客户端都会阻止db的终止,30秒后,pod将收到SIGKILL,这对postgres doc来说非常糟糕。所以你需要以某种方式安全地关闭postgres,使用preStop钩子可以。

Kubernetes

这是您的pod的确切时间顺序:
1.从Pod控制器设置state=Terminating

  1. terminationGracePeriodSeconds计时器启动(默认值为30秒)
  2. preStop挂钩:pg_cli ...
  3. SIGTERM发送:Postgres不接受新连接
  4. k8s等待直到terminationGracePeriods(可从yaml配置)
    1.如果应用程序仍处于活动状态,则发送SIGKILL

波斯格雷斯

对于pg_cli命令,您可以参考此摘要,对您最有用的命令看起来像-m fast
SIGTERM

  • “智能关机模式”
  • 不允许新连接
  • 让现有连接继续

SIGINT

  • “快速关机模式”
  • 不允许新连接
  • 发送SIGTERM到现有的服务器进程(?)他们会立即退出

SIGQUIT

  • “立即关闭模式”
  • SIGQUIT发送给所有子进程,如果它们在5秒内没有终止,则发送SIGKILL

相关问题