[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

FreeBSD-Jails zuverlaessig starten/stoppen (was: Re: Konsistentes, dateibasiertes MySQL-Backup mit ZFS in FreeBSD-Jails )


On Sat, Dec 21, 2013 at 01:45:17AM +0100, Raphael Eiselstein wrote:
> Das Ganze noch in /etc/crontab, damit es taeglich automatisch passiert:
> .--- /etc/crontab ------- 
> | 15      5       *       *       *       root    /usr/sbin/jail -rc swg_mysql
> `----------

Der Jail-Neustart mittels "jail -rc" (remove+create) geht bei aktiv
genutzten Jails leider haeufiger schief:

jail: kevent: No such process

Mit dieser Fehlermeldung bleibt ein laufendes Jail (zB swg_mysql) auf 
halbem Weg haengen, d.h. Prozesse werden teilweise beendet, das Jail dann 
aber nicht mehr neu gestartet. Im Falle der Datenbank ist das natuerlich 
schlecht ;-)

Ich habe daher ein Wrapper-Script gebaut, welches zuverlaessig Jails
stoppen und starten kann, d.h. die getriggerten Aktionen werden
ueberwacht und ggf. wiederholt.

Jails zuverlaessig stoppen (mehrere Versuche helfen bei obigem Phaenomen):
.---------- 
| jail_stop()
| {
|         local J="${1:-"unknown"}"
|         local I=0
|         echo -n "$(date "+%F %X"): $0: stop: ${J}: INFO: stopping  "
|         until /usr/sbin/jail -r "${J}" ; do 
|                 echo -n "$? "
|                 I=$(( $I + 1 ))
|                 test ${I} -gt 10 && 
|                         { echo ""; echo "$(date "+%F %X"): $0: stop: ${J}: ERROR: cannot start (${I} tries)" >&2 ; return 1; }
|                 sleep ${I}
|         done
|         echo ""
|         echo "$(date "+%F %X"): $0: stop: ${J}: INFO: stopped"
| }
`----------

Auch ein erfolgreich gestopptes Jail (Keine Prozesse mehr etc) kann sich
intern noch als Zombie im "dying"-Modus befinden. Das verhindert
normalerweise nicht, dass man es neu starten kann, allerdings will ich
vermeiden, dass 2 Jails mit dem gleichen Namen mit 2 getrennten Jail-IDs
existieren und habe daher in die Start-Routine noch einen Check
eingebaut, der den Start verzoegert, sollte sich noch ein gleichnamiges
Jail im "dying"-Zustand befinden:

.---------- 
| jail_start()
| {
|         local J="${1:-"unknown"}"
|         local I=0
|         while jail_is_dying "${J}"; do
|                 I=$(( $I + 1 ))
|                 test ${I} -gt 15 && 
|                         break           # try anyway
|                 echo "$(date "+%F %X"): $0: start: ${J}: WARNING: still dying, wait another ${I} seconds."
|                 sleep ${I}
|         done
|         # if still dying try anyway
|         if jail_exists "${J}"; then
|                 echo "$(date "+%F %X"): $0: start: ${J}: ERROR: jail exists, cannot start" >&2
|                 return 1
|         else
|                 echo "$(date "+%F %X"): $0: start: ${J}: INFO: starting "
|                 /usr/sbin/jail -c "${J}"
|                 RET=$?
|                 echo "$(date "+%F %X"): $0: start: ${J}: INFO: started (${RET}) "
|         fi
| }
| 
`----------

Die Startroutine ist allerdings so ausgelegt, dass sie durchaus eine
ganze Weile wartet, ob das alte Jail noch ganz verschwindet bevor es
dann doch eine neue Instanz diees Jails neu startet.

jail_is_dying() und jail_exists sind wrapper um "jls -d -j jailname" bzw
"jls -j jailname" herum, die den jeweiligen Zustand gezielt pruefen und
mit sinnvollen exit-Codes reagieren.

BTW: Wer Jails kennt wird vermutlich jail(8) kennen wie es ueber
/etc/rc.d/jail aufgerufen wird, naemlich bisschen wie ein chroot mit ein
paar mehr Parametern (zB IP-Adressen). Ich verwende Jails mit jail(8) 
und vor allem mit jail.conf(5), wie es seit FreeBSD 9.1 existiert. 

Damit lassen sich sehr feingranular Properties fuer einzelne Jails 
konfigurieren, die traditionell nur global fuer alle Jails einstellbar 
waren.

Als Startscript verwende ich derzeit (noch) /usr/local/rc.d/jail2, 
welches im wesentlichen jail.conf(5) verwendet aber zusaetzlich noch 
ueber rc.conf diverse Eigenschaften wie ZFS-Datasets fuer Jails 
beruecksichtigt (nutze ich derzeit nicht).

Oben erwaehnter wrapper ("jail.sh") soll auch jail.conf verwalten,
indem einzelne Jails ueber einzelne conf-Dateien parametrisiert werden
und Meta-Informationen wie zB die Start/Stop-Reihenfolge von Jails, 
ZFS-Infos, Jail-Gruppen (zB UUG_INFRA, UUG_MEMBER, ...) etc als
Kommentarzeilen in den jeweiligen jail.conf-Fragmenten enthalten sind
und durch den Wrapper genutzt werden.

Ein an Apache in Debian angelehntes Konzept ermoeglicht dabei das
selektive aktivieren/deaktivieren von Jails durch setzen von Symlinks
nach jails/enabled/*.conf auf jails/available/*.conf

Sobald ich hier was vorzeigbares habe schiebe ich das auf github, im
Moment ist das alles noch sehr experimentell.

Viele Gruesse
Raphael

-- 
Raphael Eiselstein <rabe@xxxxxxxxx>               http://rabe.uugrn.org/
xmpp:freibyter@xxxxxx  | https://www.xing.com/profile/Raphael_Eiselstein   
PGP (alt):            E7B2 1D66 3AF2 EDC7 9828  6D7A 9CDA 3E7B 10CA 9F2D
PGP (neu):            4E63 5307 6F6A 036D 518D  3C4F 75EE EA14 F625 DB4E
.........|.........|.........|.........|.........|.........|.........|..




-- 
UUGRN e.V. http://www.uugrn.org/
http://mailman.uugrn.org/mailman/listinfo/uugrn
Wiki: https://wiki.uugrn.org/UUGRN:Mailingliste
Archiv: http://lists.uugrn.org/