热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

优雅地关闭kubernetes中的nginx

为什么80%的码农都做不了架构师?##SIGINTSIGTERMSIGKILL区别三者都是结束终止进程运行。###1.SIGINTSIGTERM区别前者与字符c

为什么80%的码农都做不了架构师?>>>   hot3.png

##SIGINT SIGTERM SIGKILL区别 三者都是结束/终止进程运行。 ###1.SIGINT SIGTERM区别 前者与字符ctrl+c关联,后者没有任何控制字符关联。 前者只能结束前台进程,后者则不是。 ###2.SIGTERM SIGKILL的区别 前者可以被阻塞、处理和忽略,但是后者不可以。KILL命令的默认不带参数发送的信号就是SIGTERM.让程序有好的退出。因为它可以被阻塞,所以有的进程不能被结束时,用kill发送后者信号,即可。即:kill-9 进程号。

输入图片说明

##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 beone of: stop, quit, reopen, reload.The following table shows the corresponding system signals.stop SIGTERMquit SIGQUITreopen SIGUSR1reload SIGHUP

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

##使用kubernetes Lifecycle Hooks优雅退出nginx

kind: Deployment
metadata:name: nginx-demonamespace: scmlabels:app: nginx-demo
spec:replicas: 1template:metadata:labels:app: nginx-demospec:containers:- name: nginx-demoimage: library/nginx-demoimagePullPolicy: IfNotPresentlifecycle:preStop:exec:# nginx -s quit gracefully terminate while SIGTERM triggers a quick exitcommand: ["/usr/local/openresty/nginx/sbin/nginx","-s","quit"]env:- name: PROFILEvalue: "test"ports:- name: httpcontainerPort: 8080

##题外 如何优雅地关闭java应用

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

##doc

  • uinx 信号 SIGINT SIGTERM SIGKILL区别
  • 优雅的终止docker容器
  • Termination of Pods
  • Issues with running as PID 1 in a Docker container.
  • Docker and the PID 1 zombie reaping problem
  • Docker 和 PID 1 僵尸进程问题
  • Docker系统中僵尸进程问题
  • kubernetes-chinese-docs-pods
  • Nginx 源代码笔记 - 运维命令
  • Does nginx have a soft quit?
  • Container Lifecycle Hooks
  • Graceful shutdown of pods with Kubernetes
  • Gracefully stopping a Java process in a pod in Kubernetes?
  • How can I ensure graceful scaling in kubernetes?
  • Do Kubernetes pods still receive requests after receiving SIGTERM?
  • Deleting pods and other resources with graceful shutdown

转载于:https://my.oschina.net/go4it/blog/830950


推荐阅读
  • Nginx使用AWStats日志分析的步骤及注意事项
    本文介绍了在Centos7操作系统上使用Nginx和AWStats进行日志分析的步骤和注意事项。通过AWStats可以统计网站的访问量、IP地址、操作系统、浏览器等信息,并提供精确到每月、每日、每小时的数据。在部署AWStats之前需要确认服务器上已经安装了Perl环境,并进行DNS解析。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • 本文介绍了如何使用PHP向系统日历中添加事件的方法,通过使用PHP技术可以实现自动添加事件的功能,从而实现全局通知系统和迅速记录工具的自动化。同时还提到了系统exchange自带的日历具有同步感的特点,以及使用web技术实现自动添加事件的优势。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 本文讨论了clone的fork与pthread_create创建线程的不同之处。进程是一个指令执行流及其执行环境,其执行环境是一个系统资源的集合。在调用系统调用fork创建一个进程时,子进程只是完全复制父进程的资源,这样得到的子进程独立于父进程,具有良好的并发性。但是二者之间的通讯需要通过专门的通讯机制,另外通过fork创建子进程系统开销很大。因此,在某些情况下,使用clone或pthread_create创建线程可能更加高效。 ... [详细]
  • 31.项目部署
    目录1一些概念1.1项目部署1.2WSGI1.3uWSGI1.4Nginx2安装环境与迁移项目2.1项目内容2.2项目配置2.2.1DEBUG2.2.2STAT ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 深入解析Linux下的I/O多路转接epoll技术
    本文深入解析了Linux下的I/O多路转接epoll技术,介绍了select和poll函数的问题,以及epoll函数的设计和优点。同时讲解了epoll函数的使用方法,包括epoll_create和epoll_ctl两个系统调用。 ... [详细]
  • 目录浏览漏洞与目录遍历漏洞的危害及修复方法
    本文讨论了目录浏览漏洞与目录遍历漏洞的危害,包括网站结构暴露、隐秘文件访问等。同时介绍了检测方法,如使用漏洞扫描器和搜索关键词。最后提供了针对常见中间件的修复方式,包括关闭目录浏览功能。对于保护网站安全具有一定的参考价值。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • mac php错误日志配置方法及错误级别修改
    本文介绍了在mac环境下配置php错误日志的方法,包括修改php.ini文件和httpd.conf文件的操作步骤。同时还介绍了如何修改错误级别,以及相应的错误级别参考链接。 ... [详细]
author-avatar
Carmen果果时代
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有