2013-12-16 12 views
15

Mam skrypt punkt wejścia w pojemniku Döcker, który wygląda mniej więcej tak:wychwytywanie sygnału „stop” w bash Döcker

#!/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 

nie mogę dowiedzieć się, jak pułapka na sygnał wysłany przez uruchomiony docker stop na kontenerze. Kiedy uruchomiony interaktywnie, A ctrl+c będzie go wywołać zgodnie z oczekiwaniami, ale komenda docker stop tylko czeka na drugi limit czasu 10 i wychodzi bez kiedykolwiek wejściu do shut_down funkcja

Jak mogę pułapka sygnał wysłany przez docker stop w bash zrobić kilka sprzątać?

Odpowiedz

8

Wystarczy popatrzeć na this, może być inspirujące :-)

UPDATE:

@ nick-humrich tutaj jest to mój lamer kopia & przeszłość (zasługa oryginalnego autora 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" 
+8

specjalnie '/ opt/myapp' biegł w forground i zapobieganie pułapki z wykonaniem. Rozwiązaniem było zaktualizowanie tej linii w taki sposób, aby: "/ opt/webapp &; wait' –

+0

Powód dla DV: Odpowiedzi, które są tylko linkami, są uważane za słabe odpowiedzi. Co się stanie, jeśli link się zepsuje? –

+0

@ Nick-Humrich WOW naprawdę!?! –

2

Od Döcker 1.9, można użyć instrukcji STOPSIGNAL w Dockerfile:

STOPSIGNAL signal 

STOPSIGNAL ustawia sygnał wywołania systemowego, która zostanie wysłana do kontenera do zjazdu . Ten sygnał może być prawidłowym numerem bez znaku, który odpowiada pozycji w tabeli systemu Linux jądra, na przykład 9, lub nazwie sygnału w formacie SIGNAME, na przykład SIGKILL.

Źródło: https://docs.docker.com/engine/reference/builder/#stopsignal

+1

Należy pamiętać, że ze wszystkich sygnałów, które można wykorzystać, sygnał 9 jest prawdopodobnie najgorszy. Nazywa się KILL, ponieważ zabija proces docelowy, nie dając mu szansy na oczyszczenie. Używanie go na źle skonfigurowanym serwerze baz danych może na przykład być katastrofalne. –