在Docker中,进程管理的基础是Linux内核的PID命名空间技术。在不同的PID命名空间下,可以有相同的PID。

Linux内核为所有的PID命名空间维护了一个树状的数据结构,最顶层是系统初始化时创建的root namespace(根命名空间), 父节点可以看到子节点中的进程,并可以通过信号等方式对子节点中的进程产生影响。反过来,子节点不能看到父节点名空间中的任何内容,也不可能通过kill或ptrace影响父节点或其他名空间中的进程。

在docker中有一个很特殊的进程——PID为1的进程,这也是docker的主进程,通过Dockerfile中的 ENTRYPOINT 和/或 CMD指令指定。当主进程退出的时候,容器所拥有的PIG命名空间就会被销毁,容器的生命周期也会结束docker最佳实践建议的是一个container一个service,并不强制要你一个container一个线程。有的服务,会催生更多的子进程,比如Apache和uwsgi,这是完全OK的。

PID1进程需要对自己创建的子进程负责,当主进程没有设计好,不能优雅地让子进程退出,就会照成很多问题,比如数据库container,如果处理数据的进程没有优雅地退出,可能会照成数据丢失。如果很不幸,你的主进程就是这种管理不了子进程的那种,docker提供了一个小工具,帮助你来完成这部分内容。你只需要在run创建container的时候提供一个—init flag就行,docker就会手动为你处理好这些问题。

来看一个实例

在docker中,对于CMD和 ENTRYPOINT,支持两种进程执行方式:exec和shell。

shell的格式是:

CMD "executable param1 param2"

最终PID1进程将是: /bin/sh -c ”executable param1 param2”

Exec的格式是:

CMD ["executable","param1","param2"]

最终的PID1进程是: executable param1 param2

现在有两个镜像,Dockerfile分别如下:

  • 镜像redis:shell
FROM ubuntu:14.04
RUN apt-get update && apt-get -y install redis-server && rm -rf /var/lib/apt/lists/*
EXPOSE 6379
CMD "/usr/bin/redis-server"

  • 镜像redis:exec
FROM ubuntu:14.04
RUN apt-get update && apt-get -y install redis-server && rm -rf /var/lib/apt/lists/*
EXPOSE 6379
CMD ["/usr/bin/redis-server"]docker run -d --name myredis1 redis:shell
docker run -d --name myredis2 redis:exec

那个docker镜像更好一点呢?

我们前面讲过,PID1进程(主进程)需要对自己的子进程负责,对于redis:shell,它产生的PID1进程是

/bin/sh -c "/usr/bin/redis-server"

也就是说,是/bin/sh这个进程,不是/usr/bin/redis-server!/usr/bin/redis-server只是它创建的一个子进程!

执行命令

docker exec myredis1 ps -ef

可以验证这种猜测

通过exec方式运行的container的主进程则是我们所期望的。

你可能会觉得,这有什么大不了的呢,问题出现当我们停止container的时候。

停止redis:shell

docker stop myredis1
docker logs myredis1

Stop的时候,docker明显停顿了一段时间,而且查看日志可以看出,redis没有做任何保存数据库的操作,直接被强制退出了。这期间发生了什么?首先,运行stop命令会向容器发送 SIGTERM信号,告诉主进程:你该退出了,感觉收拾收拾。但是,这里的主进程是/bin/sh啊,它怎么可能会有处理redis进程退出的机制?所以redis进程不会马上退出。 Docker Daemon等待一段时间之后(默认是10s),发现容器还没有完全退出,这时候就会发送 SIGKILL,将容器强行杀死。在这过程中,redis进程完全不知道自己该退出了,所以他没有做任何收尾的工作。

停止redis:exec

docker stop myredis2
docker logs myredis2

这一次stop的时候是立即生效了,没有卡顿延迟现象,从输出来看,redis进行了shutdown的操作,把该持久化的数据都保存到磁盘了。因为这时候的PID1进程是

/usr/bin/redis-server

它是能够正确处理SIGTERM信号的。这才是我们所期望的。

总结一下

Docker的主进程(PID1进程)是一个很特殊的存在,它的生命周期就是docker container的生命周期,它得对产生的子进程负责,在写Dockerfile的时候,务必明确PID1进程是什么。

关注我的微信公众号

主进程退出后子进程还会存在吗?_[docker]从一个实例,一窥docker进程管理相关推荐

  1. 主进程退出后子进程还会存在吗?_【干货】Linux进程模型 全解

    关注.星标公众号,直达精彩内容 ID:嵌入式情报局 作者:情报小哥 1进程与程序 01 什么是进程 ?  什么是进程 ? 进程(process)是具有独立功能的程序单次运行,是操作系统进行资源分配的基 ...

  2. linux父进程发出退出信号,为什么prctl没有如小弟我所预期的设置一个父进程退出发给子进程信号...

    为什么prctl没有如我所预期的设置一个父进程退出发给子进程信号? 我写了一个小程序,在fork出的子进程中使用prctl,设置父进程退出后自动发送给子进程退出信号. #include #includ ...

  3. 进程退出后占用的内存都去哪儿了?

    本文是<深入理解操作系统>第四章,从本章开始将开启第一个重要的主题:进程,彻底理解进程对程序员来说是极为重要的,本章就从程序员的角度来讲解到底什么是进程.操作系统是如何实现进程的.本文承接 ...

  4. python主进程退出时子进程也退出_主进程被杀死时,如何保证子进程同时退出,而不变为孤儿进程(三)...

    之前两篇文章讨论了进程意外退出时,如何杀死子进程,这节我们研究下在使用进程池multiprocessing.Pool时,如何保证主进程意外退出,进程池中的worker进程同时退出,不产生孤儿进程.如果 ...

  5. docker 主进程 日志_[docker]从一个实例,一窥docker进程管理

    在Docker中,进程管理的基础是Linux内核的PID命名空间技术.在不同的PID命名空间下,可以有相同的PID. Linux内核为所有的PID命名空间维护了一个树状的数据结构,最顶层是系统初始化时 ...

  6. 苹果id退出后数据还在吗_答疑你的手机连接WiFi后,会关闭移动数据吗?

    十万人测评俱乐部Q群:631042704 ZEALER极客交流Q群:414894623 最近几天,深圳的高温天气让人十分抓狂,稍微动一动就大汗淋漓.在这种烧烤天里,最舒服的事,莫过于在空调房里连着Wi ...

  7. 父进程退出,保证子进程交由init。

    最近写代码遇到父进程fork出的子进程,父进程退出后子进程也退出.而要求的实现机制是,父进程启动子进程后,保证子进程能够继续运行,可以保证另一个进程启动能够和这个子进程进行通讯操作. 规避这个问题的方 ...

  8. Linux中的进程控制:进程退出、孤儿进程、僵尸进程 概念及代码示例 [Linux高并发服务器开发]

    目录 一.进程退出 二.孤儿进程 三.僵尸进程 一.进程退出 #include <stdlib.h> void  exit ( int status ); #include <uni ...

  9. 进程退出以及内存释放

    进程退出表示进程即将结束运行. 1.正常退出 在main函数中执行return. 调用exit函数. 调用_exit函数. 2.异常退出 调用abort函数 进程收到某个信号,该信号使程序终止. 进程 ...

最新文章

  1. strtok()函数详解
  2. 【iCore3 双核心板_FPGA】实验二十七:基于SDRAM的TFT驱动器的设计
  3. Knockout2.x:ko.dataFor()、ko.contextFor()使用
  4. MVC %%与%=%与区别
  5. QT的QStylePainter类的使用
  6. HDU 3966-Aragorn's Story 树链剖分+树状数组
  7. Abp + Grpc 如何实现用户会话状态传递
  8. thinkcell插件_PPT大神私藏的5款插件,用好它们,小白也能快速做出精美的PPT
  9. android listview 选中状态,Android:在ListView打开时将项目设置为选中状态?
  10. Java-第三章-从键盘输入整数判断是3和5的倍数!
  11. Visual Studio 2017 设置失败、安装失败的解决方法
  12. 如何用iMazing备份恢复贪婪洞窟
  13. Nacos 配置中心原理分Nacos 配置中心原理分析析
  14. ssl 2133 腾讯大战360#spfa#
  15. 二本学历,3年软件测试点点点,25K入职阿里巴巴
  16. 器件选型-墨水屏(电子纸)介绍
  17. ThingsBoard 二次开发之源码分析 5-如何接收 MQTT 连接
  18. android 基础培训ppt,Android基础之内部培训.ppt
  19. 将任意的十进制整数转换成任意R进制数(R在2-16之间)
  20. adb命令行 查看手机 ip

热门文章

  1. windows下linux下socket编程区别
  2. Vue系列:通过vue-router如何传递参数
  3. 空间闹钟-v1.6更新!
  4. UVA10494 If We Were a Child Again【大数除法】
  5. CCF NOI1066 素数对
  6. HDU2504 又见GCD【欧几里得算法】
  7. 冷知识 —— 物种大交换
  8. 广义逆高斯分布(Generalized Inverse Gaussian Distribution)及修正贝塞尔函数
  9. Boltzmann 玻尔兹曼机(BM)
  10. 内容联盟程序_英雄联盟可以偷看你的网页?你的账号密码还安全吗?