Shib2IdpCluster
Tartalomjegyzék
[elrejtés]Shibboleth 2.1 IdP klaszterezése
Klaszter terminológia
- Node
- egy, a szolgáltatást futtató csomópont
- Klaszter
- kívülről nem megkülönböztethető nodeok összessége
- Szerver
- fizikai (vagy virtuális) gép, amely a nodeokat futtatja (egy gépen lehet több node is)
- Failover
- amennyiben egy csomópont kiesik, egy másik csomópont automatikusan és transzparensen átveszi a munkáját
- High availability
- amennyiben egy csomópont kiesik, nem veszhet el adat, a kliensek nem veszik észre a kiesést
- Load balancing
- a terhelés elosztása az egyes csomópontok között
Terracotta
A Shibboleth2 IdP a Terracotta szoftvert támogatja a klaszter építéséhez. A Terracotta képes arra, hogy a különböző nodeokon futó Shibboleth IdP-k között a session és egyéb információkat (például artifact map, authnrequest replay map, stb.) szinkronban tartsa.
A Terracotta kliens-szerver architektúrában működik. A kliensek a JVM-ben futó instrumentált osztályokból, osztálybetöltőből és zármenedzserből állnak, a szerverek pedig biztosítják a klaszterezett adatok perzisztens tárolását és a csomópont-független elérést. Amennyiben egy JVM-ben szükség van egy távoli JVM-ben létrehozott klaszterezett objektumra, akkor ezt az első elérésnél a Terracotta kliens elkéri a távoli szervertől. Emiatt teljesítmény okokból érdemes az azonos felhasználóhoz tartozó kéréseket mindig ugyanahhoz a csomóponthoz küldeni. A HTTP-Artifact profil használata esetén ez nem garantálható, ezért ajánlott a HTTP-Post profil használata.
Shibboleth IdP és Terracotta
A Shibboleth IdP-ben a következő adatok klaszterezését kell megvalósítani: artifact, session, replay, transientId, loginContext. Ezeket az adatokat a Shibboleth StorageService tárolja.
A Terracotta telepítéséhez és beállításához ez a wikioldal nyújt segítséget.
- Terracotta letöltése, kicsomagolása
- tűzfalbeállítások (TCP/9510 kliens->szerver és TCP/9530 szerver->szerver portok engedélyezése)
- minden csomóponton azonos JVM verziót használjunk a Terracotta szerverben és kliensben is
- tim-vector integrációs modul telepítése
- Shibboleth IdP-hez Terracotta konfiguráció szerkesztése tc-config.xml alapján
- csomópontok definiálása (szervernév, hosztnév, logok helye)
- terracotta szerver futtatása
- boot jar készítése (Terracotta kliens)
- boot jar használata a webkonténer JVM-nél
- FONTOS: JVM frissítés után újra kell generálni a boot jart!
JVM beállítások:
JAVA_OPTS="-Dtc.install-root=$TC_INSTALL_DIR \
-Dtc.config=$SHIB_IDP_HOME/conf/tc-config.xml \
-Xbootclasspath/p:$TC_INSTALL_DIR/lib/dso-boot/dso-boot-hotspot_$jvm_spec_ver.jar"
2.1.2 -es IdP verzióhoz a következő konfigurációs rész is szükséges az instrumented-classes szekcióba:
<include>
<class-expression>org.opensaml.xml.util.LazyList</class-expression>
<honor-transient>true</honor-transient>
</include>
Magas rendelkezésre állás beálítása
A következő konfigurációs részt a tc-config.xml elején kell elhelyezni. Ez engedélyezi a kliens-szerver és szerver-szerver újrakapcsolódást, ezzel kivédve az apró hálózati kimaradások okozta problémákat. Sajnos mindkét beállítás megnöveli a failover idejét.
<tc-properties>
<!-- server-to-server reconnect -->
<property name="l2.nha.tcgroupcomm.reconnect.enabled" value="true" />
<property name="l2.nha.tcgroupcomm.reconnect.timeout" value="15000" />
<!-- client-to-server reconnect -->
<property name="l2.l1reconnect.enabled" value="true" />
<property name="l2.l1reconnect.timeout.millis" value="15000" />
</tc-properties>
Debian initszkript a Terracotta szerver indításához
- /etc/init.d/terracotta néven mentsük el root tulajdonossal a következő szkriptet, majd adjunk rá execute jogot:
#!/bin/sh
TC_USER=nobody
TC_GROUP=nogroup
PIDFILE=/var/run/terracotta.pid
if [ `id -u` -ne 0 ]; then
echo "You need root privileges to run this script"
exit 1
fi
if [ -f /etc/default/terracotta ]; then
. /etc/default/terracotta
fi
if [ -z "$TC_INSTALL_DIR" -o ! -d "$TC_INSTALL_DIR" ]; then
echo "No TC_INSTALL_DIR specified or invalid TC_INSTALL_DIR"
exit 1
fi
if [ -z "$TC_CONFIG_PATH" -o ! -f "$TC_CONFIG_PATH" ]; then
echo "No TC_CONFIG_PATH specified or invalid TC_CONFIG_PATH"
exit 1
fi
if [ -z "$NODENAME" ]; then
echo "No NODENAME specified"
exit 1
fi
export JAVA_HOME
JAVA_OPTS="-server -Xms512m -Xmx512m -XX:+HeapDumpOnOutOfMemoryError $JAVA_OPTS"
TC_START_OPTS="$JAVA_OPTS \
-Dcom.sun.management.jmxremote \
-Dtc.install-root=$TC_INSTALL_DIR \
-cp $TC_INSTALL_DIR/lib/tc.jar \
com.tc.server.TCServerMain -n $NODENAME -f $TC_CONFIG_PATH"
TC_STOP_OPTS="-Dtc.install-root=$TC_INSTALL_DIR \
-cp $TC_INSTALL_DIR/lib/tc.jar \
com.tc.admin.TCStop"
. /lib/lsb/init-functions
. /etc/default/rcS
check_stopped () {
return `/sbin/start-stop-daemon --test --start --pidfile "$PIDFILE" \
--user $TC_USER --startas "$JAVA_HOME/bin/java" \
>/dev/null`
}
start () {
log_daemon_msg "Starting Terracotta server node ($NODENAME)..."
if check_stopped; then
/sbin/start-stop-daemon -S -v --make-pid --pidfile "$PIDFILE" \
--chuid $TC_USER:$TC_GROUP --background \
--exec $JAVA_HOME/bin/java -- $TC_START_OPTS
else
log_progress_msg "(already running)"
fi
log_end_msg 0
}
stop () {
log_daemon_msg "Stopping Terracotta server node ($NODENAME)..."
if $JAVA_HOME/bin/java $TC_STOP_OPTS; then
log_progress_msg "(shutdown command sent)"
else
log_progress_msg "(could not send shutdown command)"
fi
sleep 5
if check_stopped; then
log_end_msg 0
else
log_progress_msg "(stopping in progress)"
fi
}
force_stop () {
log_daemon_msg "Killing Terracotta server node ($NODENAME)..."
/sbin/start-stop-daemon -K --pidfile $PIDFILE -x $JAVA_HOME/bin/java
}
case "$1" in
start)
start
;;
stop)
stop
;;
force-stop)
force_stop
;;
restart)
stop
sleep 10
start
;;
*)
echo "Usage terracotta start|stop|force-stop|restart"
exit 1;;
esac
exit $?
- A konfiguráció az /etc/default/terracotta fájlban található:
NODENAME=terracotta-node-name
TC_CONFIG_PATH=/path/to/shibboleth-idp/conf/tc-config.xml
JAVA_HOME=/path/to/jvm
TC_INSTALL_DIR=/path/to/terracotta
Monitoring (JMX, Munin, Nagios)
- JMX: Java Management Extensions
- A Terracotta támogatja a JMX-en keresztüli monitorozást és bevatkozást
- alapértelmezésképp jmxmp protokollon keresztül
- másoljuk be a jmxremote_optional.jar -t a terracotta lib/ könyvtárából egy üres könyvtárba
- indítsuk a jconsole-t a következő paranccsal: jconsole -J-Djava.endorsed.dirs=.
- kapcsolódjunk a service:jmx:jmxmp://<tc-szerver-node>:9520 url-re
- usernév/jelszavas authentikáció esetén rmi protokollon keresztül is elérhetjük a tc szervert
- alapértelmezésképp jmxmp protokollon keresztül
- Check_jmx szkriptek nagioshoz és muninhoz
Fontosabb Terracotta MBean attribútumok
- org.terracotta:type=Terracotta Server,name=DSO
- LiveObjectCount (int)
- ClientLiveObjectCount (string)
- org.terracotta.internal:type=DSO Client,name=Client Transactions,subsystem=Transactions,clients=Clients,node=...
- AvgModifiedObjectsPerTransaction (int)
- AvgNewObjectsPerTransaction (int)
- ObjectCreationRateBySecond (int)
- ReadTransactionCount (int)
- WriteTransactionCount (int)
- org.terracotta.internal:type=Terracotta Server,name=Terracotta Server
- Active (bool)
- PassiveStandby (bool)
- PassiveUninitialized (bool)
- HealthStatus (String)
- State (string)
- StartTime (timestamp)
- Shutdownable (bool)
Nagios Terracotta szerver check
#!/bin/sh
TERRACOTTA_SERVER_NODES="papigw.aai.niif.hu sandbox.aai.niif.hu"
TERRACOTTA_CLIENT_COUNT=2
TERRACOTTA_SERVER_COUNT=2
JAVA_HOME=/usr/lib/jvm/java-1.5.0-sun
TC_HOME=/usr/local/terracotta-2.7.2
TC_MONITORING=/home/hege/terracotta/terracotta-monitoring/terracotta_monitoring.jar
ACTIVE_NODES=""
STANDBY_NODES=""
CLUSTER_STATUS=""
function check_health() {
TC_HEALTH=`echo "$1" | awk "/$2.health/{print "'$2}'`
if [ "x$TC_HEALTH" = "xOK" ]; then
return 0
else
echo TERRACOTTA CRITICAL - node $2 down
exit 2
fi
}
function check_active_count() {
ACTIVE_NODES=`echo "$1" | awk '/ACTIVE-COORDINATOR/{print $1}' | sed 's/\.state://'
ACTIVE_COUNT=`echo "$1" | awk 'BEGIN {cnt=0} /ACTIVE-COORDINATOR/{cnt++} END {print cnt}'`
CLUSTER_STATUS="$CLUSTER_STATUS, active nodes: $ACTIVE_NODES"
if [ "0$ACTIVE_COUNT" -eq 1 ]; then
return 0
else if [ "0$ACTIVE_COUNT" -gt 1 ]; then
echo TERRACOTTA CRITICAL - multiple ACTIVE nodes $CLUSTER_STATUS
else
echo TERRACOTTA_CRITICAL - no ACTIVE nodes $CLUSTER_STATUS
fi
exit 2
fi
}
function check_standby_count() {
STANDBY_NODES=`echo "$1" | awk '/PASSIVE-STANDBY/{print $1}' | sed 's/\.state://'`
STANDBY_COUNT=`echo "$1" | awk 'BEGIN {cnt=0} /PASSIVE-STANDBY/{cnt++} END {print cnt}'`
CLUSTER_STATUS="$CLUSTER_STATUS, standby nodes: $STANDBY_NODES"
if [ "0$STANDBY_COUNT" -eq $(($TERRACOTTA_SERVER_COUNT-1)) ]; then
return 0
else
echo TERRACOTTA CRITICAL - not enough STANDBY node $CLUSTER_STATUS
exit 2
fi
}
function check_client_count() {
CLIENTCOUNT=`echo "$1" | awk '/clientcount/{print $2}'`
CLIENT_NODES=`echo "$1" | awk '/client.*address/{print $2}'`
CLUSTER_STATUS="$CLUSTER_STATUS, client nodes: $CLIENT_NODES"
if [ "0$CLIENTCOUNT" -eq $TERRACOTTA_CLIENT_COUNT ]; then
return 0
else
echo TERRACOTTA WARNING - client count is $CLIENTCOUNT $CLUSTER_STATUS
exit 1
fi
}
OUTPUT=`$JAVA_HOME/bin/java -jar $TC_MONITORING $TERRACOTTA_SERVER_NODES 2>/dev/null`
check_active_count "$OUTPUT"
for i in $TERRACOTTA_SERVER_NODES; do
check_health "$OUTPUT" "$i"
done
check_standby_count "$OUTPUT"
check_client_count "$OUTPUT"
echo TERRACOTTA OK - cluster is running $CLUSTER_STATUS