目录
一、docker终止容器的两种方式
Docker本身提供了两种终止容器运行的方式,docker stop与docker kill;
用docker stop命令来停掉容器的时候,docker默认会允许容器中的应用程序有10秒的时间用以终止运行。在docker stop命令执行的时候,会先向容器中PID为1的进程发送系统信号SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认的10秒,会继续发送SIGKILL的系统信号强行kill掉进程。SIGKILL信号是直接发往系统内核的,应用程序没有机会去处理它。在使用docker stop命令的时候,我们唯一能控制的是超时时间,比如设置为20秒超时:
docker stop --time=60 container_name
docker kill命令不会给容器中的应用程序有任何gracefully shutdown的机会。它会直接发出SIGKILL的系统信号,以强行终止容器中程序的运行。
二、基于python语言的信号处理
Python标准库中的signal包负责在Python程序内部处理信号,典型的操作包括预设信号处理函数,暂 停并等待信号,以及定时发出SIGALRM等。要注意,signal包主要是针对UNIX平台(比如Linux, MAC OS),而Windows内核中由于对信号机制的支持不充分,所以在Windows上的Python不能发挥信号系统的功能。
信号(signal)-- 进程之间通讯的方式,是一种软件中断。一个进程一旦接收到信号就会打断原来的程序执行流程来处理信号。
python实现对SIGTERM信号的接收并调用回调函数的示例:
SignalTest.py
import signal
# 定义回调函数
def myHandler(signum, frame):
print("接收信号为:", signum)
# 等待接收 signal.SIGTERM命令
signal.signal(signal.SIGTERM, myHandler)
signal.pause()
print("signal处理结束")
三、Docker测试
1、python程序打成镜像
(1)制作Dockerfile
FROM python:3.7
WORKDIR /docker_sig
COPY ./* /docker_sig/
CMD ["python", "./SignalTest.py"]
COPY 源目录 目的目录,其中源目录是相对Dockerfile所放位置的相对目录;
(2)存放文件
将程序和Dockerfile文件放在带有docker环境的某一目录下:
(3)制作镜像
[root@docker signalTest]# docker build -f ./Dockerfile -t hyj:2.3 .
Sending build context to Docker daemon 3.072kB
Step 1/4 : FROM python:3.7
---> ad37de9b03ef
Step 2/4 : WORKDIR /docker_sig
---> Using cache
---> 96b8f5d4db2d
Step 3/4 : COPY ./* /docker_sig/
---> 1325c7f5ce3f
Step 4/4 : CMD ["python", "./SignalTest.py"]
---> Running in e239015fd387
Removing intermediate container e239015fd387
---> ef06c745a322
Successfully built ef06c745a322
Successfully tagged hyj:2.3
[root@docker signalTest]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hyj 2.3 ef06c745a322 4 seconds ago 903MB
2、将镜像运行成容器
[root@docker signalTest]# docker run -d hyj:2.3
1fb1e66a9059bdff0faba0841200e86d4fa35e8e4a447231878457f3dcfcf52e
[root@docker signalTest]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1fb1e66a9059 hyj:2.3 "python ./SignalTest…" 3 seconds ago Up 2 seconds quirky_lederberg
3、进入容器并查询程序PID
4、启动日志检测
[root@docker signalTest]# docker logs -f -t --tail=100 1fb1e66a9059
5、停止容器并观察日志
[root@docker ~]# docker stop 1fb1e66a9059
1fb1e66a9059
[root@docker ~]#
[root@docker signalTest]# docker logs -f -t --tail=100 1fb1e66a9059
2022-05-24T09:41:17.146376396Z 接收信号为: 15
2022-05-24T09:41:17.146399445Z signal处理结束
[root@docker signalTest]#
以上,证明容器中的程序接收到SIGTERM的终止信号,并触发了回调函数;