簡體   English   中英

來自 bash 中“docker stop”的陷阱信號

[英]trapping signal from "docker stop" in bash

我在 docker 容器中有一個入口點腳本,如下所示:

#!/bin/bash

echo starting up

function shut_down() {
    echo shutting down

    pid=$(ps -e | grep myapp | awk '{print $1}')
    kill -SIGTERM $pid  
    exit
}

trap "shut_down" SIGKILL SIGTERM SIGHUP SIGINT EXIT

/opt/myapp

我不知道如何通過在容器上運行docker stop來捕獲發送的信號。 交互式運行時, ctrl+c將按預期觸發它,但docker stop命令只是等待 10 秒超時,並退出而沒有進入shut_down function

如何捕獲 docker 發送的信號docker stop在 bash 中進行一些清理?

老問題,但這可以解決問題:

#!/bin/bash

echo starting up

exec /opt/myapp

有關詳細信息,請查看此處: https : //akomljen.com/stopping-docker-containers-gracefully/

看看 這個,可能會鼓舞人心:-)

更新:

@nick-humrich 這里是我的 lamer 副本和過去(歸功於原作者https://github.com/lgierth

#!/bin/bash

function ensure_started_container {
  exists=`docker ps -q | grep $1`
  if [ "$?" = "0" ] ; then
    echo "[docker-exec] skipping docker start, already started"
  else
    output=`docker start "$1"`
    echo "[docker start] $output"
  fi
  running=1
}

function setup_signals {
  cid="$1"; shift
  handler="$1"; shift
  for sig; do
    trap "$handler '$cid' '$sig'" "$sig"
  done
}

function handle_signal {
  echo "[docker-exec] received $2"
  case "$2" in
    SIGINT)
      output=`docker stop -t 5 "$1"`
      echo "[docker stop] $output"
      running=0
      ;;
    SIGTERM)
      output=`docker stop -t 5 "$1"`
      echo "[docker stop] $output"
      running=0
      ;;
    SIGHUP)
      output=`docker restart -t 5 "$1"`
      echo "[docker restart] $output"

      # restart logging
      docker attach "$1" &
      kill "$logger_pid" 2> /dev/null
      logger_pid="$!"
      ;;
  esac
}

running=0

setup_signals "$1" "handle_signal" SIGINT SIGTERM SIGHUP

ensure_started_container "$1"

docker attach "$1" &
logger_pid="$!"

while true; do
  if [ "$running" = "1" ]; then
    sleep 1
  else
    break
  fi
done

exit_code=`docker wait "$1"`
exit "$exit_code"

由於碼頭工人1.9,你可以使用STOPSIGNAL在你的指令Dockerfile

 STOPSIGNAL signal

STOPSIGNAL設置將發送到容器以退出的系統調用信號。 該信號可以是與內核系統調用表中的位置匹配的有效無符號數,例如 9,或格式為 SIGNAME 的信號名稱,例如 SIGKILL。

來源: https : //docs.docker.com/engine/reference/builder/#stopsignal

就我而言,簡單地設置陷阱是行不通的。 我必須將進程設置為后台以捕獲信號,否則信號會轉到啟動的進程本身。

起始腳本的原始最后一行是:

sudo -H -u "$uid" sh -c "myserviced"

我用以下代碼替換了這一行:

shutdown_myservice() {
  set +e
  echo "[SHUTDOWN] Shutting down myservice"
  sudo -u "$uid" myservicecmd -c Shutdown
  echo "[SHUTDOWN] sent. $?"
  wait $dpid  # make sure the process terminated and not just started stopping
  echo "[SHUTDOWN] down. $?"
  return 0
}

trap "shutdown_myservice" HUP INT QUIT TERM USR1

# here, start the process in BACKGROUND
sudo -H -u "$uid" sh -c "myserviced" &
dpid=$!
wait $dpid

這樣,“焦點”就不再是守護進程了。 相反,它在啟動腳本上。 我似乎只有“焦點”進程(前台進程)才能收到信號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM