2015-05-04 8 views
5

Muszę skonfigurować "dokowane" środowiska (integracja, qa i produkcja) na serwerze tym samym (wymagania klienta). Każde środowisko będzie składać się następująco:Najlepszy sposób zarządzania kontenerami w doku z supervisorem

  • RabbitMQ
  • seler
  • kwiat
  • python 3 aplikacja o nazwie "A" (specyficzna gałąź za środowiska)

nad nimi, jenkins obsłuży wdrożenie na podstawie CI.

Używanie zestawu kontenerów na środowisko brzmi jak najlepsze podejście.

Ale teraz muszę, Process Manager, aby uruchomić i nadzorować wszystkie z nich:

  • 3 pojemniki królik, pojemniki
  • 3 seler/kwiatowe,
  • 3 "A" kontenery,
  • 1 pojemniki z jenkins.

Supervisord wydaje się być najlepszym wyborem, ale podczas moich testów nie jestem w stanie "prawidłowo" ponownie uruchomić kontenera. Oto urywek supervisord.conf

[program:docker-rabbit] 
command=/usr/bin/docker run -p 5672:5672 -p 15672:15672 tutum/rabbitmq 
startsecs=20 
autorestart=unexpected 
exitcodes=0,1 
stopsignal=KILL 

Więc zastanawiam się, co jest najlepszym sposobem, aby oddzielić środowisko i być w stanie zarządzać i nadzorować każdą usługę (pojemnik).

[edit Moje rozwiązanie inspirowane przez Thomasa odpowiedzi]

każdy pojemnik jest prowadzony przez .sh skryptu, który wygląda jak

rabbit-integration.py

#!/bin/bash 

#set -x 
SERVICE="rabbitmq" 
SH_S = "/path/to_shs" 
export MY_ENV="integration" 
. $SH_S/env_.sh 
. $SH_S/utils.sh 

SERVICE_ENV=$SERVICE-$MY_ENV 
ID_FILE=/tmp/$SERVICE_ENV.name # pid file 

trap stop SIGHUP SIGINT SIGTERM # trap signal for calling the stop function 
run_rabbitmq 

$ SH_S/env_.sh wygląda następująco:

# set env variable 
... 
case $MONARCH_ENV in 
    $INTEGRATION) 
     AMQP_PORT="5672" 
     AMQP_IP="172.17.42.1" 
    ... 
    ;; 
    $PREPRODUCTION) 
     AMQP_PORT="5673" 
     AMQP_IP="172.17.42.1" 
     ... 
     ;; 
    $PRODUCTION) 
     AMQP_PORT="5674" 
     REDIS_IP="172.17.42.1" 
     ... 
esac 

$ SH_S/utils.sh patrzy jak:

#!/bin/bash 

function random_name(){ 
     echo "$SERVICE_ENV-$(cat /proc/sys/kernel/random/uuid)" 
} 
function stop(){ 
     echo "stopping docker container..." 
     /usr/bin/docker stop `cat $ID_FILE` 
} 
function run_rabbitmq(){ 
     # do no daemonize and use stdout 
     NAME="$(random_name)" 
     echo $NAME > $ID_FILE 
     /usr/bin/docker run -i --name "$NAME" -p $AMQP_IP:$AMQP_PORT:5672 -p $AMQP_ADMIN_PORT:15672 -e RABBITMQ_PASS="$AMQP_PASSWORD" myimage-rabbitmq & 
     PID=$! 
     wait $PID 
} 

Przynajmniej myconfig.intergration.conf patrzy jak:

[program:rabbit-integration] 
command=/path/sh_s/rabbit-integration.sh 
startsecs=20 
priority=90 
autorestart=unexpected 
exitcodes=0,1 
stopsignal=TERM 

W przypadku chcę użyć tego samego pojemnika funkcja uruchamiania patrzy jak:

function _run_my_container() { 
    NAME="my_container" 
    /usr/bin/docker start -i $NAME & 
    PID=$! 
    wait $PID 
    rc=$? 
    if [[ $rc != 0 ]]; then 
     _run_my_container 
    fi 
} 

gdzie

function _run_my_container(){ 
    /usr/bin/docker run -p{} -v{} --name "$NAME" myimage & 
    PID=$! 
    wait $PID 
} 
+2

Nieco prostopadła do czego konkretnie pytaniem w tej kwestii, ale ty masz spojrzał na [ 'docker-compose'] (https://docs.docker.com/compose/)? Umożliwia definiowanie/administrowanie grupami kontenerów (w tym łączami między kontenerami). Dodatkowo pozwala określić [Restart Policies] (https://docs.docker.com/reference/run/#restart-policies-restart) w swojej konfiguracji, która może obsłużyć to, czego potrzebujesz. – lsowen

+0

Dzięki, widziałem to, ale nie znalazłem sposobu na ponowne uruchomienie konkretnej usługi i jak ją nadzorować. Chcemy również użyć interfejsu web supervisorctl do podłączenia do istniejącego rozwiązania monitorującego. –

+0

https://github.com/docker/dockercraft ... tworzy dobrego wizualnego menedżera dokerów: P –

Odpowiedz

8

Inspektor wymaga, aby je przetwarza zarządza nie demonizuje, jak na jego :

Programy przeznaczone do pracy pod nadzorem nie powinny dememonizować samych siebie . Zamiast tego powinny działać na pierwszym planie. Powinny one nie odłączyć się od terminala, z którego zostały uruchomione.

Jest to w dużym stopniu niezgodne z dokowanym, gdzie pojemniki są podprocesów z Proces dokowanym sam (to jest, a zatem nie są z podprocesów Promotor).

Aby móc używać Docker z Supervisor, możesz napisać odpowiednik pidproxy program, który działa z Dockerem.


Ale naprawdę, oba narzędzia nie są naprawdę architected pracować razem, więc należy rozważyć zmianę jednego lub drugiego:

  • rozważyć zastąpienie Supervisor z Docker Compose (który jest przeznaczony do pracy z doker)
  • rozważyć zastąpienie Döcker z Rocket (który nie posiada proces "master")
1

trzeba mak Upewnij się, że używasz stopignal = INT w konfiguracji supervisora, a następnie exec docker run normalnie.

[program:foo] 
stopsignal=INT 
command=docker -rm run whatever 

Przynajmniej to wydaje się działać dla mnie z wersją 1.9.1 dokowania.

Jeśli w skrypcie powłoki zostanie uruchomiony formularz dokowania, bardzo ważne jest, aby przed poleceniem uruchomienia dokowania uzyskać exec, dzięki czemu docker run zastąpi proces powłoki, a tym samym otrzyma SIGINT bezpośrednio od supervisora.

+0

Dziękuję, to jest najkrótsza i najbardziej aktualna rada, i działa to dla mnie. Używam exec w moim skrypcie powłoki i działa. Używam kontenera docker --rm -i, a dziennik jest ładnie rejestrowany w dziennikach nadzoru w/var/log/supervisor. –

2

Możesz mieć Docker po prostu nie odłączać, a następnie wszystko działa dobrze. Zarządzamy kontenerami Docker w ten sposób przez przełożonego. Kompilacja Docker jest świetna, ale jeśli już korzystasz z aplikacji Supervisor do zarządzania funkcjami non-docker, dobrze jest nadal korzystać z niej, aby mieć całe zarządzanie w jednym miejscu. będziemy zawijać nasz bieg Döcker w skrypcie bash jak poniżej i mają nadzorca śledzić to, i wszystko działa poprawnie:

#!/bin/bash¬ 
TO_STOP=docker ps | grep $SERVICE_NAME | awk '{ print $1 }'¬ 
if [$TO_STOP != '']; then¬ 
    docker stop $SERVICE_NAME¬ 
fi¬ 
TO_REMOVE=docker ps -a | grep $SERVICE_NAME | awk '{ print $1 }'¬ 
if [$TO_REMOVE != '']; then¬ 
    docker rm $SERVICE_NAME¬ 
fi¬ 
¬ 
docker run -a stdout -a stderr --name="$SERVICE_NAME" \ 
--rm $DOCKER_IMAGE:$DOCKER_TAG