SIGTERM 未被 AWS ECS docker 容器困住
SIGTERM not trapped by AWS ECS docker container
我有以下 ECS 容器定义
ContainerDefinitions:
- Name: myfluentd
Essential: true
Image: !Ref DockerImage
MountPoints:
- SourceVolume: efs-volume
ContainerPath: '/fluentd/buffers'
ReadOnly: false
PortMappings:
- ContainerPort: 24224
HostPort: 24224
Protocol: tcp
EntryPoint:
- "/var/lib/twistlock/defender.sh"
- "defender"
- "entrypoint"
- "tini"
- "--"
- "/bin/entrypoint.sh"
Command:
- fluentd
VolumesFrom:
- ReadOnly: false
SourceContainer: "TwistlockDefender"
ENTRYPOINT
是
["/var/lib/twistlock/fargate/fargate_defender.sh","fargate","entrypoint","tini","--","/bin/entrypoint.sh"]
以及entrypoint.sh
的内容
#!/bin/sh
#source vars if file exists
DEFAULT=/etc/default/fluentd
if [ -r $DEFAULT ]; then
set -o allexport
. $DEFAULT
set +o allexport
fi
# If the user has supplied only arguments append them to `fluentd` command
if [ "${1#-}" != "" ]; then
set -- fluentd "$@"
fi
# If user does not supply config file or plugins, use the default
if [ "" = "fluentd" ]; then
if ! echo $@ | grep ' \-c' ; then
set -- "$@" -c /fluentd/etc/${FLUENTD_CONF}
fi
if ! echo $@ | grep ' \-p' ; then
set -- "$@" -p /fluentd/plugins
fi
fi
. /bin/env.sh
task_cleanup() {
echo "Deleting files"
rm -rf /tmp/*
exit
}
trap task_cleanup SIGTERM SIGINT
exec "$@"
当我停止 ECS 任务时,它会向容器发出 SIGTERM
,我希望它执行 task_cleanup()
,但是信号没有被捕获。
我登录容器查看进程
PID USER TIME COMMAND
1 fluent 0:00 sh /var/lib/twistlock/defender.sh defender entrypoint tini -- /bin/entrypoint.sh fluentd
7 fluent 0:00 /var/lib/twistlock/defender defender entrypoint tini -- /bin/entrypoint.sh fluentd
16 root 0:00 /managed-agents/execute-command/amazon-ssm-agent
22 fluent 0:00 /sbin/tini -- /bin/entrypoint.sh fluentd
29 fluent 0:02 {fluentd} /usr/bin/ruby /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins
72 root 0:00 /managed-agents/execute-command/ssm-agent-worker
90 fluent 1:06 /usr/bin/ruby -Eascii-8bit:ascii-8bit /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins --under-supervisor
546 root 0:00 /managed-agents/execute-command/ssm-session-worker ecs-execute-command-03931001c6df08625
556 root 0:00 /bin/bash
870 root 0:00 ps aux
我错过了什么?为什么信号没有被困?
更新:ENTRYPOINT
启动了 2 个容器,我认为信号只发送到第一个容器 - 当我移除第一个容器时,我能够看到清理工作。任何想法如何处理这个?
Per the POSIX documentation for exec
(加粗我的):
If exec is specified with command
, it shall replace the shell with command
without creating a new process. ...
一旦您调用 exec "$@"
.
,您的 shell 进程和您使用 trap
创建的信号处理程序将不再存在
这可能会做你想做的事,但它完全未经测试,我还没有分析你构造的字符串 "$@"
:
.
.
.
task_cleanup() {
echo "Deleting files"
rm -rf /tmp/*
}
trap task_cleanup SIGTERM SIGINT
# background the task
"$@" &
pid=$!
wait $pid
kill $pid
exit
不是用"$@"
中的命令替换shell,而是运行命令作为shell.
将以下脚本保存在 test.sh
#!/usr/bin/env bash
task_cleanup() {
echo "Deleting files"
}
trap task_cleanup SIGTERM
"$@"
和 运行 它与 :
bash test.sh sleep 60
现在运行ps -ef|grep "bash test.sh sleep 60"
(在另一个bash会话中)获取PID,然后运行
kill -TERM PID
该进程将捕获信号 TERM,但仅在 sleep 60
完成后 运行 task_cleanup
。
我有以下 ECS 容器定义
ContainerDefinitions:
- Name: myfluentd
Essential: true
Image: !Ref DockerImage
MountPoints:
- SourceVolume: efs-volume
ContainerPath: '/fluentd/buffers'
ReadOnly: false
PortMappings:
- ContainerPort: 24224
HostPort: 24224
Protocol: tcp
EntryPoint:
- "/var/lib/twistlock/defender.sh"
- "defender"
- "entrypoint"
- "tini"
- "--"
- "/bin/entrypoint.sh"
Command:
- fluentd
VolumesFrom:
- ReadOnly: false
SourceContainer: "TwistlockDefender"
ENTRYPOINT
是
["/var/lib/twistlock/fargate/fargate_defender.sh","fargate","entrypoint","tini","--","/bin/entrypoint.sh"]
以及entrypoint.sh
#!/bin/sh
#source vars if file exists
DEFAULT=/etc/default/fluentd
if [ -r $DEFAULT ]; then
set -o allexport
. $DEFAULT
set +o allexport
fi
# If the user has supplied only arguments append them to `fluentd` command
if [ "${1#-}" != "" ]; then
set -- fluentd "$@"
fi
# If user does not supply config file or plugins, use the default
if [ "" = "fluentd" ]; then
if ! echo $@ | grep ' \-c' ; then
set -- "$@" -c /fluentd/etc/${FLUENTD_CONF}
fi
if ! echo $@ | grep ' \-p' ; then
set -- "$@" -p /fluentd/plugins
fi
fi
. /bin/env.sh
task_cleanup() {
echo "Deleting files"
rm -rf /tmp/*
exit
}
trap task_cleanup SIGTERM SIGINT
exec "$@"
当我停止 ECS 任务时,它会向容器发出 SIGTERM
,我希望它执行 task_cleanup()
,但是信号没有被捕获。
我登录容器查看进程
PID USER TIME COMMAND
1 fluent 0:00 sh /var/lib/twistlock/defender.sh defender entrypoint tini -- /bin/entrypoint.sh fluentd
7 fluent 0:00 /var/lib/twistlock/defender defender entrypoint tini -- /bin/entrypoint.sh fluentd
16 root 0:00 /managed-agents/execute-command/amazon-ssm-agent
22 fluent 0:00 /sbin/tini -- /bin/entrypoint.sh fluentd
29 fluent 0:02 {fluentd} /usr/bin/ruby /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins
72 root 0:00 /managed-agents/execute-command/ssm-agent-worker
90 fluent 1:06 /usr/bin/ruby -Eascii-8bit:ascii-8bit /usr/bin/fluentd -c /fluentd/etc/fluent.conf -p /fluentd/plugins --under-supervisor
546 root 0:00 /managed-agents/execute-command/ssm-session-worker ecs-execute-command-03931001c6df08625
556 root 0:00 /bin/bash
870 root 0:00 ps aux
我错过了什么?为什么信号没有被困?
更新:ENTRYPOINT
启动了 2 个容器,我认为信号只发送到第一个容器 - 当我移除第一个容器时,我能够看到清理工作。任何想法如何处理这个?
Per the POSIX documentation for exec
(加粗我的):
If exec is specified with
command
, it shall replace the shell withcommand
without creating a new process. ...
一旦您调用 exec "$@"
.
trap
创建的信号处理程序将不再存在
这可能会做你想做的事,但它完全未经测试,我还没有分析你构造的字符串 "$@"
:
.
.
.
task_cleanup() {
echo "Deleting files"
rm -rf /tmp/*
}
trap task_cleanup SIGTERM SIGINT
# background the task
"$@" &
pid=$!
wait $pid
kill $pid
exit
不是用"$@"
中的命令替换shell,而是运行命令作为shell.
将以下脚本保存在 test.sh
#!/usr/bin/env bash
task_cleanup() {
echo "Deleting files"
}
trap task_cleanup SIGTERM
"$@"
和 运行 它与 :
bash test.sh sleep 60
现在运行ps -ef|grep "bash test.sh sleep 60"
(在另一个bash会话中)获取PID,然后运行
kill -TERM PID
该进程将捕获信号 TERM,但仅在 sleep 60
完成后 运行 task_cleanup
。