8 Feb 2010

iSCSI installation/configuration howto

Author: Heiko | Filed under: Linux

Bei dieser kleinen Einführung in iSCSI werde ich das Dateisystem von Oracle ocfs2 benutzen. Da ein iSCSI für mich keinen Sinn ohne Storage macht wird dieses Beispiel auch aus zwei Servern und einem iSCSI-Storage bestehen.

Wir fangen erst einmal damit an die benötigten Pakete zu installieren

apt-get install ocfs2-tool ocfs2console open-iscsi

Nun gibt es natürlich mehrere Wege sich mit dem Storage zu verbinden. Entweder über die CHAP-Authentifizierung oder über die Authentifizierung Seitens des iSCSI-Storage. Diese erfolgt über den InitiatorName, der sich in der Datei /etc/iscsi/initiatorname.iscsi befindet.
Dieser ist eindeutig und sollte besser nicht verändert werden.
Als erstes sagen wir dem iSCSI-Storage hallo

iscsiadm -m discovery -t sendtargets -p

hier erhält man nun die iqn (iSCSI Qualified Name) des Storage diese man für den Login benötigt.
Nun kann auch schon eingeloggt werden.

scsiadm -m node -T iqn.1992-08.com.netapp:sn.135051398 -p –login

Nun sollte man mit

fdisk -l

eine neue Platte vorfinden. Diese ist das neue Blockdevice das iSCSI zur Verfügung stellt.

ocfs2

Nun kommen wir zu Oracles Dateisystem, das genau wie der Gegenpart GCFS2 von IBM, Lockmechanismen benutzt um Inkonsistenten zu vermeiden. Das heißt es sind parallele Schreibzugriffe möglich.

Kommen wir zu der Einrichten von OCFS2. Als erstes muss das dazugehörige Cluster konfiguriert werden. In dem Cluster gibt es verschiedene Nodes, die mit Heartbeat prüfen, ob die anderen Nodes noch erreichbar sind und noch Ihre Aufgabe wahrnehmen können. Falls ein Node ausfällt, bekommen die anderen dies mit und werfen den fehlenden Node aus dem Cluster.

Öffnen wir die Konfigurationsdatei und definieren die einzelnen Nodes. Diese Datei muss auf allen Hosts gleich sein.

cluster:
node_count = 2
name = meinCluster

als erstes definiert man das Cluster. Den Namen und die Anzahl der Nodes.

node:
ip_port = 7777
ip_address = 192.168.0.3
number = 1
name = app1
cluster = meinCluster
node:
ip_port = 7777
ip_address = 192.168.0.4
number = 2
name = app2
cluster = meinCluster

und hier werden die Nodes definiert. Man sollte versuchen den Heartbeat über ein eigenes Backnet laufen zu lassen, da er den Durchsatz drückt.

Als nächstes formatieren wir als erstes die eben “neu” gefundene Platte in das korrekte Filesystem.
Hier im Beispiel /dev/sdb

mkfs.ocfs2 /dev/sdb

Wenn dies nun fertig ist, muss der Heartbeat des OCFS2-Clusters konfiguriert werden. Um dies zu tun gibt es 2 Möglichkeiten.

/etc/init.d/o2cb configure

oder

dpkg-reconfigure ocfs2-tools

Die werte die für mich sich bisher als optimal erwiesen haben sind wie folgt.

# O2CB_HEARTBEAT_THRESHOLD: Iterations before a node is considered dead.
O2CB_HEARTBEAT_THRESHOLD=62

# O2CB_IDLE_TIMEOUT_MS: Time in ms before a network connection is considered dead.
O2CB_IDLE_TIMEOUT_MS=60000

# O2CB_KEEPALIVE_DELAY_MS: Max time in ms before a keepalive packet is sent
O2CB_KEEPALIVE_DELAY_MS=3000

# O2CB_RECONNECT_DELAY_MS: Min time in ms between connection attempts
O2CB_RECONNECT_DELAY_MS=2000

Es gibt noch eine Tücke. Wenn eine Netzverbindung gestört zu dem Storage ist und es zum Timeout kommt, oder eine Node ein sonstiger Fehler wirft, bekommt der Server einen KernelPanic verpasst. Dies ist zum Schutz der Konsistens der Daten. Aus diesem Grund ist auch der Timeoutzeit so hoch eingestellt.

6 Jan 2010

Es ist soweit die Reise beginnt

Author: Heiko | Filed under: Allgemein

Endlich ist es soweit die konkreten Planungen haben, für meine lang ersehnte Mexikoreise, begonnen :) .
Der Termin steht nun fest Flug wird gebucht und nun beginnt die Planung der Reiseroute. 3 Wochen Zeit und versuchen die Baja California runter und hoch zu fahren. Wie weit wir wirklich kommen wird sich zeigen :D

Abflug ist Frankfurt a. M. mit einem Zwischenstopp in N.Y. dann gehts weiter nach San Diego und ab aus dem Flugzeug ins warme :D .

Danach über die grenze ins gelobte Land :D ….

Fortsetzung folgt :>

11 Dez 2009

Ruby xen-Api howto

Author: Heiko | Filed under: Ruby

Für Phyton, Perl gibt es Bindings für die Xen-Api. Wer allerdings andere Sprachen verwenden möchte wie Ruby, hat erst einmal schlechte Karten. Denn das heißt im Regelfall die schlecht dokumentierte Api zu verstehen.

Für die Xen-Versionen <3.0.4 kann man sich das Gem “ruby-xen” ansehen. Dieses greift allerdings nicht auf die API zu, sondern händelt die Steuerung von Xen über die Xen-Tools auf der Kommandozeile und parst lediglich die Ausgabe.
Libvirt bietet auch ein ruby-Binding an, das aber nicht in den Paketquellen enthalten ist und von Hand kompeliert werden muss.

Ich wollte allerdings die Xen-Api verwenden. Hierzu zeige ich ein einfaches Beispiel, wie man mit der API kommuniziert.

Als erstes müssen in Xen ein paar Einstellungen getätigt werden.
Hierzu öffnen wir /etc/xen/xend-config.sxp
Dort suchen wird als erstes direkt am Anfang der Konfigurationsfile die Logfile definiert und den loglevel eingestellt.

(logfile /var/log/xen/xend.log)
(loglevel DEBUG)

Diese Einstellung kann man natürlich ignorieren, wenn man etwas sicherer mit dem Umgang mit der API ist. Falls dies nicht der Fall ist, empfehle ich den Loglevel so tief anzusetzen.
Nun muss der Xen-Api-Server aktiviert werden

(xen-api-server ((9363 pam ‘^localhost$ ‘)))

der Port ist natürlich variable nach localhost kann man auch noch andere IP’s oder Domains angeben die auf den API-Server Zugriff haben.
Danach muss der xend neu gestartet werden.
Jetzt kann man sich eine Testfile erstellen

vim xen-api.rb

Da wie schon erwähnt Ruby keine Xen-Bindings besitzt, muss die API über die Lib XMLRPC angesprochen werden.
Wir öffnen nun eine Verbindung zu dem Api-Server

#!/usr/bin/env ruby

require 'xmlrpc/client'

client = XMLRPC::Client.new('localhost',nil,9363)

Wie zu sehen ist, sind die Parameter

  • localhost => Server
  • nil => Pfad zum Socket (falls verwendet)
  • 9363 => Port
  • Nun wird die erste Session erzeugt. Diese wird erst erstellt wenn ein erfolgreicher Login stattgefunden hat.

    session = client.call("session.login_with_password","username","password")
    

    Achtung!!!
    Das Login erfolgt über das pam Modul, es muss also ein Systemuser angelegt sein. Via root ist es nicht möglich einzuloggen

    Wenn wir uns erfolgreich eingeloggt haben bekommen wir eine Hash zurück die in etwas so aussehen sollte.

    {”Status”=>”Success”, “Value”=>”25d9b202-1ac4-572a-54d1-19d9e0a88810″}

    als nächster Schritt muss eine Hostreferenz erstellt werden (HostObject)

    host_ref = client.call("session.get_this_host",session["Value"], session["Value"])
    

    Ab diesem Zeitpunkt kann man alle API Functions nutzen die man möchte. Man hat nun die Session und die benötigte Host-Referenz.

    Beispiel:
    Auflisten aller VM’s

    vms = client.call("host.get_resident_VMs",session["Value"],host_ref["Value"])
    vms["Value"].each {|vm|
    
    vm_name = client.call("VM.get_name_label",session["Value"],vm)
    
    puts vm_name["Value"]
    }
    

    Die einzelnen Functions lassen sich aus der Xen-APIDoc auslesen.