Docker Swarm Rebalance

Ich wollte schon immer, dass im Docker Swarm bestimmte Services auf bestimmten Nodes laufen, sofern diese aktiv sind. Und nur im Falle eines Ausfalls diese auf einen anderen umziehen.

Letzteres kann Docker Swarm ja. Aber ersteres eben nicht: Es kann kein Node (oder mehrere) als eine Art Preferred Node gesetzt werden. Wenn ein Service einmal auf einem Node läuft, dann läuft er dort, bis der Node aus fällt oder der Service aktiv verändert wird.

Auf einem Raspi kann das aber irgendwann doof werden, dem geht dann die Power oder vorher der Ram aus.

Es gibt eine Lösung im Ansatz: https://github.com/flopon/swarmconstraint🖹

Aber die ist eher so "naja". Kann nur eine Konfig.

Also genug Gründe, selbst etwas zu schreiben.

Anfangs sollte es Bash werden, es waren ja nur wenige docker-Befehle nötig: Nodes prüfen, Labels setzen.

Da aber doch einiges an Strings zu zerlegen wären, war Perl eine andere Option. Da es aber ein Python Binding für Docker gibt und ich doch endlich mal Python lernen will, war das eine Gelegenheit. Yaml kann man mit Python dann auch recht leicht einlesen, sehr gut.

Am Ende sind es dann doch über 8000 Zeilen Code geworden. Das Docker Image werde ich dann wohl irgendwann mal auf Docker-Hub veröffentlichen!

Hier einfach schonmal das Konfigfile:

 1# set to true if settings labels should be disabled, for testing
 2dryrun: true
 3
 4# interval between checks in seconds, default 60s 
 5interval: 60
 6
 7# what to balance
 8balance:
 9# name of a balance setup
10  setup1:
11# nodes that should preferrable run the service
12    primary:
13      - node1
14      - node2
15# fallback nodes if no primary is running
16    secondary:
17      - node3
18      - node4
19# name of label to set (as used by placement constraints)
20    label: "testservice"
21# true value of label if service should run on node
22    truevalue: "here"
23# a false value of label if service should not run on node
24    falsevalue: "secondary"
25# minutes to wait until reenable secondary nodes for automatic failover (so truevalue is set after primary nodes up again), default 10
26    resettime: 10
27# set all nodes to true when checker is stopped
28    trueonexit: false
29# set all secondary nodes to false when checker is stopped
30    falseonexit: false
31
32  setup2:
33    primary:
34      - node2
35    secondary:
36      - node3
37    label: "testservice2"
38    truevalue: "here"
39    falsevalue: "secondary"
40
41# exclude service on nodes if certain other (!) service is active on it
42exclude:
43# name of an exclude setup
44  excl1:
45# name of node to check
46    name: cloud
47# name of service
48    service: pihole_pihole
49# labels to set if that service is running on that node, as labelname1: value list
50    labels:
51      fluentd: secondary

siehe auch