优雅地关闭kubernetes中的nginx

SIGINT SIGTERM SIGKILL区别

三者都是结束/终止进程运行。

1.SIGINT SIGTERM区别

前者与字符ctrl+c关联,后者没有任何控制字符关联。
前者只能结束前台进程,后者则不是。

2.SIGTERM SIGKILL的区别

前者可以被阻塞、处理和忽略,但是后者不可以。KILL命令的默认不带参数发送的信号就是SIGTERM.让程序有好的退出。因为它可以被阻塞,所以有的进程不能被结束时,用kill发送后者信号,即可。即:kill-9 进程号。

1-ZAZWGqxfJh59DsqQlFWakw.png

docker stop与docker kill

docker stop

当我们用docker stop命令来停掉容器的时候,docker默认会允许容器中的应用程序有10秒的时间用以终止运行。

在docker stop命令执行的时候,会先向容器中PID为1的进程(main process)发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。在容器中的应用程序,可以选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,因为SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。

docker kill

默认情况下,docker kill命令不会给容器中的应用程序有任何gracefully shutdown的机会。它会直接发出SIGKILL的系统信号,以强行终止容器中程序的运行。

与docker stop命令不一样的地方在于,docker kill没有任何的超时时间设置,它会直接发送SIGKILL信号,以及用户通过signal参数指定的其他信号。

docker stop命令,更类似于Linux系统中的kill命令,二者都是发送系统信号SIGTERM。而docker kill命令,更像是Linux系统中的kill -9或者是kill -SIGKILL命令,用来发送SIGKILL信号,强行终止进程。

关于pid为1的进程

process ID为1的进程,通常是UNIX init进程, 在操作系统中有重要的作用:每当一个进程退出了,如果它还有子进程存在,则该子进程变成了孤儿进程,init进程过来接管。Unix被设计为这样一种方式,父进程必须明确地“等待”子进程终止,以便收集它的退出状态。

子进程在结束后,内核仍然会为其维护一个基本的结构,保存其pid, 退出原因和状态等信息,父进程通过waitpid系统调用,可以获得这些信息。如果父进程没有调用waitpid,这些状态信息会一直保留,变成所谓僵尸进程。如果子进程后于父进程结束,一般来说, init进程会负责这些孤儿进程。

根据一般一个容器只运行一个进程的原则,对于一个web服务,它在容器中运行时的pid是1,假设它调用了bash的cgi脚本,而这个脚本又调用了grep,一段时间后,cgi脚本因为某种原因超时,web服务开始尝试杀死它,但是grep却并未受到影响,因此变成了孤儿进程。这时,pid=1的web服务应该能接管,但是绝大多数的web服务并没有init那样的能力,所以grep就变成了僵尸进程。

kubernetes的pod关闭机制

pod代表着一个集群中节点上运行的进程,让这些进程不再被需要,优雅的退出是很重要的(与粗暴的用一个KILL信号去结束,让应用没有机会进行清理操作)。用户应该能请求删除,并且在室进程终止的情况下能知道,而且也能保证删除最终完成。当一个用户请求删除pod,系统记录想要的优雅退出时间段,在这之前Pod不允许被强制的杀死,TERM信号会发送给容器主要的进程。一旦优雅退出的期限过了,KILL信号会送到这些进程,pod会从API服务器其中被删除。如果在等待进程结束的时候,Kubelet或者容器管理器重启了,结束的过程会带着完整的优雅退出时间段进行重试。

一个示例流程:

  • 1.用户发送一个命令来删除Pod,默认的优雅退出时间是30秒
  • 2.API服务器中的Pod更新时间,超过该时间Pod被认为死亡
  • 3.在客户端命令的的里面,Pod显示为"Terminating(退出中)"的状态
  • 4.(与第3同时)当Kubelet看到Pod标记为退出中的时候,因为第2步中时间已经设置了,它开始pod关闭的流程
  • 4.1如果该Pod定义了一个停止前的钩子,其会在pod内部被调用。如果钩子在优雅退出时间段超时仍然在运行,第二步会意一个很小的优雅时间断被调用
  • 4.2进程被发送TERM的信号
  • 5.(与第三步同时进行)Pod从service的列表中被删除,不在被认为是运行着的pod的一部分。缓慢关闭的pod可以继续对外服务,当负载均衡器将他们轮流移除。
  • 6.当优雅退出时间超时了,任何pod中正在运行的进程会被发送SIGKILL信号被杀死。
  • 7.Kubelet会完成pod的删除,将优雅退出的时间设置为0(表示立即删除)。pod从API中删除,不在对客户端可见。

默认情况下,所有的删除操作的优雅退出时间都在30秒以内。kubectl delete命令支持--grace-period=的选项,以运行用户来修改默认值。0表示删除立即执行,并且立即从API中删除pod这样一个新的pod会在同时被创建。在节点上,被设置了立即结束的的pod,仍然会给一个很短的优雅退出时间段,才会开始被强制杀死。

nginx与SIGTERM

有两种方式可以向正在运行的Nginx进程的发送信号以完全管理操作:使用Nginx进程的 -s 选项或者直接使用系统命令kill发送信号给master进程。使用 -s 选项时,nginx会自动查找运行中的master进程ID(master进程负责接收并处理信号,同时根据不同的信号,对所有工作进程完成不同的管理操作).

SIGINT和SIGTERM作用一样,用于强制 Nginx进程退出;master进程接到强制退出信号时,会向所有工作进程发送强制退出信号,如果工作进程未能及时退出,master使用计时器重复发送强制信号,计时器触发时会发送SIGALRM信号;SIGIO信号被Nginx显式忽略;SIGCHLD信号告诉 master进程有工作进程退出,需要完成资源回收或者重启工作进程的工作。

Nginx进程退出分为两种

  • master进程接到SIGQUIT信号时
    将此信号转发给工作进程。工作进程随后关闭监听端口以便不再接收新的连接请求,并闭空闲连接,等待活跃连接全部正常结速后,调用 ngx_worker_process_exit 退出。而 master 进程在所有工作进程都退出后,调用 ngx_master_process_exit 函数退出;

  • master进程接收到SIGTERM或者SIGINT信号时
    将信号转发给工作进程。工 作进程直接调用 ngx_worker_process_exit 函数退出。master进程在所有工作进程都退出后,调用ngx_master_process_exit 函数退出。另外,如果工作进程未能正常退出,master进程会等待1秒后,发送SIGKILL信号强制终止工作进程。

nginx的优雅退出

 -s signal      Send signal to the master process. The argument signal can be
                one of: stop, quit, reopen, reload.

                The following table shows the corresponding system signals.

                stop    SIGTERM
                quit    SIGQUIT
                reopen  SIGUSR1
                reload  SIGHUP

其中
stop — 快速关闭
quit — 优雅退出,执行完当前的请求后退出
reload — 重新加载配置文件
reopen — 重新打开日志文件

使用kubernetes Lifecycle Hooks优雅退出nginx

kind: Deployment
metadata:
  name: nginx-demo
  namespace: scm
  labels:
    app: nginx-demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx-demo
    spec:
      containers:
      - name: nginx-demo
        image: library/nginx-demo
        imagePullPolicy: IfNotPresent
        lifecycle:
          preStop:
            exec:
              # nginx -s quit gracefully terminate while SIGTERM triggers a quick exit
              command: ["/usr/local/openresty/nginx/sbin/nginx","-s","quit"]
        env:
          - name: PROFILE
            value: "test"
        ports:
          - name: http
            containerPort: 8080

题外

如何优雅地关闭java应用

command: ["/bin/bash", "-c", "PID=`pidof java` && kill -SIGTERM $PID && while ps -p $PID > /dev/null; do sleep 1; done;"]

doc

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 155,541评论 4 358
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 65,987评论 1 285
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 105,387评论 0 236
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,325评论 0 201
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,657评论 3 284
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,125评论 1 202
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,519评论 2 305
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,242评论 0 193
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,863评论 1 234
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,198评论 2 239
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,747评论 1 255
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,106评论 2 249
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,635评论 3 227
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,926评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,631评论 0 190
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,131评论 2 261
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,083评论 2 257

推荐阅读更多精彩内容