![](/img/trans.png)
[英]Bash Script to loop docker ps command to stop and remove old containers
[英]Docker stop sleeping bash script
我有作為 docker 入口點運行的 bash 腳本。
這個腳本做了一些事情然后睡覺。
當發出docker stop
命令時,我需要能夠優雅地停止這個腳本。 AFAIK docker 向進程 1 發送SIGTERM
信號。
所以我創建了對SIGTERM
做出反應的 bash 腳本。
它在沒有kill -TERM <pid>
情況下運行良好,我可以啟動它,發出kill -TERM <pid>
並優雅地停止腳本。 不幸的是,它在 docker 中不起作用。
Dockerfile:
FROM ubuntu:20.04
WORKDIR /root
COPY test.sh .
CMD ./test.sh
測試.sh:
#!/bin/sh
trap 'echo TERM; exit' TERM
sleep 1 &
while wait $!
do
sleep 1 &
done
我應該如何修改腳本或 Dockerfile 以允許 docker stop 正常工作?
請注意,我不允許將-it
參數傳遞給docker run
。
問題來自CMD
指令的外殼形式: CMD ./test.sh
。
在這種情況下,命令是使用/bin/sh -c
shell 執行的。 所以/bin/sh
作為PID 1
運行,然后派生test.sh
, PID 1
是/bin/sh -c ./test.sh
。 結果SIGTERM
信號被發送到PID 1
並且永遠不會到達test.sh
。
要改變這一點,你必須使用exec form
: CMD ["./test.sh"]
。 在這種情況下,命令將在沒有 shell 的情況下執行。 所以信號會到達你的腳本。
FROM ubuntu:20.04
WORKDIR /root
COPY test.sh .
CMD ["./test.sh"]
跑和殺。
# run
docker run -d --name trap trap:latest
# send the signal
docker kill --signal=TERM trap
# check if the signal has been received
docker logs trap
# TERM
我建議您嘗試使用docker kill --signal=SIGTERM <CONTAINER_ID>
。
請讓我知道它是否會起作用。
請注意,如果您的腳本碰巧生成子進程,則您可能會在 docker 退出時留下孤立進程。 嘗試使用--init標志docker run --init ...
,內置的tini
-init 可執行文件tini
將假定 pid 1 並確保所有子進程(例如您的睡眠示例)在退出時相應地終止。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.