RPi-Docker-Cluster... die Anfänge

 

Schritt 1:

28,10,0,50,1
600,600,60,1,3000,5000,25,800
90,150,1,50,12,30,50,1,70,12,1,50,1,1,1,5000
Powered By Creative Image Slider
Spannungscheck (ok, Spannung bricht gegenüber Leerlauf nicht ein) Oberster RPi noch außer Betrieb da HM-MOD-RPI-PCB angeschlossen aber damit sind die 5V-Anschlüsse auf der Anschlussleiste blockiert.
Hardwareaufbau
View Image
Nach Erweiterung des obersten RPi um CCU2 Funkmodul (HM-MOD-RPI-PCB) und externe Spannungsversorgung gleichzeitig nuten zu können.
Erster Startup, mit Netzwerk und frischen SD-Karten. (HypriotOS, außer oberster RPi mit fertigem Raspbian und YAHM)
First Startup
View Image

Man nehme sich "ein paar RaspberryPis".
Am besten RPi2er oder RPi3er. Die ganzen RPi1er sind doch ein wenig lahm mit nur einem Kern, aber das geht auch.

Mein Setup besteht aus: 1x RPi3, 2x RPi2, 1x RPi 1B+

 

Schritt 2:

Installiere das Basis OS:
Hypriot V1.1.3 (Stand Januar 2017)
Download-Link siehe Linkliste am Ende

Der RPi3 läuft unter Raspbian Jessie, da hier noch eine CCU2 (YAHM) mit laufen muß.
Um auf dem Raspbian auch eine 1.12.x Docker Version zu bekommen hab ich diese Anleitung genommen:
http://blog.alexellis.io/getting-started-with-docker-on-raspberry-pi/

Mit den regelmäßigen Updates und als ist nun auch ein fertiges Docker Paket (17.05.0-ce) für ARM/RPi zu bekommen.
(deb [arch=armhf] https://apt.dockerproject.org/repo raspbian-jessie main)

 

Schritt 3&4:

Kubernetes (benötigt mindestens Docker V1.12.x, und geht aktuell nicht mit Docker 17.05.0-ce auf RPi)
( https://blog.hypriot.com/post/setup-kubernetes-raspberry-pi-cluster/ )

Also: Test mit Docker 17.05.0-ce auf RPi Hypriot V1.4.0 und Docker Swarm
(Und der RPi mit Raspbian Jessie und CCU2 wird zum DRBD/Corosync Fileserver)

 

DRBD:

So hab ich mein DRBD gebaut und installiert:

Als erstes die Grundlagen schaffen

apt-get install net-tools rsync rsyslog heartbeat pacemaker corosync bridge-utils drbd8-utils -f -y
apt-get remove drbd8-utils -f -y
apt-get install build-essential flex autoconf automake bison -f -y

cd /usr/src
wget http://www.drbd.org/download/drbd/utils/drbd-utils-8.9.10.tar.gz
tar xzvf drbd-utils-8.9.10.tar.gz
cd drbd-utils-8.9.10
./configure --prefix=/usr --sysconfdir=/etc --without-83support --with-pacemaker --with-heartbeat --with-udev --runstatedir=/var/run --localstatedir=/var
# ./configure --prefix=/usr --sysconfdir=/etc --without-83support --with-pacemaker --with-heartbeat --with-udev --runstatedir=/var/run --localstatedir=/var --without-manual
make

make install

 

Die vorhanden DRBD Versionen sind zu alt (Wheezy ist zu alt, bei Jessie = 8.9.2~rc1-1~bpo70+1 aber als ich es gebaut hab, hatte ich das Upgrade auf Jessie noch nicht gemacht) für einige Features.

 

Das Modul "drbd" laden

und dauerhaft laden lassen über z.B. /etc/modules oder /etc/modules-load.d/modules.conf

modprobe drbd
vi /etc/modules

 

 

Nun legt euch die Konfigration an:

/etc/drbd.d/clusterbeispiel.res
resource clusterbeispiel {
  protocol C;
  startup { wfc-timeout 0; degr-wfc-timeout 120; }

  disk { on-io-error detach; }
# HA-IPs (DRBD/Heartbeat Kommunikation / MUST match hostname (uname -n))
  on <Hostname des ersten DRBD Servers> {
    ### Optionen für Master-Server ###
    # Name des bereitgestellten Blockdevices
    device     /dev/drbd0;
    # dem DRBD zugrunde liegendes Laufwerk
    disk       /dev/sda1; # In dem Fall der erste USB-Stick... vor sich bei mehreren Sticks
    # Adresse und Port, über welche die Synchr. läuft
    address    192.168.100.1:7788;
    # Speicherort der Metadaten, hier im Laufwerk selbst
    meta-disk  internal;
  }
# HA-IPs (DRBD/Heartbeat Kommunikation / MUST match hostname (uname -n))
  on <Hostname des ersten DRBD Servers> {
    ## Optionen für Slave-Server
    # Name des bereitgestellten Blockdevices
    device     /dev/drbd0;
    # dem DRBD zugrunde liegendes Laufwerk
    disk       /dev/sda1; # In dem Fall der erste USB-Stick... vor sich bei mehreren Sticks
    # Adresse und Port, über welche die Synchr. läuft

    address    192.168.100.2:7788;
    # Speicherort der Metadaten, hier im Laufwerk selbst
    meta-disk  internal;
  }
}

Diese Datei muß identisch auf BEIDEN Systemen liegen (in /etc/drbd.d)

 

Verbinden und Filesystem anlegen

Auf beiden Systemen:

drbdadm create-md kubedata
drbdadm up kubedata

Nur auf dem der später "Master" sein soll:

drbdadm -- --overwrite-data-of-peer primary kubedata
mkfs.ext4 /dev/drbd0

Der aktuelle Zustand (und die Fortschritte bei (re-)sync Aktionen) könne mit folgendem Kommando beobachtet werden:
watch "cat /proc/drbd"


NFS-Server

Über einen NFS-Server die Filesysteme jeweils freigeben.

apt-get -y -f install nfs-kernel-server

mkdir -p /nfs-server/kubedata
touch /nfs-server/kubedata/IF_YOU_SEE_THIS_SOMETHING_IS_WORNG

mount /dev/drbd0 /nfs-server/kubedata

vi /etc/exports
/nfs-server/kubedata 192.168.2.0/24(rw,async,no_root_squash,no_subtree_check,fsid=1)

 

Corosync (den Failover) einrichten

Als nächstes Corosync aktivieren, damit bei einem Ausfall auch auf den anderen Server geschwenkt wir.

Dafür jeweils:

vi /etc/default/corosync
START=yes

und die eigentliche Konfiguration anpassen in
/etc/corosync/corosync.conf

aisexec {
        # Run as root - this is necessary to be able to manage
        # resources with Pacemaker
        user:           root
        group:          root
}

totem {
  version: 2
  cluster_name: rpi
  transport: udpu

        # How long before declaring a token lost (ms)
        token:          5000
        # How many token retransmits before forming a new configuration
        token_retransmits_before_loss_const: 10
        # How long to wait for join messages in the membership protocol (ms)
        join:           1000
        # How long to wait for consensus to be achieved before starting
        # a new round of membership configuration (ms)
        consensus:      6000
        # Turn off the virtual synchrony filter
        vsftype:        none
        # Number of messages that may be sent by one processor on
        # receipt of the token
        max_messages:   20
        # Limit generated nodeids to 31-bits (positive signed integers)
        # you would set it to 'yes', the new option 'new' means wiping
        # off the highest bit in network order to avoid possible nodeid
        # conflicting.
        clear_node_high_bit: new
        # secauth: Enable mutual node authentication. If you choose to
        # enable this ("on"), then do remember to create a shared
        # secret with "corosync-keygen".
        secauth: off
        # How many threads to use for encryption/decryption
        threads: 0

  interface {
        member {
                memberaddr: 192.168.2.100
        }
        member {
                memberaddr: 192.168.2.101
        }
    ringnumber: 0
    bindnetaddr: 192.168.2.0
    mcastport: 5405
    netmtu: 1480
    ttl: 1
  }
}

nodelist {
  node {
    ring0_addr: 192.168.2.101
    name: RPi1
    nodeid: 1
  }
  node {
    ring0_addr: 192.168.2.100
    name: RPi2
    nodeid: 2
  }
}

logging {
        fileline: off
        to_stderr: yes
        to_logfile: no
        to_syslog: yes
        syslog_facility: daemon
        debug: off
        timestamp: on
        logger_subsys {
                subsys: AMF
                debug: off
                tags: enter|leave|trace1|trace2|trace3|trace4|trace6
        }
}

amf {
        mode: disabled
}

Die authentication hab ich aus, zum einen weil ich die RaspberryPis in einem eigenen Netz hab und zum anderen bringt es auf den schwachen RPis etwas mehr Geschwindigkeit.
Für Tests ok, für alles Produktive ein totales No-Go.

Nach einem Reboot kann nun der Zustand kontrolliert werden (und alle Nodes bis auf einen zum Secondary degradieren):

crm status
crm node standby RPi2
corosync-cfgtool -s
corosync-objctl | grep member



 

 

...Fortsetzung folgt... weiter in Arbeit