问题描述
我已根据 Azure Oss Db Tools Pgbouncer Sidecar 文档在 Azure Kubernetes 中的一个 Pod 中将 Pgbouncer 配置为边车模式。它具有以下容器生命周期钩子:
lifecycle:
preStop:
exec:
command: ["/bin/sh","-c","killall -INT pgbouncer && sleep 120"]
我相信此命令的预期目的是等待 120 秒,直到任何正在运行的查询完成。
为了了解它的作用,我在 Pgbouncer 容器内打开了两个交互式 shell。在第一个 shell 中,我执行了 killall
命令,在第二个 shell 中,我多次执行了 ps
命令。
第一个外壳:
/ $ ps
PID USER TIME COMMAND
1 postgres 0:00 /usr/bin/pgbouncer /etc/pgbouncer/pgbouncer.ini
6 postgres 0:00 /bin/sh
30 postgres 0:00 ps
/ $
/ $
/ $ killall -INT pgbouncer && sleep 120
第二个外壳:
/ $ ps
PID USER TIME COMMAND
1 postgres 0:00 /usr/bin/pgbouncer /etc/pgbouncer/pgbouncer.ini
6 postgres 0:00 /bin/sh
33 postgres 0:00 /bin/sh
40 postgres 0:00 sleep 120
41 postgres 0:00 ps
/ $
/ $
/ $ ps
PID USER TIME COMMAND
1 postgres 0:00 /usr/bin/pgbouncer /etc/pgbouncer/pgbouncer.ini
6 postgres 0:00 /bin/sh
33 postgres 0:00 /bin/sh
42 postgres 0:00 ps
120 秒后,Pgbouncer 主进程仍在运行(参见第二个 shell 的输出)。我认为这应该终止我的两个终端会话,因为它应该杀死 Pgbouncer 进程 (PID
= 1
) 并停止容器。
如果我尝试使用以下命令杀死:
/ $ kill 1
/ $ command terminated with exit code 137
我看到我的两个终端会话都立即终止,容器也停止了。
我想了解我们是否真的需要这个生命周期钩子,因为它不能正常工作?还是我在试图理解它的作用时犯了什么错误?
感谢您的帮助! ?
解决方法
这里有区别。如果没有指定信号,killall -INT
会发送 INT 信号,而 kill
会发送 TERM 信号。您可以使用 kill -INT 1
再试一次,看看它是否得到相同的行为。我认为 pgbouncer
过程也在捕捉 INT。
这里是对 site 的引用:
int cf_shutdown; /* 1 - wait for queries to finish,2 - shutdown immediately */
...
static void handle_sigterm(evutil_socket_t sock,short flags,void *arg)
{
log_info("got SIGTERM,fast exit");
/* pidfile cleanup happens via atexit() */
exit(1);
}
static void handle_sigint(evutil_socket_t sock,void *arg)
{
log_info("got SIGINT,shutting down");
sd_notify(0,"STOPPING=1");
if (cf_reboot)
die("takeover was in progress,going down immediately");
if (cf_pause_mode == P_SUSPEND)
die("suspend was in progress,going down immediately");
cf_pause_mode = P_PAUSE;
cf_shutdown = 1;
}
当给出 INT 信号时,Pgbouncer 停止处理任何更多的查询,而 TERM 信号将立即终止进程。