三者都是结束/终止进程运行。html
前者与字符ctrl+c关联,后者没有任何控制字符关联。
前者只能结束前台进程,后者则不是。java
前者能够被阻塞、处理和忽略,可是后者不能够。KILL命令的默认不带参数发送的信号就是SIGTERM.让程序有好的退出。由于它能够被阻塞,因此有的进程不能被结束时,用kill发送后者信号,便可。即:kill-9 进程号。nginx
当咱们用docker stop命令来停掉容器的时候,docker默认会容许容器中的应用程序有10秒的时间用以终止运行。git
在docker stop命令执行的时候,会先向容器中PID为1的进程(main process
)发送系统信号SIGTERM,而后等待容器中的应用程序终止执行,若是等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。在容器中的应用程序,能够选择忽略和不处理SIGTERM信号,不过一旦达到超时时间,程序就会被系统强行kill掉,由于SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。github
默认状况下,docker kill命令不会给容器中的应用程序有任何gracefully shutdown的机会。它会直接发出SIGKILL的系统信号,以强行终止容器中程序的运行。web
与docker stop命令不同的地方在于,docker kill没有任何的超时时间设置,它会直接发送SIGKILL信号,以及用户经过signal参数指定的其余信号。docker
docker stop命令,更相似于Linux系统中的kill命令,两者都是发送系统信号SIGTERM。而docker kill命令,更像是Linux系统中的kill -9或者是kill -SIGKILL命令,用来发送SIGKILL信号,强行终止进程。api
process ID为1的进程,一般是UNIX init进程, 在操做系统中有重要的做用:每当一个进程退出了,若是它还有子进程存在,则该子进程变成了孤儿进程,init进程过来接管。Unix被设计为这样一种方式,父进程必须明确地“等待”子进程终止,以便收集它的退出状态。bash
子进程在结束后,内核仍然会为其维护一个基本的结构,保存其pid, 退出缘由和状态等信息,父进程经过waitpid系统调用,能够得到这些信息。若是父进程没有调用waitpid,这些状态信息会一直保留,变成所谓僵尸进程。若是子进程后于父进程结束,通常来讲, init进程会负责这些孤儿进程。服务器
根据通常一个容器只运行一个进程的原则,对于一个web服务,它在容器中运行时的pid是1,假设它调用了bash的cgi脚本,而这个脚本又调用了grep,一段时间后,cgi脚本由于某种缘由超时,web服务开始尝试杀死它,可是grep却并未受到影响,所以变成了孤儿进程。这时,pid=1的web服务应该能接管,可是绝大多数的web服务并无init那样的能力,因此grep就变成了僵尸进程。
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进程的发送信号以彻底管理操做:使用Nginx进程的 -s 选项或者直接使用系统命令kill发送信号给master进程。使用 -s 选项时,nginx会自动查找运行中的master进程ID(master进程负责接收并处理信号,同时根据不一样的信号,对全部工做进程完成不一样的管理操做).
SIGINT和SIGTERM做用同样,用于强制 Nginx进程退出;master进程接到强制退出信号时,会向全部工做进程发送强制退出信号,若是工做进程未能及时退出,master使用计时器重复发送强制信号,计时器触发时会发送SIGALRM信号;SIGIO信号被Nginx显式忽略;SIGCHLD信号告诉 master进程有工做进程退出,须要完成资源回收或者重启工做进程的工做。
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信号强制终止工做进程。
-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 — 从新打开日志文件
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;"]