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+ bzw. 2x PineA64+

 

Schritt 2:

Installiere das Basis OS:
Hypriot V1.1.3 (Stand Januar 2017)
Hypriot V1.9.0 (Stand July 2018)
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)

Docker Swarm (RPi Hyprio mit Docker 18.05.0-ce bzw. PineA64 Ubuntu mit Docker 18.03.1-ce) ist schnell erledigt.

 

DRBD:

So hab ich mein DRBD gebaut und installiert:

Als erstes die Grundlagen schaffen

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

systemctl disable corosync

 

Volle Kernelsourcen werden benötigt oder DRBD kompilieren wird nicht funktionieren. Linux-Header reichen nicht aus.

cd /usr/src
apt-get install linux-source-3.10.107-pine64
tar xJvf linux-source-3.10.107-pine64.tar.xz
cd linux-source-3.10.107-pine64
make headers_check
make scripts


cd /usr/src
wget http://www.linbit.com/downloads/drbd/9.0/drbd-9.0.14-1.tar.gz

tar xzvf drbd-9.0.14-1.tar.gz
cd drbd-9.0.14-1
make install

cd /usr/src
wget http://www.drbd.org/download/drbd/utils/drbd-utils-9.4.0.tar.gz

tar xzvf drbd-utils-9.4.0.tar.gz
cd drbd-utils-9.4.0
./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.
Update (2017075): DRBD/CoroSync-Cluster (Basis 2x Pine64) neu aufgebaut mit neueren Versionen (Ubuntu 16.04.4 LTS/DRBD 9.0.14/DRBD Utils 9.4.0)

 

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... vorsicht bei mehreren Sticks
    # Besser ist etwas wie:
    # disk  /dev/disk/by-partuuid/12345678-1111-2222-3333-1234567890ab;

    # kann mit blkid abgerufen werden, und ist eindeutig und Reihenfolgen unabhägig

      # 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... vorsicht bei mehreren Sticks
    # Besser ist etwas wie:
    # disk  /dev/disk/by-partuuid/12345678-1111-2222-3333-1234567890ab;

    # kann mit blkid abgerufen werden, und ist eindeutig und Reihenfolgen unabhägig


    # 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"
drbdadm status


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

/etc/exports

/nfs-server/kubedata 192.168.100.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:

systemctl enable corosync

 

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


totem {
  version: 2
  cluster_name: kubedata
  transport: udpu

  interface {
    ringnumber: 0
    bindnetaddr: 192.168.100.0
    broadcast: yes
    mcastport: 5407
  }
}

nodelist {
  node {
    ring0_addr: 192.168.100.1
  }
  node {
    ring0_addr: 192.168.100.2
  }
}

quorum {
  provider: corosync_votequorum
}

logging {
  to_logfile: yes
  logfile: /var/log/corosync/corosync.log
  to_syslog: yes
  timestamp: on
}

service {
  name: pacemaker
  ver: 1
}

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

 

ClusterIP die zwischen den Cluster-Mitgliedern wechseln kann ist in diesem Beispiel 192.168.100.10

(Diese wird bei ifconfig NICHT angezeigt... also nicht wundern).

Die Hostnamen (MyMasterHostname und MySlaveHostname) wie beim DRBD gegen die eigenen austauschen.

mkdir /kubedata
crm configure

node MyMasterHostname \
        attributes standby="on"
node MySlaveHostname \
        attributes standby="off"
primitive VIP IPaddr2 \
        params ip=192.168.100.10 cidr_netmask=24 \
        op monitor interval=10s \
        meta migration-threshold=10 \
    
primitive my_drbd ocf:linbit:drbd \
        params drbd_resource="kubedata" \
        op monitor interval="30s" role="Slave" \
        op monitor interval="29s" role="Master" \
        op start interval="0" timeout="240s" \
        op stop interval="0" timeout="100s"
ms DRBD my_drbd \
        meta master-max="1" master-node-max="1" \
        clone-max="2" clone-node-max="1" \
        notify="true" globally-unique=false
location DRBD-master-on-MyMasterHostname DRBD rule role=master 100: \#uname eq MyMasterHostname
        
primitive my_mountfs ocf:heartbeat:Filesystem \
        params device="/dev/drbd0" directory="/nfs-server/kubedata" \
        options="defaults,noatime,nodiratime,commit=600" fstype="ext4" \
        op start interval="0" timeout="60s" \
        op stop interval="0" timeout="60s"
primitive my_nfs-kernel-server lsb:nfs-kernel-server

group NFS my_mountfs my_nfs-kernel-server VIP
colocation colocation-nfs inf: NFS DRBD:Master
order nfs_after_drbd inf: DRBD:promote NFS:start

property $id="cib-bootstrap-options" \
        no-quorum-policy="ignore" \
        stonith-enabled="false" \
        dc-version="1.1.14-70404b0" \
        cluster-infrastructure="corosync" \
        expected-quorum-votes="2" \
        cluster-name="KubeCluster" \
        last-lrm-refresh="1426233152"

 

Direkt mit den Kommandos wird es ausgeführt/aktiviert. Also zum einen am besten vorschreiben und einfügen, und auch bedenken das er alles direkt aktiviert.

Hint:

delete NFS
delete colocation-nfs
delete nfs_after_drbd

 

 

Docker Swarm:

 

docker swarm init --advertise-addr 192.168.100.1

Swarm initialized: current node (....) is now a manager.

...

 

docker swarm join-token manager

To add a manager to this swarm, run the following command:

    docker swarm join --token <key> 192.168.100.1:2377

Copy&Paste auf des nächste System:

    docker swarm join --token <key> 192.168.100.1:2377

 

Warum nicht einfach worker hinzufügen?
Darum:
If the swarm loses the quorum of managers, the swarm cannot perform management tasks. If your swarm has multiple managers, always have more than two. To maintain quorum, a majority of managers must be available. An odd number of managers is recommended, because the next even number does not make the quorum easier to keep. For instance, whether you have 3 or 4 managers, you can still only lose 1 manager and maintain the quorum. If you have 5 or 6 managers, you can still only lose two.

In meinem Cluster hab ich die RPi2&3 als Manager und den RPi1 als worker laufen. Der Schwarm kann damit Administraiert werden wenn ein Manager ausfällt (>50% der Manager des Schwarms müssen aktiv sein).

 

...Fortsetzung folgt... weiter in Arbeit