Canonicals Hypertainer LXD 3.0 LTS ist nach LXD 2.0 vor zwei Jahren die zweite Version der Anwendung, die Langzeituntersützung erhält. Nun folgte LXC 3.0 sowie das Dateisystem LXCFS 3.0, ebenfalls jeweils als LTS-Versionen.
Die größte Neuerung bei LXD 3.0 ist die Einführung der Clustering-Unterstützung. Dadurch können identisch konfigurierte LXD-Server zu einem Cluster zusammengefügt werden, der nach außen hin als ein großer LXD-Server erscheint. Die LXD-Datenbank wird mit dqlite5, einer Kombination aus Sqlite3 und Raft repliziert, sodass drei der Cluster-Mitglieder jederzeit eine Kopie der gesamten Datenbank haben.
Vorbereitung
Um LXD in der (benötigten) Version 3.0 zu installieren benötigen wir Snapd.
apt install snapd
Mit Snapd installieren wir nun LXD:
snap install lxd
$ lxc --version
3.0.0
$ lxd --version
3.0.0
Cluster erstellen
Schon bei der ersten Initialisierung zeigen sich die ersten großen Unterschiede.
Z.B. ist gleich die erste Frage ob wir einen Cluster erstellen wollen oder nicht und nun ist die Konfigurierung der LXD-Bridge auch im gleichen Stil gehalten und es öffnet sich nicht extra ein ncurse -UI.
Installation des ersten Nodes
$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: yes
What name should be used to identify this node in the cluster? [default=LXC-Host01]:
What IP address or DNS name should be used to reach this node? [default=192.168.2.29]:
Are you joining an existing cluster? (yes/no) [default=no]:
Setup password authentication on the cluster? (yes/no) [default=yes]:
Trust password for new clients:
Again:
Do you want to configure a new local storage pool? (yes/no) [default=yes]:
Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]:
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]: yes
Path to the existing block device: /dev/sdb
Do you want to configure a new remote storage pool? (yes/no) [default=no]:
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new network bridge? (yes/no) [default=yes]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
Die hier gestellten Fragen sind recht selbsterklärend und mit der Standard-Konfiguration fährt der „Normal“-Anwender sicher ganz gut.
Wichtig ist hier vor allem, dass auf die erste Frage (ob wir LXD clustering verwenden wollen) mit yes antworten und auf die Frage ob wir einem bestehenden Cluster beitreten wollen mit no antworten. Der Rest der Fragen kann dann ganz nach persönlichen Wünschen ausgefüllt werden.
Installation des zweiten Nodes
die Installationsroutine füllt man fast identisch aus wie beim ersten Node:
$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: yes
What name should be used to identify this node in the cluster? [default=LXC-Host02]:
What IP address or DNS name should be used to reach this node? [default=192.168.2.30]:
Are you joining an existing cluster? (yes/no) [default=no]: yes
IP address or FQDN of an existing cluster node: 192.168.2.29
Cluster fingerprint: e4c10cc3b143c99b2b464fc41a8b6226acefbf9eb5b5fc73d80488ef97926592
You can validate this fingerpring by running "lxc info" locally on an existing node.
Is this the correct fingerprint? (yes/no) [default=no]: yes
Cluster trust password:
All existing data is lost when joining a cluster, continue? (yes/no) [default=no] yes
Choose the local disk or dataset for storage pool "local" (empty for loop disk): /dev/sdb
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
Man gibt natürlich auch hier bei der ersten Frage an das man einen Cluster verwenden will. Der „große“ Unterschied ist hierbei, dass man auf die Frage ob man einem bestehenden Cluster beitreten will mit yes antwortet und anschließend die IP des ersten Nodes angibt, zusammen mit dem gesetzten Passwort.
Auch der angezeigte Fingerprint lässt sich leicht mit lxc info
auf dem ersten Node überprüfen.
Ich habe hierbei auf beiden Nodes eine weitere Festplatte angehangen, welche als zfs Backend Storage dient.
steuern des Clusters
des aktuelles Status jedes einzelnen Nodes des Clusters kann man sich wie folgt ausgeben lassen:
$ lxc cluster list
If this is your first time running LXD on this machine, you should also run: lxd init
To start your first container, try: lxc launch ubuntu:16.04
+------------+---------------------------+----------+--------+-------------------+
| NAME | URL | DATABASE | STATE | MESSAGE |
+------------+---------------------------+----------+--------+-------------------+
| LXC-Host01 | https://192.168.2.29:8443 | YES | ONLINE | fully operational |
+------------+---------------------------+----------+--------+-------------------+
| LXC-Host02 | https://192.168.2.30:8443 | YES | ONLINE | fully operational |
+------------+---------------------------+----------+--------+-------------------+
wenn man nun einen Container auf einem der Nodes startet…
$ lxc list
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | LOCATION |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web01 | RUNNING | 10.193.215.243 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe89:a0bb (eth0) | PERSISTENT | 0 | LXC-Host01 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web02 | RUNNING | 10.193.215.194 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe92:ca0f (eth0) | PERSISTENT | 0 | LXC-Host02 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web03 | RUNNING | 10.193.215.156 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe39:af82 (eth0) | PERSISTENT | 0 | LXC-Host01 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
wird nun auch in der letzten Spalte angezeigt, auf welchem Node der Container aktuell läuft.
Container auf einem bestimmten Node starten
Man kann bei der Erstellung eines neuen Containers per lxc launch
mit der --target
Option angebenauf welchem Node der Container gestartet werden soll.
$ lxc launch ubuntu:16.04 web04 --target LXC-Host01
Creating web04
Starting web04
$ lxc list
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS | LOCATION |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web01 | RUNNING | 10.193.215.243 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe89:a0bb (eth0) | PERSISTENT | 0 | LXC-Host01 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web02 | RUNNING | 10.193.215.194 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe92:ca0f (eth0) | PERSISTENT | 0 | LXC-Host02 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web03 | RUNNING | 10.193.215.156 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe39:af82 (eth0) | PERSISTENT | 0 | LXC-Host01 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
| web04 | RUNNING | 10.193.215.137 (eth0) | fd42:bb14:2278:4e66:216:3eff:fe4f:aa87 (eth0) | PERSISTENT | 0 | LXC-Host01 |
+-------+---------+-----------------------+-----------------------------------------------+------------+-----------+------------+
Nachteile
Der größte Nachteil an diesem Cluster-Konstrukt ist momentan das es keinerlei failover oder fallback Option zu haben scheint.
Wenn ich den ersten Node ausschalte sind nicht nur alle Container von dem entsprechenden Node nicht erreichbar sondern es betrifft auch den zweiten Node, da dieser nicht mehr regulär arbeitet und sich nicht mehr bedienen ließ und somit alle Container unbrauchbar waren.
$ lxc list
Error: Failed to fetch http://unix.socket/1.0: 500 Internal Server Error
$ lxc cluster list
Error: Failed to fetch http://unix.socket/1.0: 500 Internal Server Error
Von daher wirkt das noch auf mich wie eine Erweiterung der remote Funktion und leider nicht wie ein Cluster den man produktiv einsetzen möchte.