但是,我很想知道官方形象如何解决问题。
Don tabes: Docker 1.13 。
Any image run with docker run --init
would include an init
inside the container that forwards signals and reaps processes.
As mentioned here, tini
works transparently, Dockerfiles don t need to be modified in any way.
因此,在Unix系统中,当你在码头上报CTRL+C
时,将“SIG(Signal Interrupt)发给地下加工组,在这种情况下,是Docker集装箱。 如果您使用<条码>CTRL+,则发送<条码>SIGQUIT,如果您使用<条码>CTRL+Z,则发送<条码>SIGTSTP(传真号码)。
Docker containers run a single main process, and this process runs in PID 1.
PID 1 is special on Linux: it is the first process that runs and is the ancestor of all other processes.
It also has a special relationship with Unix signals: it is the only process that can choose to ignore SIGINT
and SIGTERM
. Other processes cannot ignore these signals, but they can have handlers that execute when they receive them.
In Docker, when you use CMD
to specify the process to run, Docker will wrap that process with a small init
system (like tini
), which properly handles Unix signals and forwards them to the main process (I mentioned it originally here).
This is why your caddy
image, which does not have an ENTRYPOINT
and only has CMD
, can handle the CTRL+C
.
然而,当你使用<条码>ENTRYPOINT时,Docker没有用这个小型<代码>in系统对这一过程进行总结,而这一过程则作为PID 1进行。
如果程序没有为<代码>SIGINT或SIGTERM
建立,则不会对<代码>CTRL+C做出答复。 因此,mariadb
index, which has an ENTRYPOINT
, do not end when You press CTRL+C
。
处理杀人信号是gracefuldown的一个重要部分。 当一个过程收到<代码>SIGTERM(或<编码>SIGINT时,它就应停止接受新的工作,完成其目前的工作,然后退出。 这使它能够清理它使用的任何资源,并确保数据的一致性。
如果程序没有处理这些信号,而且只是被杀(有<代码>SIGKILL),那么它就没有机会清理,并且可能将资源留给一个不一致的国家。 在MariaDB这样的数据库中,这种情况可能有害,因为MariaDB可能会有未经处理的交易或部分书面数据。
为了支持在Docker入境点处理杀人信号,你可以:
在条目编号上添加处理信号。 这需要修改文字,如果切入点是双亲,则可能不可行。
利用<代码>in系统处理信号并将其传送到主要程序。 为此设计的有小的<代码>init/code>,如tini
。 您可在您的Dockerfile中加以利用。
FROM your-base-image
RUN apt-get update && apt-get install -y tini
ENTRYPOINT ["/usr/bin/tini", "--", "your-command"]
这将作为PID1运行tini
,处理信号并将信号转交你指挥。
使用Dockers的内装,这是最低限度的tini
执行。 您可使用<代码>-init。 您经营集装箱时的选择:
docker run --init -it --rm -p 3306:3306 -e MARIADB_ALLOW_EMPTY_ROOT_PASSWORD=true mariadb:latest
这将把Docker的内装成PID1,处理信号并将其转发给MariaDB。
这些方法确保你的Docker入境点能够处理杀人信号,并在必要时进行可耻的关闭。
NOT是否有理由支持处理杀人信号?
勿庸置疑,除非你希望你的形象真实:
- simple, for a very simple or short-lived processes, with no need of signal handling
- fast, to avoid any shutdown signals during critical sections of their code
- resilient, when you want to prevent unwanted or unauthorized shutdown.
但一般来说,无视终止信号可能导致诸如数据损失、资源流失或立案程序等问题,应当避免。
剩下的唯一事情是:如果不支持关闭信号,那么像MariaDB一样,服务就有些危险,为什么MariaDB本身不直接支持它?
This could be for a legacy reason, inherited from MySQL, which MariaDB is a fork of. MySQL was developed before Docker existed, and in a traditional server environment, it s less common for a process to receive a SIGINT
. It s more common for a process to receive a SIGTERM
when the system is shutting down, which MySQL and MariaDB do handle.
Its entrypoint reflects that, and you run it with --init
to ensure a basic SIGINT
support.
But keep in mind it is not the only issue. I made the mistake of running a MariaDB instance on an Azure ACI (container) instead of AKS (Kubernetes).
When an ACI closes (at least when I used it in 2021), it sends... a SIGKILL (a signal which cannot be caught, blocked, or ignored). When the kernel sends a SIGKILL to a process, that process is immediately terminated, and it doesn t get a chance to clean up or do any other work before it s killed.
因此,不管你的形象是否支持可耻的关闭,都铭记你的执行环境,这首先可能不允许任何可耻的关闭。