Grundlegende Funktionen von LXD — dem Container-System in Linux

Grundlegende Funktionen von LXD — dem Container-System in Linux

LXD — ist ein Systemcontainer-Manager der nächsten Generation, so steht es geschrieben Quelle. Er bietet eine Benutzeroberfläche, die ähnlich wie virtuelle Maschinen ist, jedoch stattdessen Linux-Container verwendet.

Der LXD-Kernel — ist ein privilegierter Daemon (ein Dienst, der mit Root-Rechten ausgeführt wird), der eine REST-API über einen lokalen Unix-Socket sowie über das Netzwerk bereitstellt, sofern die entsprechende Konfiguration vorgenommen wurde. Clients wie das mit LXD gelieferte Kommandozeilenwerkzeug senden Anfragen über diese REST-API. Das bedeutet, dass es unabhängig davon, ob Sie auf den lokalen Host oder auf einen entfernten zugreifen, alles gleich funktioniert.

In diesem Artikel werden wir nicht näher auf die Konzepte von LXD eingehen und auch nicht alle verfügbaren Funktionen, die in der Dokumentation aufgeführt sind, einschließlich der jüngsten Implementierung in den neuesten Versionen von LXD, die Unterstützung für QEMU-virtuelle Maschinen parallel zu Containern bieten. Stattdessen werden wir nur die grundlegenden Funktionen zur Verwaltung von Containern kennenlernen – wir werden Speicherpools, Netzwerke einrichten, Container starten, Ressourcenlimits anwenden und auch betrachten, wie man Snapshots verwendet, damit Sie ein grundlegendes Verständnis von LXD erhalten und Container in Linux nutzen können.

Für umfassende Informationen wenden Sie sich bitte an die offizielle Quelle:

Navigation

Installation von LXD ^

Installation von LXD in Ubuntu-Distributionen ^

In der Ubuntu-Distribution 19.10 hat das Paket lxd eine Übersetzung auf Snap-Paket:

apt search lxd

lxd/eoan 1:0.7 all
  Übergangspaket - lxd -> snap (lxd)

Das bedeutet, dass zwei Pakete gleichzeitig installiert werden, eines systemweit und das andere als Snap-Paket. Die Installation von zwei Paketen im System kann ein Problem verursachen, bei dem das systemweite Paket ein Waise werden kann, wenn das Snap-Paket mit dem Snap-Paketmanager entfernt wird.

Paket finden lxd im Snap-Repository kann mit dem folgenden Befehl erfolgen:

snap find lxd

Name             Version        Zusammenfassung
lxd              3.21           System Container-Manager und API
lxd-demo-server  0+git.6d54658  Online-Software-Demo-Sitzungen mit LXD
nova             ocata          OpenStack Compute Service (nova)
nova-hypervisor  ocata          OpenStack Compute Service - KVM Hypervisor (nova)
distrobuilder    1.0            Image-Builder für LXC und LXD
fabrica          0.1            Snaps erstellen, indem man einfach ein Webformular auf...
satellite        0.1.2          Fortschrittliche, skalierbare Open-Source-Intelligence-Plattform

Wenn Sie den Befehl ausführen die Umwandlung von numerischen und textuellen Daten in die Formate kann man überprüfen, dass das Paket lxd noch nicht installiert ist:

snap list

Name  Version    Rev   Tracking  Publisher   Hinweise
core  16-2.43.3  8689  stable    canonical✓  core

Obwohl LXD ein Snap-Paket ist, muss es über das systemweite Paket installiert werden lxd, das im System die entsprechende Gruppe und die notwendigen Utilities erstellt. /usr/bin usw.

sudo apt update
sudo apt install lxd

Überprüfen wir, ob das Paket als Snap-Paket installiert ist:

snap list

Name  Version    Rev    Tracking  Publisher   Hinweise
core  16-2.43.3  8689   stable    canonical✓  core
lxd   3.21       13474  stable/...  canonical✓  -

Installation von LXD in Arch-Linux-Distributionen ^

Um das LXD-Paket im System zu installieren, müssen die folgenden Befehle ausgeführt werden, der erste aktualisiert die Liste der im Repository verfügbaren Pakete, der zweite installiert das Paket direkt:

sudo pacman -Syyu && sudo pacman -S lxd

Nach der Installation des Pakets muss der Benutzer, der LXD verwalten möchte, zur systemweiten Gruppe hinzugefügt werden lxd:

sudo usermod -a -G lxd user1

Überprüfen wir, ob der Benutzer user1 der Gruppe hinzugefügt wurde lxd:

id -Gn user1

user1 adm dialout cdrom floppy sudo audio dip video plugdev netdev lxd

Wenn die Gruppe lxd nicht in der Liste angezeigt wird, muss die Benutzersitzung erneut aktiviert werden. Dazu müssen Sie sich abmelden und wieder unter demselben Benutzer anmelden.

Aktivieren wir systemd die LXD-Dienststart beim Systemstart:

sudo systemctl enable lxd

Starten Sie den Dienst:

sudo systemctl start lxd

Überprüfen Sie den Dienststatus:

sudo systemctl status lxd

LXD-Speicher (Storage) ^

Vor Beginn der Initialisierung müssen wir verstehen, wie der Speicher in LXD logisch strukturiert ist.

Der Speicher (Speicher) besteht aus einem oder mehreren Storage Pool , der eines der unterstützten Dateisysteme wie ZFS, BTRFS, LVM oder normale Verzeichnisse verwendet. Jeder Storage Pool ist in Volumes (Storage Volume) unterteilt, die Images, Container oder Daten für andere Zwecke enthalten.

  • Images — dies sind speziell zusammengestellte Distributionen ohne den Linux-Kernel, die aus externen Quellen verfügbar sind
  • Container — dies sind bereitgestellte Distributionen aus Images, die für den Einsatz bereit sind
  • Snapshots — dies sind Zustandsbilder von Containern, zu denen man zurückkehren kann

Grundlegende Funktionen von LXD — dem Container-System in Linux

Zum Verwalten des Speichers in LXD dient der Befehl lxc storage , deren Hilfe man mit dem Schlüssel — erhalten kann lxc storage --help

Der folgende Befehl gibt eine Liste aller aus Storage Pool im LXD-Speicher:

lxc storage list

+---------+-------------+--------+--------------------------------+---------+
|  NAME   | BESCHREIBUNG | TREIBER |             QUELLE             | BENUTZT VON |
+---------+-------------+--------+--------------------------------+---------+
| hddpool |             | btrfs  | /dev/loop1                     | 2       |
+---------+-------------+--------+--------------------------------+---------+
| ssdpool |             | btrfs  | /var/lib/lxd/disks/ssdpool.img | 4       |
+---------+-------------+--------+--------------------------------+---------+

Um die Liste aller Storage Volume im gewählten Storage Pool dient der Befehl lxc storage volume list:

lxc storage volume list hddpool

+-------+----------------------------------+-------------+---------+
| TYP   |          NAME                    | BESCHREIBUNG | BENUTZT VON |
+-------+----------------------------------+-------------+---------+
| image | ebd565585223487526ddb3607f515... |             | 1       |
+-------+----------------------------------+-------------+---------+

lxc storage volume list ssdpool

+-----------+----------------------------------+-------------+---------+
|   TYP    |            NAME                  | BESCHREIBUNG | BENUTZT VON |
+-----------+----------------------------------+-------------+---------+
| container | alp3                             |             | 1       |
+-----------+----------------------------------+-------------+---------+
| container | jupyter                          |             | 1       |
+-----------+----------------------------------+-------------+---------+
| image     | ebd565585223487526ddb3607f515... |             | 1       |
+-----------+----------------------------------+-------------+---------+

Außerdem, wenn bei Storage Pool bei der Erstellung das Dateisystem BTRFS ausgewählt wurde, kann die Liste der Storage Volume oder Subvolumes im BTRFS-Kontext mit den Werkzeugen dieses Dateisystems abgerufen werden:

sudo btrfs subvolume list -p /var/lib/lxd/storage-pools/hddpool

ID 257 gen 818 parent 5 top level 5 path images/ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3

sudo btrfs subvolume list -p /var/lib/lxd/storage-pools/ssdpool

ID 257 gen 1820 parent 5 top level 5 path images/ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
ID 260 gen 1819 parent 5 top level 5 path containers/jupyter
ID 263 gen 1820 parent 5 top level 5 path containers/alp3

Initialisierung von LXD ^

Vor der Erstellung und Nutzung von Containern muss eine allgemeine Initialisierung von LXD durchgeführt werden, die das Netzwerk sowie den Speicher erstellt und konfiguriert. Dies kann manuell mit den Standardbefehlen des Clients erfolgen, die in der Liste mit dem Befehl lxc --help oder mit dem Initialisierungsassistenten lxd init beantwortet werden, nachdem man einige Fragen beantwortet hat.

Auswahl des Dateisystems für den Speicherpool ^

Während der Initialisierung stellt LXD mehrere Fragen, darunter die Bestimmung des Dateisystemtyps für das Standard- Storage Pool. Standardmäßig wird das Dateisystem BTRFS ausgewählt. Eine Änderung auf ein anderes FS nach der Erstellung wird nicht möglich sein.. Zur Auswahl des FS wird eine Vergleichstabelle der Funktionen angeboten.:

Funktion
Verzeichnis
Btrfs
LVM
ZFS
CEPH

Optimierter Bildspeicher
nein
yes
yes
yes
yes

Optimierte Instanterstellung
nein
yes
yes
yes
yes

Optimierte Snapshot-Erstellung
nein
yes
yes
yes
yes

Optimierter Bildtransfer
nein
yes
nein
yes
yes

Optimierter Instanztransfer
nein
yes
nein
yes
yes

Kopie bei Schreibzugriff
nein
yes
yes
yes
yes

Blockbasiert
nein
nein
yes
nein
yes

Sofortige Klonung
nein
yes
yes
yes
yes

Speicher-Driver, der innerhalb eines Containers genutzt werden kann
yes
yes
nein
nein
nein

Wiederherstellung von älteren Snapshots (nicht dem neuesten)
yes
yes
yes
nein
yes

Speicherquoten
ja(*)
yes
yes
yes
nein

Einrichtung von Netzwerk und Speicherpool mit dem Assistenten ^

Der nächste Befehl, den wir betrachten werden, bietet die Möglichkeit, die grundlegenden Komponenten von LXD durch Antworten auf einfache Fragen mithilfe des Initialisierungsassistenten zu konfigurieren.

Führen Sie den Befehl aus lxc init und geben Sie die Antworten auf die Fragen nach dem Doppelpunkt ein, wie im folgenden Beispiel gezeigt oder ändern Sie sie gemäß Ihren Bedingungen:

lxd init

Möchten Sie LXD-Clustering verwenden? (ja/nein) [Standard=no]: 
Möchten Sie einen neuen Speicherpool konfigurieren? (ja/nein) [Standard=ja]: 
Name des neuen Speicherpools [Standard=default]: ssdpool         
Name des verwendeten Speicher-Backends (lvm, btrfs, dir) [Standard=btrfs]: 
Möchten Sie einen neuen BTRFS-Pool erstellen? (ja/nein) [Standard=ja]: 
Möchten Sie ein vorhandenes Blockgerät verwenden? (ja/nein) [Standard=nein]: 
Größe in GB des neuen Loop-Geräts (mindestens 1 GB) [Standard=15GB]: 10GB
Möchten Sie sich mit einem MAAS-Server verbinden? (ja/nein) [Standard=nein]: 
Möchten Sie einen neuen lokalen Netzwerkbrücke erstellen? (ja/nein) [Standard=ja]: 
Wie soll die neue Brücke heißen? [Standard=lxdbr0]: 
Welche IPv4-Adresse soll verwendet werden? (CIDR-Subnetznotation, „auto“ oder „none“) [Standard=auto]: 10.0.5.1/24
Möchten Sie, dass LXD den IPv4-Verkehr in Ihrem Netzwerk brückt? [Standard=ja]: 
Welche IPv6-Adresse soll verwendet werden? (CIDR-Subnetznotation, „auto“ oder „none“) [Standard=auto]: none
Möchten Sie, dass LXD über das Netzwerk verfügbar ist? (ja/nein) [Standard=nein]: 
Möchten Sie, dass veraltete zwischengespeicherte Bilder automatisch aktualisiert werden? (ja/nein) [Standard=ja] nein
Möchten Sie, dass eine YAML "lxd init" vordefiniert ausgedruckt wird? (ja/nein) [Standard=nein]: 

Erstellung eines zusätzlichen Speicherpools ^

Im vorherigen Schritt haben wir erstellt, Storage Pool dem wir den Namen gegeben haben ssdpool und dessen Datei sich in meinem System unter der Adresse befindet /var/lib/lxd/disks/ssdpool.img. Diese Adresse des Dateisystems entspricht einer physischen SSD-Festplatte in meinem PC.

In den nächsten Schritten, um ein besseres Verständnis dafür zu gewinnen, welche Rolle spielt Storage Pool im Speicher, werden wir einen zweiten Storage Pool erstellen, der physisch auf einem anderen Festplattentyp, einer HDD, liegen wird. Das Problem ist, dass LXD nicht zulässt, dass Storage Pool außerhalb der Adresse /var/lib/lxd/disks/ und selbst symbolische Links werden nicht funktionieren, siehe die Antwort des Entwicklers.Um diese Einschränkung zu umgehen, können wir beim Initialisieren/Formatieren Storage Pool den Wert als Blockgerät angeben, anstatt einen Pfad zur Loopback-Datei in dem Schlüssel festzulegen. source.

Also, bevor wir erstellen Storage Pool Es ist notwendig, eine Loopback-Datei oder eine vorhandene Partition in Ihrem Dateisystem zu bestimmen, die er verwenden wird. Dazu erstellen wir eine Datei, die wir auf 10 GB begrenzen:

dd if=\/dev\/zero of=\/mnt\/work\/lxd\/hddpool.img bs=1MB count=10000

10000+0 Datensätze ein
10000+0 Datensätze aus
10000000000 Bytes (10 GB, 9,3 GiB) kopiert, 38,4414 s, 260 MB\/s

Wir binden die Loopback-Datei an ein freies Loopback-Gerät an:

sudo losetup --find --show \/mnt\/work\/lxd\/hddpool.img

\/dev\/loop1

Durch den Schalter --show gibt der Befehl den Gerätenamen zurück, an den unsere Loopback-Datei gebunden wurde. Bei Bedarf können wir eine Liste aller belegten Geräte dieses Typs anzeigen, um die Korrektheit unserer Aktionen zu überprüfen:

losetup -l

NAME       SIZELIMIT OFFSET AUTOCLEAR RO BACK-FILE                      DIO LOG-SEC
\/dev\/loop1         0      0         0  0 \/mnt\/work\/lxd\/hddpool.img        0     512
\/dev\/loop0         0      0         1  0 \/var\/lib\/lxd\/disks\/ssdpool.img   0     512

Aus der Liste ist ersichtlich, dass im Gerät /dev/loop1 die Loopback-Datei angebunden ist, /mnt/work/lxd/hddpool.img, und im Gerät /dev/loop0 die Loopback-Datei angebunden ist, /var/lib/lxd/disks/ssdpool.img das dem Standard entspricht. Storage Pool.

Der nächste Befehl erstellt einen neuen Storage Pool in LXD auf Basis der gerade vorbereiteten Loopback-Datei. LXD formatiert die Loopback-Datei /mnt/work/lxd/hddpool.img im Gerät /dev/loop1 unter dem BTRFS-Dateisystem:

lxc storage create hddpool btrfs size=10GB source=\/dev\/loop1

Lassen Sie uns eine Liste aller Storage Pool anzeigen:

lxc storage list

+---------+-------------+--------+--------------------------------+---------+
|  NAME   | DESCRIPTION | DRIVER |             SOURCE             | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| hddpool |             | btrfs  | \/dev\/loop1                     | 0       |
+---------+-------------+--------+--------------------------------+---------+
| ssdpool |             | btrfs  | \/var\/lib\/lxd\/disks\/ssdpool.img | 0       |
+---------+-------------+--------+--------------------------------+---------+

Erhöhung der Größe des Speicherpools ^

Nach der Erstellung kann er bei Bedarf erweitert werden. Für Storage Poolbasiert auf dem BTRFS-Dateisystem, führen Sie die folgenden Befehle aus: Storage Pool sudo truncate -s +5G \/mnt\/work\/lxd\/hddpool.img sudo losetup -c \/dev\/loop1 sudo btrfs filesystem resize max \/var\/lib\/lxd\/storage-pools\/hddpool

Wir haben ein kleines Problem: Bei einem Neustart des Host-Systems wird die Datei

Automatisches Einfügen einer Loopback-Datei in den Slot des Loopback-Geräts ^

"aus dem Gerät "fliegen" /mnt/work/lxd/hddpool.img und der LXD-Dienst wird beim Starten abstürzen, da er ihn in diesem Gerät nicht sehen kann. Um dieses Problem zu lösen, müssen wir einen Systemdienst erstellen, der diese Datei beim Start des Host-Systems in das Gerät einfügt. /dev/loop1 Erstellen wir /dev/loop1 eine Datei vom Typ

für das Init-System SystemD: Unit cat << EOF | sudo tee -a \/etc\/systemd\/system\/lxd-hddpool.service [Unit] Description=Losetup LXD Storage Pool (hddpool) After=local-fs.target[Service] Type=oneshot ExecStart=\/sbin\/losetup \/dev\/loop1 \/mnt\/work\/lxd\/hddpool.img RemainAfterExit=true[Install] WantedBy=local-fs.target EOF service in /etc/systemd/system/ Aktivieren Sie den Dienst:

Aktivieren wir den Dienst:

Aktivieren Sie den Dienst:

sudo systemctl aktivieren lxd-hddpool

Symlink erstellt /etc/systemd/system/local-fs.target.wants/lxd-hddpool.service → /etc/systemd/system/lxd-hddpool.service.

Nach dem Neustart des Hostsystems überprüfen wir den Status des Dienstes:

systemctl status lxd-hddpool.service 

● lxd-hddpool.service - Losetup LXD Storage Pool (hddpool)
     Loaded: geladen (/etc/systemd/system/lxd-hddpool.service; aktiviert; Voreinstellung des Anbieters: deaktiviert)
     Active: aktiv (beendet) seit Mi 2020-04-08 03:43:53 MSK; vor 1min 37s
    Process: 711 ExecStart=/sbin/losetup /dev/loop1 /mnt/work/lxd/hddpool.img (code=beendet, status=0/ERFOLG)
   Main PID: 711 (code=beendet, status=0/ERFOLG)

apr 08 03:43:52 manjaro systemd[1]: Starte Losetup LXD Storage Pool (hddpool)...
apr 08 03:43:53 manjaro systemd[1]: Losetup LXD Storage Pool (hddpool) abgeschlossen.

Aus der Ausgabe können wir erkennen, dass der Status des Dienstes gleich ist active, obwohl die Ausführung unseres Skripts aus einem einzigen Befehl abgeschlossen wurde, hat uns die Option erlaubt, das zu tun RemainAfterExit=true.

Sicherheit. Containerberechtigungen ^

Da alle Prozesse des Containers tatsächlich isoliert auf dem Hostsystem unter Verwendung seines Kernels ausgeführt werden, bietet LXD zur zusätzlichen Absicherung des Zugriffs der Containerprozesse auf das Hostsystem die Privilegierung von Prozessen, wobei:

  • Privilegierte Container — das sind Container, in denen die Prozesse die gleiche UID und GID wie der Besitzer auf dem Hostsystem haben. Zum Beispiel hat ein Prozess, der in einem Container mit einer UID von 0 ausgeführt wird, die gleichen Zugriffsrechte wie der Prozess des Hostsystems mit einer UID von 0. Mit anderen Worten, der Root-Benutzer im Container hat alle Rechte nicht nur im Container, sondern auch auf dem Hostsystem, wenn er außerhalb des isolierten Namensraums des Containers gelangen kann.

  • Unprivilegierte Container — das sind Container, in denen die Prozesse einem Eigentümer mit einer UID und GID von 0 bis 65535 gehören, aber für das Hostsystem wird der Eigentümer durch ein hinzugefügtes SubUID- und SubGID-Bit maskiert. Zum Beispiel wird ein Benutzer mit UID=0 im Container auf dem Hostsystem als SubUID + UIDentdeckt. Dies schützt das Hostsystem, da, falls ein Prozess im Container aus seinem isolierten Namensraum ausbrechen kann, er nur als Prozess mit einer unbekannten, sehr hohen UID/GID mit dem Hostsystem interagieren kann.

Standardmäßig haben neu erstellte Container den Status unprivilegiert, daher müssen wir SubUID und SubGID festlegen.

Wir erstellen zwei Konfigurationsdateien, in denen wir die Maske für SubUID und SubGID festlegen:

sudo touch /etc{/subuid,/subgid}
sudo usermod --add-subuids 1000000-1065535 root 
sudo usermod --add-subgids 1000000-1065535 root

Um Änderungen anzuwenden, muss der LXD-Dienst neu gestartet werden:

sudo systemctl restart lxd

Erstellung eines virtuellen Netzwerkswitches ^

Da wir zuvor das Netzwerk mit dem Initialisierungsassistenten eingerichtet haben lxd init und ein Netzwerkgerät erstellt haben lxdbr0, werden wir uns in diesem Abschnitt einfach mit dem Netzwerk in LXD vertraut machen und lernen, wie man einen virtuellen Switch (Netzwerkbrücke) mit dem Client-Befehl erstellt.

Das folgende Diagramm zeigt, wie der Switch (Netzwerkbrücke) den Host und die Container in ein Netzwerk verbindet:

Grundlegende Funktionen von LXD — dem Container-System in Linux

Container können über das Netzwerk mit anderen Containern oder dem Host, auf dem diese Container betrieben werden, kommunizieren. Dazu müssen die virtuellen Netzwerkkarten der Container mit dem virtuellen Switch verbunden werden. Zunächst erstellen wir den Switch, während die Netzwerkinterfaces der Container in den folgenden Kapiteln verknüpft werden, nachdem der Container erstellt wurde.

Der folgende Befehl erstellt einen Switch mit einer Subnetze 10.0.5.0/24 und einer IPv4-Adresse 10.0.5.1/24, und aktiviert ipv4.nat , damit die Container über den Host mit NAT-Dienst ins Internet gelangen können:

lxc network create lxdbr0 ipv4.address=10.0.5.1/24 ipv4.nat=true ipv6.address=none

Überprüfen Sie die Liste der verfügbaren LXD-Netzwerkgeräte:

lxc network list

+--------+----------+---------+-------------+---------+
|  NAME  |   TYPE   | MANAGED | DESCRIPTION | USED BY |
+--------+----------+---------+-------------+---------+
| eno1   | physical | NEIN    |             | 0       |
+--------+----------+---------+-------------+---------+
| lxdbr0 | bridge   | JA      |             | 0       |
+--------+----------+---------+-------------+---------+

Sie können auch die Erstellung des Netzwerkgeräts mit dem Standardtool des Linux-Distros überprüfen — ip link oder ip addr:

ip addr

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eno1:  mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether bc:ee:7b:5a:6b:44 brd ff:ff:ff:ff:ff:ff
    altname enp0s25
    inet6 fe80::9571:11f3:6e0c:c07b/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: lxdbr0:  mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether c2:38:90:df:cb:59 brd ff:ff:ff:ff:ff:ff
    inet 10.0.5.1/24 scope global lxdbr0
       valid_lft forever preferred_lft forever
    inet6 fe80::c038:90ff:fedf:cb59/64 scope link 
       valid_lft forever preferred_lft forever
5: veth3ddab174@if4:  mtu 1500 qdisc noqueue master lxdbr0 state UP group default qlen 1000
    link/ether ca:c3:5c:1d:22:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0

Konfigurationsprofil ^

Jeder Container in LXD hat seine eigene Konfiguration und kann diese durch global deklarierte Konfigurationen, die als Konfigurationsprofile. Die Anwendung von Konfigurationsprofilen auf einen Container folgt einem kaskadierenden Modell, das im folgenden Beispiel demonstriert wird:

Grundlegende Funktionen von LXD — dem Container-System in Linux

In diesem Beispiel wurden im LXD-System drei Profile erstellt: default, hddpool und hostfs. Alle drei Profile sind auf einen Container angewendet, der über eine lokale Konfiguration (graue Zone) verfügt. Das Profil default hat ein Gerät root dessen Parameter pool , dann wird diese Funktion den Socket mit der Option ssdpool, aber dank des kaskadierenden Modells der Anwendung von Konfigurationen können wir für den Container das Profil anwenden, hddpool dessen Parameter pool das diesen gleichen Parameter aus dem Profil überschreibt, default und der Container erhält die Gerätekonfiguration root und dem Parameter pool siehe hddpool, während das Profil hostfs einfach ein neues Gerät zum Container hinzufügt.

Um die Liste der verfügbaren Konfigurationsprofile zu sehen, dient der folgende Befehl:

lxc profile list

+---------+---------+
|  NAME   | USED BY |
+---------+---------+
| standard | 1       |
+---------+---------+
| hddroot | 0       |
+---------+---------+
| ssdroot | 1       |
+---------+---------+

Die vollständige Liste der verfügbaren Befehle zur Arbeit mit Profilen kann erhalten werden, indem man den Schalter --help:

lxc profile --help

Beschreibung:
  Profile verwalten

Verwendung:
  lxc profile [Befehl]

Verfügbare Befehle:
  add         Profile zu Instanzen hinzufügen
  assign      Profile-Sets Instanzen zuweisen
  copy        Profile kopieren
  create      Profile erstellen
  delete      Profile löschen
  device      Instanzgeräte verwalten
  edit        Profilkonfigurationen als YAML bearbeiten
  get         Werte für Profilkonfigurationsschlüssel abrufen
  list        Profile auflisten
  remove      Profile von Instanzen entfernen
  rename      Profile umbenennen
  set         Profilkonfigurationsschlüssel setzen
  show        Profilkonfigurationen anzeigen
  unset       Profilkonfigurationsschlüssel zurücksetzen

Profil bearbeiten ^

Das Standardkonfigurationsprofil default hat keine Netzwerkkonfiguration für den Container, und alle neu erstellten Container haben kein Netzwerk. Für sie müssen lokale (dedizierte) Netzwerkgeräte mit einem separaten Befehl erstellt werden, aber wir können im Konfigurationsprofil ein globales Netzwerkgerät erstellen, das von allen Containern, die dieses Profil verwenden, geteilt wird. Somit haben sie direkt nach dem Befehl zur Erstellung eines neuen Containers Zugang zum Netzwerk. Dabei gibt es keine Einschränkungen; wir können später immer ein lokales Netzwerkgerät erstellen, wenn dies erforderlich ist.

Der nächste Befehl fügt dem Konfigurationsprofil das Gerät eth0 des Typs nic verbunden mit dem Netzwerk lxdbr0:

lxc profile device add default eth0 nic network=lxdbr0 name=eth0

Es ist wichtig zu beachten, dass, da wir das Gerät tatsächlich dem Konfigurationsprofil hinzugefügt haben, alle Container, die dieses Profil verwenden, die gleiche IP-Adresse teilen, wenn wir eine statische IP-Adresse für das Gerät angeben. Wenn es notwendig ist, einen Container mit einer dedizierten statischen IP-Adresse zu erstellen, sollte eine Netzwerkkonfiguration auf der Containerebene (lokale Konfiguration) mit der IP-Adresse vorgenommen werden, anstatt auf der Profil-Ebene.

Überprüfen wir das Profil:

lxc profile show default

config: {}
beschreibung: Standard LXD-Profil
geräte:
  eth0:
    name: eth0
    netzwerk: lxdbr0
    typ: nic
  root:
    pfad: \
    pool: ssdpool
    typ: disk
name: default
used_by: []

In diesem Profil sehen wir, dass für alle neu erstellten Container zwei Geräte (devices) erstellt werden:

  • eth0 — Gerät vom Typ nic verbunden mit einem Switch (Netzwerkbrücke) lxdbr0
  • root — Gerät vom Typ disk das den Speicherspeicherpool verwendet ssdpool

Erstellung neuer Profile ^

Um die zuvor erstellten Storage Pool Container zu nutzen, erstellen wir ein Konfigurationsprofil ssdroot in das wir ein Gerät vom Typ disk mit dem Mount-Punkt / (root) hinzufügen, das den zuvor erstellten Storage Poolssdpool:

lxc profile create ssdroot
lxc profile device add ssdroot root disk path=\ pool=ssdpool

Ähnlich erstellen wir ein Gerät vom Typ disk, aber in diesem Fall verwenden wir Storage Poolhddpool:

lxc profile create hddroot
lxc profile device add hddroot root disk path=\ pool=hddpool

Überprüfen wir die Konfigurationsprofile:

lxc profile show ssdroot

config: {}
beschreibung: ""
geräte:
  root:
    pfad: \
    pool: ssdpool
    typ: disk
name: ssdroot
used_by: []

lxc profile show hddroot

config: {}
beschreibung: ""
geräte:
  root:
    pfad: \
    pool: hddpool
    typ: disk
name: hddroot
used_by: []

Bild-Repository ^

Container werden aus Images erstellt, die speziell gebaute Distributionen sind, die keinen Linux-Kernel haben. Daher muss ein Container, bevor er gestartet werden kann, aus diesem Image entpackt werden. Die Quelle der Images ist ein lokales Repository, in das Images aus externen Repositories hochgeladen werden.

Entfernte Bild-Repositories ^

Standardmäßig ist LXD so konfiguriert, dass es Images von drei entfernten Quellen erhält:

  • ubuntu: (für stabile Ubuntu-Images)
  • ubuntu-daily: (für tägliche Ubuntu-Images)
  • images: (für eine Reihe anderer Distributionen)

lxc remote list

+-----------------+------------------------------------------+--------+--------+
|      NAME       |                   URL                    | PUBLIC | STATIC |
+-----------------+------------------------------------------+--------+--------+
| images          | https://images.linuxcontainers.org       | JA     | NEIN   |
+-----------------+------------------------------------------+--------+--------+
| local (default) | unix://                                  | NEIN   | JA     |
+-----------------+------------------------------------------+--------+--------+
| ubuntu          | https://cloud-images.ubuntu.com/releases | JA     | JA     |
+-----------------+------------------------------------------+--------+--------+
| ubuntu-daily    | https://cloud-images.ubuntu.com/daily    | JA     | JA     |
+-----------------+------------------------------------------+--------+--------+

Zum Beispiel hat das Repository ubuntu: die folgenden Images:

lxc image -c dasut list ubuntu: | head -n 11

+----------------------------------------------+--------------+----------+------------+
|                   BESCHREIBUNG               | ARCHITEKTUR  |   GRÖSSE  |   TYP      |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150728)  | x86_64       | 153.72MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150819)  | x86_64       | 152.91MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150906)  | x86_64       | 154.69MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150930)  | x86_64       | 153.86MB | CONTAINER  |
+----------------------------------------------+--------------+----------+------------+

Um eine begrenzte Anzahl von Spalten anzuzeigen, haben wir die Option -c mit den Parametern dasut, und haben außerdem die Länge der Liste mit dem Befehl eingeschränkt. head.

Für die Ausgabe der Liste der verfügbaren Images steht eine Filterung zur Verfügung. Der folgende Befehl gibt die Liste aller verfügbaren Architekturen der Distribution AlpineLinux:

lxc image -c ldast list images:alpine/3.11

+------------------------------+--------------------------------------+--------------+
|            ALIAS             |             BESCHREIBUNG            | ARCHITEKTUR |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11 (3 weitere)       | Alpine 3.11 amd64 (20200220_13:00)   | x86_64       |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/arm64 (1 weiteres) | Alpine 3.11 arm64 (20200220_13:00)   | aarch64      |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/armhf (1 weiteres) | Alpine 3.11 armhf (20200220_13:00)   | armv7l       |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/i386 (1 weiteres)  | Alpine 3.11 i386 (20200220_13:01)    | i686         |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/ppc64el (1 weiteres) | Alpine 3.11 ppc64el (20200220_13:00) | ppc64le      |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/s390x (1 weiteres)  | Alpine 3.11 s390x (20200220_13:00)   | s390x        |
+------------------------------+--------------------------------------+--------------+

Lokales Bild-Repository ^

Um mit der Nutzung des Containers zu beginnen, muss ein Image aus dem globalen Repository in das lokale hinzugefügt werden. local:. Der lokale Repository ist momentan leer, das zeigt uns der Befehl lxc image list. Wenn der Methode die Umwandlung von numerischen und textuellen Daten in die Formate kein Repository angegeben wird, wird standardmäßig das lokale Repository verwendet — local:

lxc image list local:

+-------+-------------+--------+-------------+--------------+------+------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE |
+-------+-------------+--------+-------------+--------------+------+------+

Die Verwaltung von Images im Repository erfolgt durch die folgenden Methoden:

Team
Beschreibung

lxc image Alias
Image-Alias verwalten

lxc image copy
Images zwischen Servern kopieren

lxc image delete
Images löschen

lxc image edit
Image-Eigenschaften bearbeiten

lxc image export
Images exportieren und herunterladen

lxc image import
Images in den Image-Speicher importieren

lxc image info
Nützliche Informationen über Images anzeigen

lxc image die Umwandlung von numerischen und textuellen Daten in die Formate
Images auflisten

lxc image -Token anfordern.
Images aktualisieren

lxc image show
Image-Eigenschaften anzeigen

Wir kopieren das Image aus dem globalen Repository in das lokale. images::

lxc image copy images:alpine/3.11/amd64 local: --alias=alpine3

Image erfolgreich kopiert!

Lass uns eine Liste aller aktuell verfügbaren Images im lokalen Repository ausgeben. local::

lxc image -c lfdatsu list local:

+---------+--------------+------------------------------------+--------------+
|  ALIAS  | FINGERPRINT  |            DESCRIPTION             | ARCHITECTURE |
+---------+--------------+------------------------------------+--------------+
| alpine3 | 73a3093d4a5c | Alpine 3.11 amd64 (20200220_13:00) | x86_64       |
+---------+--------------+------------------------------------+--------------+

LXD-Konfiguration ^

Neben dem interaktiven Modus unterstützt LXD auch einen nicht-interaktiven Modus zur Konfiguration, bei dem die Konfiguration in Form einer YAML-Datei übergeben wird, einem speziellen Format, das es ermöglicht, die gesamte Konfiguration auf einmal zu setzen, ohne viele interaktive Befehle auszuführen, die zuvor in diesem Artikel behandelt wurden, einschließlich Netzwerkkonfiguration, Erstellung von Konfigurationsprofilen usw. Wir werden diesen Bereich hier nicht behandeln, Sie können sich damit selbst beschäftigen. Dokumentation.

Der nächste interaktive Befehl lxc config den wir betrachten werden, ermöglicht die Konfiguration. Um beispielsweise zu verhindern, dass heruntergeladene Images im lokalen Repository automatisch aus den globalen Repositories aktualisiert werden, können wir dieses Verhalten mit dem folgenden Befehl aktivieren:

lxc config set images.auto_update_cached=false

Erstellung und Verwaltung von Containern ^

Um einen Container zu erstellen, используется кон mandateать команду lxc init die die Werte repository:image und dann die gewünschte ID für den Container erhält. Das Repository kann als lokal angegeben werden. local: so wie jede globale. Wenn das Repository nicht angegeben ist, wird standardmäßig das lokale Repository zur Bildsuche verwendet. Wenn das Bild aus dem globalen Repository angegeben ist, wird das Bild zuerst in das lokale Repository heruntergeladen und dann zur Erstellung des Containers verwendet.

Führen wir den folgenden Befehl aus, um unseren ersten Container zu erstellen:

lxc init alpine3 alp --storage=hddpool --profile=default --profile=hddroot

Lassen Sie uns die Schlüsselfunktionen des Befehls, die wir hier verwenden, der Reihe nach durchgehen:

  • alpine3 — Gibt den Alias (Pseudonym) für das Bild an, das zuvor im lokalen Repository hochgeladen wurde. Wenn für dieses Bild kein Alias erstellt wurde, kann immer auf das Bild über seine Fingerabdruck verwiesen werden, das in der Tabelle ausgegeben wird.
  • alp — Legt die Kennung für den Container fest
  • --storage — Dieser Schlüssel gibt an, in welchem Storage Pool der Container erstellt wird
  • --profile — Diese Schlüssel wenden die Konfiguration aus zuvor erstellten Profilen kaskadierend auf den Container an

Wir starten den Container, der beginnt, das Init-System der Distribution zu starten:

lxc start alp

Außerdem kann der Befehl lxc launch verwendet werden, um die Befehle lxc init und lxc start in eine Operation zu kombinieren.

Wir überprüfen den Status des Containers:

lxc list -c ns46tb
+------+---------+------------------+------+-----------+--------------+
| NAME |  STATE  |       IPV4       | IPV6 |   TYPE    | STORAGE POOL |
+------+---------+------------------+------+-----------+--------------+
| alp  | RUNNING | 10.0.5.46 (eth0) |      | CONTAINER | hddpool      |
+------+---------+------------------+------+-----------+--------------+

Wir überprüfen die Konfiguration des Containers:

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200326_13:39)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200326_13:39"
  image.type: squashfs
  volatile.base_image: ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
  volatile.eth0.host_name: vethb1fe71d8
  volatile.eth0.hwaddr: 00:16:3e:5f:73:3e
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: RUNNING
devices:
  root:
    path: \
    pool: hddpool
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

Im Abschnitt profiles wir können sicherstellen, dass dieser Container zwei Konfigurationsprofile verwendet — default und hddroot. Im Abschnitt devices finden wir nur ein Gerät, da das Netzwerkgerät auf Profilebene erstellt wurde. default. Um alle vom Container verwendeten Geräte anzuzeigen, müssen Sie den Schlüssel hinzufügen --expanded:

lxc config show alp --expanded

architektur: x86_64
konfiguration:
  image.architektur: amd64
  image.beschreibung: Alpine 3.11 amd64 (20200326_13:39)
  image.betriebssystem: Alpine
  image.version: "3.11"
  image.serial: "20200326_13:39"
  image.typ: squashfs
  volatile.base_image: ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
  volatile.eth0.host_name: vethb1fe71d8
  volatile.eth0.hwaddr: 00:16:3e:5f:73:3e
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: RUNNING
geräte:
  eth0:
    name: eth0
    netzwerk: lxdbr0
    typ: nic
  root:
    pfad: \/
    pool: hddpool
    typ: festplatte
ephemeral: false
profile:
- standard
- hddroot
zustandsbehaftet: false
beschreibung: ""

Festlegen einer statischen IP-Adresse ^

Wenn wir versuchen, eine IP-Adresse für das Netzwerkgerät eth0 Wir setzen ein eigenes Passwort für den Benutzer lxc config device set alp zu konfigurieren, erhalten wir einen Fehler, der besagt, dass das Gerät nicht existiert, da das Gerät eth0 das vom Container verwendet wird, dem Profil gehört default:

lxc config device set alp eth0 ipv4.address 10.0.5.5

Fehler: Das Gerät existiert nicht

Wir können natürlich eine statische IP-Adresse für eth0 das Gerät im Profil festlegen, aber sie wird für alle Container, die dieses Profil verwenden, gleich sein. Daher fügen wir ein dediziertes Gerät für den Container hinzu:

lxc config device add alp eth0 nic name=eth0 nictype=bridged parent=lxdbr0 ipv4.address=10.0.5.5

Danach müssen wir den Container neu starten:

lxc restart alp

Wenn wir uns jetzt die Konfiguration des Containers ansehen, müssen wir die Option nicht mehr anwenden --expanded um das Netzwerkgerät zu sehen eth0, da wir es auf Container-Ebene erstellt haben und es dieses Gerät aus dem Profil überlagert hat. default:

lxc config show alp

Architektur: x86_64
Konfiguration:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200326_13:39)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200326_13:39"
  image.type: squashfs
  volatile.base_image: ebd565585223487526ddb3607f5156e875c15a89e21b61ef004132196da6a0a3
  volatile.eth0.host_name: veth2a1dc59d
  volatile.eth0.hwaddr: 00:16:3e:0e:e2:71
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.idmap: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":65536},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":65536}]'
  volatile.last_state.power: LAUFEND
Geräte:
  eth0:
    ipv4.adresse: 10.0.5.5
    name: eth0
    nictype: bridged
    parent: lxdbr0
    typ: nic
  root:
    pfad: \/
    pool: hddpool
    typ: disk
ephemeral: false
profile:
- standard
- hddroot
zustandsbehaftet: false
beschreibung: ""

Löschen eines Containers ^

Zum Löschen des Containers verwenden Sie den Befehl lxc delete, aber bevor Sie den Container löschen, muss er mit dem Befehl gestoppt werden lxc stop:

lxc stop alp

lxc list

+------+---------+-------------------+------+-----------+-----------+
| NAME |  STATUS |       IPV4        | IPV6 |   TYP     | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| alp  | STOPPED | 10.0.5.10 (eth0)  |      | CONTAINER | 0         |
+------+---------+-------------------+------+-----------+-----------+

Nachdem wir sichergestellt haben, dass der Zustand des Containers STOPPED, kann er aus Storage Pool:

lxc delete alp

Zugriff auf den Container ^

Um Befehle im Container direkt, ohne Netzwerkverbindungen, auszuführen, verwenden Sie den Befehl lxc exec , der Befehle im Container ohne Aufruf einer Shell ausführt. Wenn Sie einen Befehl in einer Shell ausführen müssen, die Shell-Muster wie Variablen, Dateiweiterleitungen (Pipe) usw. verwendet, müssen Sie ausdrücklich die Shell aufrufen und den Befehl als Argument übergeben, zum Beispiel:

lxc exec alp -- \/bin\/sh -c "echo $HOME"

Im Befehl wurde ein Escape-Zeichen verwendet für das Sonderzeichen $ damit die Variable $HOME nicht auf der Hostmaschine interpretiert wird, sondern nur innerhalb des Containers interpretiert wird.

Es ist auch möglich, den interaktiven Modus der Shell zu starten und die Sitzung nach Beendigung mit der Tastenkombination CTRL+D:

lxc exec alp -- \/bin\/sh

Ressourcenverwaltung des Containers ^

In LXD kann man die Ressourcen des Containers mit einer speziellen Konfiguration verwalten. Eine vollständige Liste der Konfigurationsparameter des Containers finden Sie Dokumentation.

RAM-Ressourcenlimit ^

Parameter limits.memory beschränkt den verfügbaren RAM für den Container. Als Wert wird eine Zahl und einer der verfügbaren Suffixe.

Setzen wir eine Begrenzung für den RAM des Containers auf 256 MB:

lxc config set alp limits.memory 256MB

Es gibt auch andere Parameter zur Einschränkung des Speichers:

  • limits.memory.enforce
  • limits.memory.hugepages
  • limits.memory.swap
  • limits.memory.swap.priority

Team lxc config show zeigt die gesamte Konfiguration des Containers an, einschließlich der festgelegten Ressourcensperre:

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200220_13:00)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200220_13:00"
  image.type: squashfs
  limits.memory: 256MB
  volatile.base_image: 73a3093d4a5ce0148fd84b95369b3fbecd19a537ddfd2e2d20caa2eef0e8fd60
  volatile.eth0.host_name: veth75b6df07
  volatile.eth0.hwaddr: 00:16:3e:a1:e7:46
  volatile.idmap.base: "0"
  volatile.idmap.current: '[]'
  volatile.idmap.next: '[]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
devices: {}
ephemeral: false
profiles:
- default
stateful: false
description: ""

CPU-Ressourcenlimit ^

Es gibt mehrere Typen von Ressourcenbeschränkungen für CPU Beschränkungen:

  • limit.cpu — bindet den Container an einen oder mehrere CPU-Kerne
  • limits.cpu.allowance — steuert entweder die Quoten des CFS-Schedulers, wenn die Zeitbeschränkung erreicht ist, oder einen allgemeinen Mechanismus zur gemeinsamen Nutzung der CPU-Ressourcen, wenn ein Prozentsatz erreicht ist
  • limits.cpu.priority — Scheduler-Priorität, wenn mehreren Instanzen, die sich eine Prozessorgruppe teilen, der gleiche Prozentsatz der Prozessoren zugewiesen ist

lxc config set alp limits.cpu.allowance 40%

lxc config show alp

architecture: x86_64
config:
  image.architecture: amd64
  image.description: Alpine 3.11 amd64 (20200220_13:00)
  image.os: Alpine
  image.release: "3.11"
  image.serial: "20200220_13:00"
  image.type: squashfs
  limits.cpu.allowance: 40%
  limits.memory: 256MB
  volatile.base_image: 73a3093d4a5ce0148fd84b95369b3fbecd19a537ddfd2e2d20caa2eef0e8fd60
  volatile.eth0.host_name: veth75b6df07
  volatile.eth0.hwaddr: 00:16:3e:a1:e7:46
  volatile.idmap.base: "0"
  volatile.idmap.current: '[]'
  volatile.idmap.next: '[]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
devices: {}
ephemeral: false
profiles:
- default
stateful: false
description: ""

Festplattenspeicherlimit ^

Neben Beschränkungen wie limits.read, limits.write können wir auch den Speicherplatzverbrauch des Containers einschränken (funktioniert nur mit ZFS oder BTRFS):

lxc config device set alp root size=2GB

Nach der Festlegung können wir im Parameter devices.root.size die festgelegte Einschränkung überprüfen:

lxc config show alp
...
devices:
  root:
    path: \/
    pool: hddpool
    size: 2GB
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

Um die verwendeten Festplattensquoten anzuzeigen, können wir den Befehl lxc info:

lxc info alp
...
Ressourcen:
  Prozesse: 5
  Speicherverbrauch:
    root: 1.05GB
  CPU-Nutzung:
    CPU-Nutzung (in Sekunden): 1
  Speicherverbrauch:
    Speicher (aktuell): 5.46MB
  Netzwerk-Nutzung:
    eth0:
      empfangene Bytes: 802B
      gesendete Bytes: 1.59kB
      empfangene Pakete: 4
      gesendete Pakete: 14
    lo:
      empfangene Bytes: 0B
      gesendete Bytes: 0B
      empfangene Pakete: 0
      gesendete Pakete: 0

Trotz der Tatsache, dass wir eine Begrenzung für das Root-Gerät des Containers auf 2GB festgelegt haben, werden Systemtools wie df dieses Limit nicht erkennen. Zu diesem Zweck führen wir einen kleinen Test durch und schauen, wie das funktioniert.

Wir erstellen 2 neue identische Container im selben Storage Pool (hddpool):

lxc init alpine3 alp1 --storage=hddpool --profile=default --profile=hddroot
lxc init alpine3 alp2 --storage=hddpool --profile=default --profile=hddroot

lxc list
+------+---------+------------------+------+-----------+-----------+
| NAME |  STATE  |       IPV4       | IPV6 |   TYPE    | SNAPSHOTS |
+------+---------+------------------+------+-----------+-----------+
| alp1 | RUNNING | 10.0.5.46 (eth0) |      | CONTAINER | 0         |
+------+---------+------------------+------+-----------+-----------+
| alp2 | RUNNING | 10.0.5.30 (eth0) |      | CONTAINER | 0         |
+------+---------+------------------+------+-----------+-----------+

In einem der Container erstellen wir eine Datei mit der Größe von 1GB:

lxc exec alp1 -- dd if=\/dev\/urandom of=file.img bs=1M count=1000

Wir stellen sicher, dass die Datei erstellt wurde:

lxc exec alp1 -- ls -lh
total 1000M  
-rw-r--r--    1 root     root     1000.0M Mar 27 10:16 file.img

Wenn wir im zweiten Container nachsehen und die Existenz der Datei am selben Ort überprüfen, wird diese Datei nicht vorhanden sein, was zu erwarten ist, da Container in ihren eigenen Storage Volume in diesem Storage Pool:

lxc exec alp2 -- ls -lh
total 0

Aber lassen Sie uns die Werte vergleichen, die angezeigt werden df in den beiden Containern:

lxc exec alp1 -- df -hT
Filesystem           Type            Size      Used Available Use% Mounted on
\/dev\/loop1           btrfs           9.3G   1016.4M      7.8G  11% \/
...

lxc exec alp2 -- df -hT
Filesystem           Type            Size      Used Available Use% Mounted on
\/dev\/loop1           btrfs           9.3G   1016.4M      7.8G  11% \/
...

Gerät /dev/loop1 Das als Root-Partition gemountete ist Storage Pool das von diesen Containern verwendet wird, deshalb teilen sie sich dessen Volumen.

Ressourcennutzungsstatistik ^

Die Nutzung von Ressourcen für einen Container kann mit dem Befehl eingesehen werden:

lxc info alp

Name: alp
Location: none
Remote: unix:\/\/ 
Architecture: x86_64
Created: 2020\/04\/08 18:05 UTC
Status: Running
Type: container
Profiles: default, hddroot
Pid: 19219
Ips:
  eth0: inet    10.0.5.5        veth2a1dc59d
  eth0: inet6   fe80::216:3eff:fe0e:e271        veth2a1dc59d
  lo:   inet    127.0.0.1
  lo:   inet6   ::1
Resources:
  Processes: 5
  Disk usage:
    root: 495.62kB
  CPU usage:
    CPU usage (in seconds): 1
  Memory usage:
    Memory (current): 4.79MB
  Network usage:
    eth0:
      Bytes received: 730B
      Bytes sent: 1.59kB
      Packets received: 3
      Packets sent: 14
    lo:
      Bytes received: 0B
      Bytes sent: 0B
      Packets received: 0
      Packets sent: 0

Arbeiten mit Snapshots ^

In LXD besteht die Möglichkeit, Snapshots zu erstellen und aus ihnen den Zustand des Containers wiederherzustellen.

Um einen Snapshot zu erstellen, führen Sie folgenden Befehl aus:

lxc snapshot alp snapshot1

Der Befehl lxc snapshot hat keinen Schlüssel die Umwandlung von numerischen und textuellen Daten in die Formate, daher muss der Befehl zur Anzeige der Liste der Snapshots verwendet werden, um allgemeine Informationen über den Container zu erhalten:

lxc info alp
...
...
Snapshots:
  snapshot1 (erfasst am 2020/04/08 18:18 UTC) (stateless)

Container aus einem Snapshot kann mit dem Befehl lxc restore wiederhergestellt werden, indem der Container angegeben wird, für den die Wiederherstellung durchgeführt wird, sowie der Alias des Snapshots:

lxc restore alp snapshot1

Der folgende Befehl dient zum Löschen eines Snapshots. Bitte beachten Sie, dass die Syntax des Befehls nicht wie bei allen anderen ist; hier muss ein Schrägstrich nach dem Namen des Containers angegeben werden. Wenn der Schrägstrich weggelassen wird, wird der Befehl zur Löschung des Snapshots als Befehl zur Löschung des Containers interpretiert!

lxc delete alp/snapshot1

Im obigen Beispiel haben wir so genannte stateless Snapshots betrachtet. In LXD gibt es auch einen anderen Typ von Snapshots — stateful, bei denen der aktuelle Zustand aller Prozesse im Container gespeichert wird. Mit stateful Snapshots sind eine Reihe von interessanten und nützlichen Funktionen verbunden.

Was ist noch? ^

  • Für Python-Entwickler ist das Modul PyLXD verfügbar, das eine API zu LXD bereitstellt.

UPDATE 10.04.2020 15:00: Navigation hinzugefügt

Quelle: habr.com

60GB SSD 8Gb DDR4