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