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