问题 僵尸进程 僵尸进程是指完成执行(通过exit系统调用,或运行时发生致命错误或收到终止信号所致),但在操作系统进程表中仍然有一个表项,处于“终止状态”的进程。...的关系 现在有很多人使用docker,只在容器里面运行一个进程。...大多数情况下,这个进程并不会有init进程的行为,也就是说,这个进程并不会reap收养的进程,而是期望init进程来做这件事,这种做法是合理的。 来看一个具体的例子。...在其他的情况下,这个问题可能也存在。大家经常将第三方的应用程序跑在docker容器里,比如PostgreSQL,和上面一样,这个进程也是容器内的唯一进程。...不过,这个办法有一个关键问题:不能正确处理信号。对bash发送一个SIGTERM信号,bash会终止,但是并不会发送SIGTERM给其子进程。 当bash程序终止时,内核会停止整个容器和其中的进程。
Docker 和子进程“僵尸化”问题 初始进程的责任:“收割”“僵尸进程” Unix 的进程之间是树状结构的关系。每个进程都可以派生出子进程,而除了最顶端的进程之外,也都会有一个父进程。...这些程序又可能会派生出它们自己的子进程。 ? 这一部分并没有什么问题。但问题在于当一个进程终止时,会发生什么?...对 Linux waitpid 的文档引用如下: "在“僵尸进程”在被父进程“等待”以彻底消除之前,其仍然会被记录在内核进程表中。而当该表被写满后,新的进程将无法被创建。"...对 Docker 的影响 这个问题会如何对 Docker 产生怎样的影响?我们可以看到很多人只在他们的容器中跑一个进程,而且也认为只需要跑这么一个进程就足够了。...但此时 grep 程序并不会受到影响仍然继续执行,当其执行结束时,就变成了一个“僵尸进程”并由初始进程(即 web 服务器)「收养」。
每个Docker容器都是一个PID命名空间,这意味着容器中的进程与主机上的其他进程是隔离的。PID命名空间是一棵树,从PID 1开始,通常称为init。...注意:当你运行一个Docker容器时,镜像的ENTRYPOINT就是你的根进程,即PID 1(如果你没有ENTRYPOINT,那么CMD就会作为根进程,你可能配置了一个shell脚本,或其他的可执行程序...docker stop命令执行后,容器会有一个关闭的时限,默认为10秒,超过十秒则用kill强制关闭。...换句话说,给 Bash发送SIGTERM信号终止时,会等待十秒钟,然后被内核强制终止包含所有进程的整个容器。这些进程通过 SIGKILL 信号不正常地终止。...为什么docker中会有僵尸进程? 使用容器的理想境界是一个容器只启动一个进程,但这在现实应用中有时是做不到的。
当遇到特殊情况而无法关闭容器时,还可以使用 docker kill 命令强制终止容器,示例代码如下: 以上示例使用 docker kill 命令强制终止了容器。...docker container prune 会直接删除所有处于终止状态的容器,为了防止用户的误操作,将有用的容器删除,命令执行时会有警告信息与询问信息。...如果不对容器使用的资源进行限制,那么容器对宿主机资源的消耗可能导致其他容器或进程不能够正常运行,严重时可能导致服务完全不可用。...任何进程都有可能被终止,包括 Docker 和其他重要的应用程序。如果终止了系统关键进程,可能导致整个系统瘫痪。 设置限制内存上限虽然能保护主机,但是也可能会导致容器里的服务运行不畅。...下面测试内存使用超出限额的情况,实例代码如下: 从以上示例中可以看到,容器使用的内存超过了限额,容器里的进程被终止掉了,其中,signal 9 就是终止进程信号,最后容器退出。
容器 镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。...注:容器是否会长久运行,是和 docker run 指定的命令有关,和 -d 参数无关。 使用 -d 参数启动后会返回一个唯一的 id。...可以在伪终端中利用 ps 或 top 来查看进程信息。 终止容器 可以使用 docker container stop 来终止一个运行中的容器。...此外,当 Docker 容器中指定的应用终结时,容器也自动终止。 用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。...此外,docker container restart 命令会将一个运行态的容器终止,然后再重新启动它。 进入容器 在使用 -d 参数时,容器启动后会进入后台。
SIGSEGV 由以下代码表示: 在 Unix/Linux 中,SIGSEGV 是操作系统信号 11 在 Docker 容器中,当 Docker 容器由于 SIGSEGV 错误而终止时,它会抛出退出码...当进程尝试使用 MMU 未分配给它的内存地址时,会发生 SIGSEGV 信号或分段错误。...操作系统执行的其他操作 除了终止进程外,操作系统还可以生成 core 文件来辅助调试,也可以执行其他平台相关的操作。...相反,当容器被发现执行内存违规时,Kubernetes 节点上的主机可以触发 SIGSEGV。然后容器终止,Kubernetes 检测到这一点,并可能根据 pod 配置尝试重新启动它。...当 Docker 容器被 SIGSEGV 信号终止时,它会抛出退出码 139。
当容器终止时,容器引擎使用退出码来报告容器终止的原因。...)容器使用 abort() 函数自行中止137立即终止 (SIGKILL)容器被操作系统通过 SIGKILL 信号终止139分段错误 (SIGSEGV)容器试图访问未分配给它的内存并被终止143优雅终止...通常,当您运行 docker pause 命令时会发生这种情况 Exited:Docker 容器已经被终止,通常是因为容器的进程被杀死了 当一个容器达到 Exited 状态时,Docker 会在日志中报告一个退出码...例如,在 Docker 中,尝试 docker start 而不是 docker run; 测试您是否能够使用相同的用户名或上下文在主机上运行其他容器。...可能的原因是: 当通过容器引擎杀死容器时触发,例如使用 docker kill 命令时; 由 Linux 用户向进程发送 kill -9 命令触发; 在尝试终止容器并等待 30 秒的宽限期后由 Kubernetes
但是,谈论到如何停掉运行中的docker容器并正确的终止其中的程序,这就成为一个非常值得讨论的话题了。...场景C:再比如现在流行的微服务架构中,一般会有服务发现的机制,也即每一个微服务在启动之后,都会主动把自己的地址信息注册到服务发现模块当中,让其他的服务可以知道自己的存在。...如上的各种场景中,都要求打包在容器中的应用程序能够被优雅的终止(也即gracefully shutdown),这种gracefully shutdown的方式,允许程序在容器被停止的时候,有一定时间做一些后续处理操作...stop命令执行的时候,会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行...总结 用docker kill命令,可以简单粗暴的终止docker容器中运行的程序,但是想要优雅的终止掉的话,我们需要使用docker stop命令,并且在程序中多花一些功夫来处理系统信号,这样能保证程序不被粗暴的终止掉
综述 当Node.js应用程序运行在设置了内存限制的容器中时(使用docker --memory选项或者系统中的其他任意标志),请使用--max-old-space-size选项以确保Node.js...因此,理论上,当设置--max-old-space-size内存限制大于容器内存时,期望应用程序应直接被OOM(Out Of Memory)终止。 实际上,这可能不会发生。...为什么?当活动内存达到容器设置限制时,并且swap space还有空间时,一些旧内存片段将被推送到swap space并可供同一进程使用。...但正如您在上面的示例中看到的,原因是应用程序可能无法使用标志访问JavaScript堆集的全长。 请记住,当您使用的内存多于容器中可用的内存时,无法保证应用按期望行为方式运行。为什么?...如果容器中不存在其他活动进程,将此值用作容器的内存限制。该值上浮10%以上会更加安全。
前言 当检查你的 Kubernetes 集群的节点时,在节点上执行 docker ps 命令,你可能会注意到一些被称为“暂停”(pause)的容器,例如: ?...init 进程的其中一个作用是当某个子进程由于父进程的错误退出而变成了“孤儿进程”,便会被 init 进程收养并在该进程退出时回收资源。...同时,init 进程必须拥有“信号屏蔽”功能,不能处理某个信号逻辑,从而防止 init 进程被误杀。所以不是随随便便一个进程都能当 init 进程的。...当在主机上发送 SIGKILL 或者 SIGSTOP(也就是 docker kill 或者 docker stop)强制终止容器的运行时,其实就是在终止容器内的 init 进程。...但是,Nginx 并不是设计用来作为一个 init 进程运行并收割僵尸进程的。这意味着将会有很多这种僵尸进程,并且这种情况将持续整个容器的生命周期。
什么是容器退出码 当容器终止时,容器引擎使用退出码来报告容器终止的原因。...通常,当您运行 docker pause 命令时会发生这种情况 Exited:Docker 容器已经被终止,通常是因为容器的进程被杀死了 当一个容器达到 Exited 状态时,Docker 会在日志中报告一个退出码...例如,在 Docker 中,尝试 docker start 而不是 docker run; 测试您是否能够使用相同的用户名或上下文在主机上运行其他容器。...可能的原因是: 当通过容器引擎杀死容器时触发,例如使用 docker kill 命令时; 由 Linux 用户向进程发送 kill -9 命令触发; 在尝试终止容器并等待 30 秒的宽限期后由 Kubernetes...如果上述操作失败,则 bash 进入容器并检查有关 entrypoint 进程及其失败原因的日志或其他线索。 哪些 Kubernetes 错误与容器退出代码有关?
当利用docker run来创建容器时,Docker在后台运行的标准操作包括: 检查本地是否存在指定的镜像,不存在就从公有镜像仓库(或者镜像加速器)下载 利用镜像创建并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层...从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 从地址池配置一个ip地址给容器 执行用户指定的应用程序(Dockerfile中通过CMD指令设置的程序或者启动容器时指定的程序) 执行完毕后容器被终止...三.终止容器 可以使用docker container stop来终止一个运行中的容器。...$ docker stop c421520d8484 c421520d8484 此外,当Docker容器中指定的应用终结时,容器也自动终止。...需要区分容器"在后台运行"和"长久运行"这2个概念的区别: 后台运行: Docker容器本身只是一个进程,那么这个进程在前台运行和在后台运行与其他进程没有区别,通过"-d"参数控制; 长久运行: 长久运行是指
如果过程不在 Docker 容器中,通过 SIGTERM 信号终止的容器在其日志中显示退出码 143。...SIGTERM 与 SIGKILL SIGTERM(Unix 信号 15)是一个“礼貌”的 Unix 信号,默认情况下会终止进程,但可以被进程处理或忽略。...退出码 143 和 137 与 Docker 容器中的 SIGTERM 和 SIGKILL 一一对应: Docker 退出码 143 – 表示容器收到底层操作系统的 SIGTERM Docker 退出码...使用此命令发送 SIGKILL:kill -9 [ID] 处理僵尸进程 当您列出正在运行的进程时,您可能会发现在 CMD 列中显示 defunct 的进程。这些是没有正确终止的僵尸进程。...问题:NGINX 没有在 SIGTERM 上执行优雅终止 如果你使用的是官方的 NGINX Ingress Controller,当 controller Pod 被终止时,Kubernetes 会像往常一样发送一个
---pod 是什么Pod 是一组互相协作的容器,是我们可以在 Kubernetes 中创建和管理的最小可部署单元。同一个 pod 内的容器共享网络和存储,并且作为一个整体被寻址和调度。...为什么需要 pod思考以下问题,为什么不直接在 kubernetes 部署容器?为什么需要把多个容器视作一个整体?为什么不使用同一个容器内运行多个进程的方案?...当一个应用包含多个进程且通过IPC方式通讯,需要运行在同一台主机。...但是 container 的设计是每个容器运行一个单独的进程,除非进程本身会创建多个子进程,当然如果你选择在同一个容器内运行多个没有联系的进程的话,那么需要自己来管理其他进程,包括每个进程的生命周期(重启挂掉的进程...Succeeded: Pod 中的所有容器都已成功终止,不会重新启动。Failed:Pod 中的所有容器都已终止,并且至少有一个容器因故障而终止。也就是说,容器要么以非零状态退出,要么被系统终止。
当旧的 EC2 实例被终止时,在这些 EC2 实例上运行的服务 Pod 也会被终止。如果 Pod 的终止过程没有得到妥善处理,可能会导致用户请求处理失败。...2优雅终止应用程序 在这个过程中,首先要优雅地终止应用程序。终止一个 Pod 可能会导致 Pod 中的 Docker 容器突然终止,在 Docker 容器中运行的进程也会突然终止。...这可能会导致正在处理中的请求被终止,最终导致当时正在调用应用程序的上游服务调用失败。 当一个 EC2 实例在打补丁过程中被终止,该实例上的 Pod 也将被驱逐。...Docker 容器中的进程 (PID 1) 发送一个 SIGTERM 信号,并以 1 秒为等待时间间隔,直到进程成功终止。...我们把它叫作 node-drainer),当发生特定的 ASG 生命周期钩子事件时被触发。
当利用 docker run 来创建容器时,Docker 在后台运行的标准操作包括: 检查本地是否存在指定的镜像,不存在就从公有仓库下载 利用镜像创建并启动一个容器 分配一个文件系统,并在只读的镜像层外面挂载一层可读写层...从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去 从地址池配置一个 ip 地址给容器 执行用户指定的应用程序 执行完毕后容器被终止 可以利用 docker start 命令,直接将一个已经终止的容器启动运行...我们用 ps 或 top 在伪终端中查看进程信息,可以看到只有我们运行的进程,没有其他花里胡哨的(上图最后一条命令) 试一试如下命令 cat /etc/hosts ip a ps -aux cd ~ &...容器是否会长久运行,是和docker run指定的命令有关,和 -d 参数无关 在使用 -d 参数时,容器启动后会进入后台。...可以使用 docker rm 来删除一个处于终止状态的容器。如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。
这个要从linux内核说起 在linux操作系统中,当内核初始化完毕之后,会启动一个init进程,这个进程是整个操作系统的第一个用户进程,所以它的进程ID为1,也就是我们常说的PID1进程,然后所有的用户态进程...当一个进程结束了运行或在半途中终止了运行,那么内核就需要释放该进程所占用的系统资源。这包括进程运行时打开的文件,申请的内存等。...但是,这里要注意的是,进程表项并没有随着进程的退出而被清除,它会一直占用内核的内存。为什么会有这么奇怪的行为呢?...了解了linux的PID1,接着来看下容器中的PID1进程 熟悉docker都知道,docker容器并不是一个完整的linux的操作系统,它也没什么内核初始化过程,更没有像init(1)这样的初始化过程...可以看到,就是Dockerfile中指定的CMD那个进程,注意:如果你启动容器的时候,指定了命令,会覆盖CMD,也就是CMD是条默认启动的命令参数,如果启动容器时指定了命令,会覆盖,当Dockerfile
问题就在这里,这些基础镜像的 init 系统[2]也被抹掉了,这就是问题的根源! init 系统有以下几个特点: 它是系统的第一个进程,负责产生其他所有用户进程。...Docker 容器停止过程 对于容器来说,init 系统不是必须的,当你通过命令 docker stop mycontainer 来停止容器时,docker CLI 会将 TERM 信号发送给 mycontainer...要想解决这个问题,就要往脚本中添加信号处理代码,让它捕获到 SIGTERM 信号时就终止进程: #!...最后一个问题:如果移除 popcorn.sh 中对 SIGTERM 信号的处理逻辑,容器会在我们执行停止命令后立即终止吗? 答案是肯定的。...在 Linux 系统中,PID 1 和其他进程不太一样,准确地说应该是 init 进程和其他进程不一样,它不会执行与接收到的信号相关的默认动作,必须在代码中明确实现捕获处理 SIGTERM 信号的逻辑,