Funzionalità di base di LXD — sistemi di contenitori in Linux.

Funzionalità di base di LXD — sistemi di contenitori in Linux.

LXD — è un gestore di container di nuova generazione, così si afferma fonte. Offre un'interfaccia utente simile a quella delle macchine virtuali, ma utilizza invece i container Linux.

Il kernel LXD — è un demone privilegiato (servizio eseguito con diritti di root), che fornisce un'API REST tramite un socket unix locale, così come attraverso la rete, se configurato di conseguenza. Clienti come l'utility da riga di comando fornita con LXD inviano richieste tramite questa API REST. Ciò significa che, indipendentemente dal fatto che tu stia accedendo all'host locale o a uno remoto, tutto funziona allo stesso modo.

In questo articolo non approfondiremo i concetti di LXD e non esamineremo tutte le funzionalità disponibili nella documentazione, inclusa la recente implementazione del supporto per macchine virtuali QEMU parallele ai contenitori nelle ultime versioni di LXD. Invece, ci concentreremo solo sulle funzionalità di base della gestione dei contenitori: configureremo i pool di archiviazione, la rete, avvieremo un contenitore, applicheremo limiti sulle risorse e vedremo come utilizzare gli snapshot, in modo da ottenere una comprensione di base di LXD e utilizzare i contenitori in Linux.

Per informazioni complete, consultare la fonte ufficiale:

Navigazione

Installazione di LXD ^

Installazione di LXD nelle distribuzioni Ubuntu ^

Nel pacchetto di Ubuntu 19.10, il pacchetto lxd ha una transizione verso pacchetto snap:

apt search lxd

lxd/eoan 1:0.7 all
  Pacchetto di transizione - lxd -> snap (lxd)

Ciò significa che saranno installati due pacchetti contemporaneamente, uno di sistema e l'altro come pacchetto snap. L'installazione di due pacchetti nel sistema può creare alcuni problemi, in cui il pacchetto di sistema potrebbe diventare orfano se il pacchetto snap viene rimosso dal gestore di pacchetti snap.

Trovare il pacchetto lxd nel repository snap è possibile con il seguente comando:

snap find lxd

Nome             Versione        Riepilogo
lxd              3.21           Gestore di contenitori di sistema e API
lxd-demo-server  0+git.6d54658  Sessioni di demo software online utilizzando LXD
nova             ocata          Servizio di calcolo OpenStack (nova)
nova-hypervisor  ocata          Servizio di calcolo OpenStack - Hypervisor KVM (nova)
distrobuilder    1.0            Costruttore di immagini per LXC e LXD
fabrica          0.1            Costruisci snap indicando semplicemente un modulo web a...
satellite        0.1.2          Piattaforma avanzata di intelligence open source scalabile

Esegui il comando list è possibile verificare che il pacchetto lxd non è ancora installato:

snap list

Nome  Versione    Rev   Tracking  Editore    Note
core  16-2.43.3  8689  stable    canonical✓  core

Nonostante LXD sia un pacchetto snap, deve essere installato tramite il pacchetto di sistema lxd, che creerà nel sistema il gruppo corrispondente, le utility necessarie in /usr/bin ecc.

sudo apt update
sudo apt install lxd

Assicuriamoci che il pacchetto sia installato come pacchetto snap:

snap list

Nome  Versione    Rev    Tracking  Editore    Note
core  16-2.43.3  8689   stable    canonical✓  core
lxd   3.21       13474  stable/…  canonical✓  -

Installazione di LXD nelle distribuzioni Arch Linux ^

Per installare il pacchetto LXD nel sistema, è necessario eseguire i seguenti comandi; il primo attualizza l'elenco dei pacchetti disponibili nel repository, il secondo installa direttamente il pacchetto:

sudo pacman -Syyu && sudo pacman -S lxd

Dopo l'installazione del pacchetto, per gestire LXD come utente normale, è necessario aggiungerlo nel gruppo di sistema lxd:

sudo usermod -a -G lxd user1

Assicuriamoci che l'utente user1 sia stato aggiunto al gruppo lxd:

id -Gn user1

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

Se il gruppo lxd non appare nell'elenco, allora è necessario riattivare la sessione dell'utente. Per fare ciò, esci e rientra nel sistema con lo stesso utente.

Attiviamo systemd il caricamento del servizio LXD all'avvio del sistema:

sudo systemctl enable lxd

Avviamo il servizio:

sudo systemctl start lxd

Controlliamo lo stato del servizio:

sudo systemctl status lxd

Archiviazione LXD (Storage) ^

Prima di iniziare l'inizializzazione, è necessario comprendere come è strutturato logicamente lo storage in LXD.

Lo storage (Storage) è composto da uno o più Storage Pool che utilizza uno dei file system supportati, come ZFS, BTRFS, LVM o directory normali. Ogni Storage Pool è suddiviso in volumi (Storage Volume) che contengono immagini, contenitori o dati per altri scopi.

  • Le immagini sono distribuzioni costruite appositamente senza il kernel Linux e disponibili da fonti esterne.
  • Container sono distribuzioni distribuite dalle immagini, pronte per l'uso.
  • Gli snapshot sono istantanee dello stato dei contenitori a cui è possibile tornare.

Funzionalità di base di LXD — sistemi di contenitori in Linux.

Per gestire lo storage in LXD, si utilizza il comando lxc storage di cui si può ottenere aiuto specificando il flag — lxc storage --help

Il comando seguente visualizza un elenco di tutti Storage Pool nei storage di LXD:

lxc storage list

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

Per visualizzare l'elenco di tutti Storage Volume nel selezionato Storage Pool la seguente comando è disponibile lxc storage volume list:

lxc storage volume list hddpool

+-------+----------------------------------+-------------+---------+
| TYPE  |          NAME                    | DESCRIPTION | USED BY |
+-------+----------------------------------+-------------+---------+
| image | ebd565585223487526ddb3607f515... |             | 1       |
+-------+----------------------------------+-------------+---------+

lxc storage volume list ssdpool

+-----------+----------------------------------+-------------+---------+
|   TYPE    |            NAME                  | DESCRIPTION | USED BY |
+-----------+----------------------------------+-------------+---------+
| container | alp3                             |             | 1       |
+-----------+----------------------------------+-------------+---------+
| container | jupyter                          |             | 1       |
+-----------+----------------------------------+-------------+---------+
| image     | ebd565585223487526ddb3607f515... |             | 1       |
+-----------+----------------------------------+-------------+---------+

Inoltre, se per Storage Pool se è stata scelta la filesystem BTRFS durante la creazione, puoi ottenere un elenco Storage Volume o subvolumi nell'interpretazione di BTRFS puoi utilizzare gli strumenti di questo filesystem:

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

Inizializzazione di LXD ^

Prima di creare e utilizzare i contenitori, è necessaria un'inizializzazione generale di LXD, che crea e configura la rete, così come lo storage. Questo può essere fatto manualmente con i comandi standard del client disponibili nell'elenco chiamando il comando lxc --help oppure tramite la procedura guidata di inizializzazione lxd init rispondendo a qualche domanda.

Scelta del filesystem per il Pool di Archiviazione ^

Durante l'inizializzazione, LXD pone alcune domande, tra cui la determinazione del tipo di filesystem per il predefinito Storage Pool. Per impostazione predefinita, viene selezionato il filesystem BTRFS. Cambiare in un altro FS dopo la creazione sarà impossibile. Per scegliere il FS viene proposta una tabella di confronto delle funzionalità:

Caratteristica
Directory
Btrfs
LVM
ZFS
CEPH

Storage delle immagini ottimizzato
no



Creazione dell'istanza ottimizzata
no



Creazione di snapshot ottimizzata
no



Trasferimento immagine ottimizzato
no

no

Trasferimento istanza ottimizzato
no

no

Copy on write
no



Basato su blocchi
no
no

no

Clonazione istantanea
no



Driver di archiviazione utilizzabile all'interno di un contenitore


no
no
no

Ripristina da snapshot precedenti (non l'ultimo)



no

Quote di archiviazione
sì(*)



no

Inizializzazione della rete e del Pool di Archiviazione tramite il wizard ^

Il prossimo comando che esamineremo consente di configurare i componenti principali di LXD rispondendo a semplici domande tramite il wizard di inizializzazione.

Esegui il comando lxc init e inserisci le risposte alle domande dopo i due punti come mostrato nell'esempio qui sotto o modificale secondo le tue esigenze:

lxd init

Vuoi utilizzare il clustering LXD? (sì/no) [predefinito=no]: 
Vuoi configurare un nuovo pool di archiviazione? (sì/no) [predefinito=sì]: 
Nome del nuovo pool di archiviazione [predefinito=default]: ssdpool
Nome del backend di archiviazione da utilizzare (lvm, btrfs, dir) [predefinito=btrfs]: 
Vuoi creare un nuovo pool BTRFS? (sì/no) [predefinito=sì]: 
Vuoi utilizzare un dispositivo a blocchi esistente? (sì/no) [predefinito=no]: 
Dimensione in GB del nuovo dispositivo a loop (minimo 1GB) [predefinito=15GB]: 10GB
Vuoi connetterti a un server MAAS? (sì/no) [predefinito=no]: 
Vuoi creare un nuovo ponte di rete locale? (sì/no) [predefinito=sì]: 
Come dovrebbe chiamarsi il nuovo ponte? [predefinito=lxdbr0]: 
Quale indirizzo IPv4 dovrebbe essere utilizzato? (notazione CIDR, “auto” o “nessuno”) [predefinito=auto]: 10.0.5.1/24
Vuoi che LXD NAT sia il traffico IPv4 sul tuo ponte? [predefinito=sì]: 
Quale indirizzo IPv6 dovrebbe essere utilizzato? (notazione CIDR, “auto” o “nessuno”) [predefinito=auto]: nessuno
Vuoi che LXD sia disponibile sulla rete? (sì/no) [predefinito=no]: 
Vuoi che le immagini memorizzate nella cache obsolete vengano aggiornate automaticamente? (sì/no) [predefinito=sì] no
Vuoi che venga stampato un preseed YAML "lxd init"? (sì/no) [predefinito=no]: 

Creazione di un ulteriore Pool di Archiviazione ^

Nel passaggio precedente abbiamo creato Storage Pool a cui abbiamo dato il nome ssdpool e il cui file si trova nel mio sistema all'indirizzo /var/lib/lxd/disks/ssdpool.img. Questo indirizzo del filesystem corrisponde al disco SSD fisico nel mio PC.

Per comprendere meglio il ruolo che gioca Storage Pool nello storage, creeremo un secondo Storage Pool che si troverà fisicamente su un altro tipo di disco, l'HDD. Il problema è che LXD non consente di creare Storage Pool fuori dall'indirizzo /var/lib/lxd/disks/ e nemmeno i link simbolici funzioneranno, vedi la risposta del developer. Possiamo aggirare questa limitazione durante l'inizializzazione/formatting Storage Pool specificando il valore come dispositivo a blocchi invece che come percorso a un file loopback specificandolo nella chiave source.

Quindi, prima di creare Storage Pool è necessario determinare il file loopback o una partizione esistente nel filesystem che utilizzerà. Per fare ciò, creeremo e useremo un file limitato a 10GB:

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

10000+0 records in
10000+0 records out
10000000000 bytes (10 GB, 9,3 GiB) copiati, 38,4414 s, 260 MB/s

Colleghiamo il file loopback a un dispositivo loopback libero:

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

/dev/loop1

Grazie alla chiave --show L'esecuzione del comando restituisce a schermo il nome del dispositivo a cui è collegato il nostro file loopback. Se necessario, possiamo visualizzare a schermo l'elenco di tutti i dispositivi di questo tipo per verificare la correttezza delle nostre azioni:

losetup -l

NOME       SIZELIMIT OFFSET AUTOCLEAR RO FILE-INDIRIZZO                      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

Dall'elenco si può notare che nel dispositivo /dev/loop1 è collegato un file loopback /mnt/work/lxd/hddpool.img, e nel dispositivo /dev/loop0 è collegato un file loopback /var/lib/lxd/disks/ssdpool.img che corrisponde al predefinito Storage Pool.

Il comando successivo crea un nuovo Storage Pool in LXD basato sul file loopback appena preparato. LXD formatterà il file loopback /mnt/work/lxd/hddpool.img nel dispositivo /dev/loop1 sotto il filesystem BTRFS:

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

Visualizziamo l'elenco di tutti Storage Pool a schermo:

lxc storage list

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

Aumento della dimensione del Pool di Archiviazione ^

Dopo aver creato Storage Pool, se necessario, può essere ampliato. Per Storage Pool basato su file system BTRFS, eseguire i seguenti comandi:

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

Auto-inserimento del file loopback nello slot del dispositivo loopback ^

Abbiamo un piccolo problema: al riavvio del sistema host, il file /mnt/work/lxd/hddpool.img "scomparirà" dal dispositivo /dev/loop1 e il servizio LXD non si avvierà al boot, poiché non lo troverà in questo dispositivo. Per risolvere questo problema, è necessario creare un servizio di sistema che monti questo file nel dispositivo /dev/loop1 al boot del sistema host.

Creiamo un'unità file di tipo service in /etc/systemd/system/ per il sistema di init SystemD:

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

Attiviamo il servizio:

sudo systemctl enable lxd-hddpool

Created symlink /etc/systemd/system/local-fs.target.wants/lxd-hddpool.service → /etc/systemd/system/lxd-hddpool.service.

Dopo il riavvio del sistema host, controlliamo lo stato del servizio:

systemctl status lxd-hddpool.service 

● lxd-hddpool.service - Losetup LXD Storage Pool (hddpool)
     Caricato: caricato (/etc/systemd/system/lxd-hddpool.service; abilitato; impostazione predefinita del fornitore: disabilitata)
     Attivo: attivo (uscito) dal Wed 2020-04-08 03:43:53 MSK; 1min 37s fa
    Processo: 711 ExecStart=/sbin/losetup /dev/loop1 /mnt/work/lxd/hddpool.img (codice=uscito, stato=0/SUCCESS)
   PID principale: 711 (codice=uscito, stato=0/SUCCESS)

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

Dall'output possiamo assicurarci che lo stato del servizio è active, nonostante l'esecuzione del nostro script da un comando singolo sia terminata, ci ha permesso di effettuare l'opzione RemainAfterExit=true.

Sicurezza. Privilegi dei contenitori ^

Poiché tutti i processi del container vengono effettivamente eseguiti in isolamento sul sistema host utilizzando il suo kernel, per una protezione aggiuntiva dell'accesso dei processi del container al sistema host, LXD offre privilegi per i processi, dove:

  • Container privilegiati — sono contenitori in cui i processi con UID e GID corrispondono allo stesso proprietario del sistema host. Ad esempio, un processo avviato in un contenitore con UID pari a 0 ha gli stessi diritti di accesso di un processo del sistema host con UID pari a 0. In altre parole, l'utente root nel contenitore ha pieni diritti non solo all'interno del contenitore, ma anche nel sistema host, se riesce a uscire dallo spazio dei nomi isolato del contenitore.

  • Contenitori non privilegiati — sono contenitori in cui i processi appartengono a un proprietario con UID e GID numerati da 0 a 65535, ma per il sistema host il proprietario è nascosto tramite il bit SubUID e SubGID aggiunto. Ad esempio, un utente con UID=0 nel contenitore sarà riconosciuto nel sistema host come SubUID + UID. Questo protegge il sistema host, poiché, se un processo all'interno del contenitore riesce a uscire dal suo spazio dei nomi isolato, può interagire con il sistema host solo come un processo con un UID/GID sconosciuto e molto elevato.

Per impostazione predefinita, i contenitori appena creati hanno lo stato di non privilegiati e quindi dobbiamo definire SubUID e SubGID.

Creeremo due file di configurazione in cui imposteremo la maschera per SubUID e SubGID rispettivamente:

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

Per applicare le modifiche, il servizio LXD deve essere riavviato:

sudo systemctl restart lxd

Creazione di un virtual switch di rete ^

Poiché abbiamo precedentemente inizializzato la rete utilizzando il master di inizializzazione lxd init e creato un dispositivo di rete lxdbr0, in questa sezione ci limiteremo a esplorare la rete in LXD e a come creare uno switch virtuale (bridge) utilizzando il comando del client.

Il seguente schema dimostra come uno switch (bridge) collega l'host e i contenitori nella rete:

Funzionalità di base di LXD — sistemi di contenitori in Linux.

I contenitori possono interagire tramite la rete con altri contenitori o con l'host su cui questi contenitori sono ospitati. A tal fine, è necessario collegare le schede di rete virtuali dei contenitori allo switch virtuale. Inizialmente creeremo lo switch, e le interfacce di rete del contenitore saranno collegate nei capitoli successivi, dopo che il contenitore stesso sarà stato creato.

Il comando seguente crea uno switch con una subnet 10.0.5.0/24 e un indirizzo IPv4 10.0.5.1/24, e attiva ipv4.nat affinché i contenitori possano accedere a Internet tramite l'host utilizzando il servizio NAT:

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

Controlliamo l'elenco delle interfacce di rete disponibili in LXD:

lxc network list

+--------+----------+---------+-------------+---------+
|  NOME  |   TIPO   | GESTITO | DESCRIZIONE | UTILIZZATO |
+--------+----------+---------+-------------+---------+
| eno1   | fisico   | NO      |             | 0       |
+--------+----------+---------+-------------+---------+
| lxdbr0 | bridge   | SÌ      |             | 0       |
+--------+----------+---------+-------------+---------+

Inoltre, è possibile verificare la creazione del dispositivo di rete usando lo strumento standard del sistema operativo Linux — ip link o ip addr:

ip addr

1: lo:  mtu 65536 qdisc noqueue stato UNKNOWN gruppo 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 stato UP gruppo 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 stato UP gruppo 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 stato UP gruppo default qlen 1000
    link/ether ca:c3:5c:1d:22:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0

Profilo di configurazione ^

Ogni contenitore in LXD ha la propria configurazione e può ampliarla tramite configurazioni dichiarate globalmente che vengono chiamate profili di configurazione. L'applicazione dei profili di configurazione a un contenitore segue un modello a cascata, il seguente esempio lo dimostra:

Funzionalità di base di LXD — sistemi di contenitori in Linux.

In questo esempio, nel sistema LXD sono stati creati tre profili: default, hddpool e hostfs. Tutti e tre i profili sono applicati a un contenitore che ha una configurazione locale (zona grigia). Profilo default ha un dispositivo root che ha il parametro pool è uguale a ssdpool, ma grazie al modello a cascata di applicazione della configurazione possiamo applicare un profilo al contenitore hddpool che ha il parametro pool sovrascriverà lo stesso parametro dal profilo default e il contenitore riceverà la configurazione del dispositivo root con il parametro pool uguale a hddpool, mentre il profilo hostfs aggiunge semplicemente un nuovo dispositivo al contenitore.

Per vedere l'elenco dei profili di configurazione disponibili, si utilizza il seguente comando:

lxc profile list

+---------+---------+
|  NOME   | USATO DA |
+---------+---------+
| default | 1       |
+---------+---------+
| hddroot | 0       |
+---------+---------+
| ssdroot | 1       |
+---------+---------+

L'elenco completo dei comandi disponibili per gestire il profilo può essere ottenuto aggiungendo il flag --help:

lxc profile --help

Descrizione:
  Gestire i profili

Uso:
  lxc profile [comando]

Comandi disponibili:
  add         Aggiungi profili a istanze
  assign      Assegna set di profili a istanze
  copy        Copia profili
  create      Crea profili
  delete      Elimina profili
  device      Gestisci dispositivi delle istanze
  edit        Modifica configurazioni del profilo come YAML
  get         Ottieni valori per le chiavi di configurazione del profilo
  list        Elenca profili
  remove      Rimuovi profili dalle istanze
  rename      Rinomina profili
  set         Imposta chiavi di configurazione del profilo
  show        Mostra configurazioni del profilo
  unset       Disattiva chiavi di configurazione del profilo

Modifica del profilo ^

Profilo di configurazione predefinito default non è configurata alcuna scheda di rete per il contenitore e tutti i nuovi contenitori non hanno accesso alla rete. Per questi è necessario creare dispositivi di rete locali (dedicati) tramite un comando separato, ma possiamo creare un dispositivo di rete globale nel profilo di configurazione che sarà condiviso da tutti i contenitori che utilizzano questo profilo. In questo modo, subito dopo il comando di creazione di un nuovo contenitore, avranno accesso alla rete. Non ci sono limitazioni, possiamo sempre creare in seguito un dispositivo di rete locale se necessario.

Il comando successivo aggiungerà al profilo di configurazione un dispositivo eth0 di tipo nic collegato alla rete lxdbr0:

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

È importante notare che, dato che abbiamo effettivamente aggiunto un dispositivo al profilo di configurazione, se avessimo specificato un indirizzo IP statico per il dispositivo, tutti i container che utilizzeranno questo profilo condivideranno lo stesso indirizzo IP. Se è necessario creare un container con un indirizzo IP statico dedicato, è necessario creare una configurazione di dispositivo di rete a livello di container (configurazione locale) con il parametro dell'indirizzo IP, piuttosto che a livello di profilo.

Controlliamo il profilo:

lxc profile show default

config: {}
description: Profilo LXD predefinito
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: ssdpool
    type: disk
name: default
used_by: []

In questo profilo possiamo vedere che per tutti i nuovi container creati verranno creati due dispositivi (devices):

  • eth0 — Dispositivo di tipo nic collegato a uno switch (bridge di rete) lxdbr0
  • root — Dispositivo di tipo disk che utilizza il pool di archiviazione ssdpool

Creazione di nuovi profili ^

Per utilizzare i precedentemente creati Storage Pool container, creiamo un profilo di configurazione ssdroot in cui aggiungeremo un dispositivo di tipo disk con punto di montaggio / (root) che utilizza il già creato Storage Poolssdpool:

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

Allo stesso modo, creiamo un dispositivo di tipo disk, ma in questo caso utilizzare Storage Poolhddpool:

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

Controlliamo i profili di configurazione:

lxc profile show ssdroot

config: {}
description: ""
devices:
  root:
    path: /
    pool: ssdpool
    type: disk
name: ssdroot
used_by: []

lxc profile show hddroot

config: {}
description: ""
devices:
  root:
    path: /
    pool: hddpool
    type: disk
name: hddroot
used_by: []

Repository delle immagini ^

I contenitori vengono creati da immagini che sono distribuzioni specialmente realizzate senza un kernel Linux. Pertanto, prima di avviare un contenitore, deve essere estratto da questa immagine. Le immagini provengono da un repository locale in cui vengono caricate da repository esterni.

Repository delle immagini remote ^

Per impostazione predefinita, LXD è configurato per ricevere immagini da tre fonti remote:

  • ubuntu: (per immagini Ubuntu stabili)
  • ubuntu-daily: (per immagini quotidiane di Ubuntu)
  • images: (per molte altre distribuzioni)

lxc remote list

+-----------------+------------------------------------------+--------+--------+
|      NOME      |                   URL                    | PUBBLICO | STATICO |
+-----------------+------------------------------------------+--------+--------+
| immagini       | https://images.linuxcontainers.org       | SÌ     | NO     |
+-----------------+------------------------------------------+--------+--------+
| locale (predefinito) | unix://                                  | NO     | SÌ     |
+-----------------+------------------------------------------+--------+--------+
| ubuntu         | https://cloud-images.ubuntu.com/releases | SÌ     | SÌ     |
+-----------------+------------------------------------------+--------+--------+
| ubuntu-daily   | https://cloud-images.ubuntu.com/daily    | SÌ     | SÌ     |
+-----------------+------------------------------------------+--------+--------+

Ad esempio, il repository ubuntu: ha le seguenti immagini:

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

+----------------------------------------------+--------------+----------+------------+
|                   DESCRIZIONE                | ARCHITETTURA |   DIMENSIONE   |   TIPO     |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150728)  | x86_64       | 153.72MB | CONTENITORE  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150819)  | x86_64       | 152.91MB | CONTENITORE  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150906)  | x86_64       | 154.69MB | CONTENITORE  |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150930)  | x86_64       | 153.86MB | CONTENITORE  |
+----------------------------------------------+--------------+----------+------------+

Per visualizzare un numero limitato di colonne abbiamo utilizzato l'opzione -c con i parametri dasut, e abbiamo anche limitato la lunghezza dell'elenco con il comando head.

Per l'output dell'elenco delle immagini è disponibile un filtro. Il seguente comando visualizzerà l'elenco di tutte le architetture disponibili per la distribuzione AlpineLinux:

lxc image -c ldast list images:alpine/3.11

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

Repository locale delle immagini ^

Per iniziare a utilizzare il contenitore, è necessario aggiungere un'immagine dal repository globale a quello locale locale:. Al momento, il repository locale è vuoto, e lo verifichiamo con il comando lxc image list. Se non viene specificato alcun repository per il metodo list , per impostazione predefinita verrà utilizzato il repository locale — locale:

lxc image list local:

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

La gestione delle immagini nel repository avviene tramite i seguenti metodi:

Team
Descrizione

lxc image alias
Gestisci alias delle immagini

lxc image copy
Copia immagini tra server

lxc image elimina
Elimina immagini

lxc image modifica
Modifica proprietà dell'immagine

lxc image esporta
Esporta e scarica immagini

lxc image importa
Importa immagini nel deposito delle immagini

lxc image info
Mostra informazioni utili sulle immagini

lxc image list
Elenca immagini

lxc image aggiorna
Aggiorna immagini

lxc image mostra
Mostra proprietà dell'immagine

Copiaamo l'immagine nel repository locale da globale images::

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

Immagine copiata con successo!

Elenco di tutte le immagini attualmente disponibili nel repository locale locale::

lxc image -c lfdatsu list local:

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

Configurazione LXD ^

Oltre alla modalità interattiva, LXD supporta anche la modalità non interattiva per la configurazione, in cui la configurazione viene fornita in un file YAML, un formato speciale che consente di impostare tutta la configurazione in un colpo solo, evitando di eseguire numerosi comandi interattivi esaminati in precedenza in questo articolo, inclusa la configurazione della rete, la creazione di profili di configurazione, ecc. In quest'area non ci soffermeremo, potete esplorare autonomamente. nella documentazione.

Il prossimo comando interattivo lxc config che esamineremo, consente di impostare la configurazione. Ad esempio, per evitare che le immagini scaricate nel repository locale vengano aggiornate automaticamente dai repository globali, possiamo attivare questo comportamento con il seguente comando:

lxc config set images.auto_update_cached=false

Creazione e gestione del contenitore ^

Per creare un contenitore, utilizziamo il comando lxc init a cui vengono passati i valori repository:image e quindi l'identificatore desiderato per il contenitore. Il repository può essere specificato come locale. locale: così come qualsiasi repository globale. Se non viene specificato un repository, per impostazione predefinita verrà utilizzato il repository locale per cercare l'immagine. Se l'immagine è specificata da un repository globale, verrà prima scaricata nel repository locale e poi utilizzata per creare il contenitore.

Eseguiamo il seguente comando per creare il nostro primo contenitore:

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

Analizziamo i parametri del comando che stiamo utilizzando qui:

  • alpine3 — Viene specificato un alias (pseudonimo) per l'immagine precedentemente scaricata nel repository locale. Se non fosse stato creato un alias per quest'immagine, è possibile sempre fare riferimento all'immagine tramite il suo Fingerprint che viene visualizzato nella tabella.
  • alp — Viene assegnato un identificatore per il contenitore
  • --storage — Questo parametro indica in quale Storage Pool verrà creato il contenitore
  • --profile — Questi parametri applicano a cascata al contenitore la configurazione dai profili di configurazione precedentemente creati.

Avviamo il contenitore, che inizia a lanciare il sistema init della distribuzione:

lxc start alp

In alternativa, è possibile utilizzare il comando lxc launch che consente di combinare i comandi lxc init e lxc start in un'unica operazione.

Controlliamo lo stato del contenitore:

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

Controlliamo la configurazione del contenitore:

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: ""

Nella sezione profiles possiamo assicurarci che questo contenitore utilizzi due profili di configurazione — default e hddroot. Nella sezione devices possiamo rilevare solo un dispositivo, poiché il dispositivo di rete è stato creato a livello di profilo default. Per visualizzare tutti i dispositivi utilizzati dal contenitore è necessario aggiungere la chiave --expanded:

lxc config show alp --expanded

architettura: x86_64
configurazione:
  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:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: hddpool
    type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""

Assegnazione di un indirizzo IP statico ^

Se proviamo a impostare un indirizzo IP per il dispositivo di rete eth0 comando lxc config device set alp destinato alla configurazione del contenitore, riceveremo un errore che indica che il dispositivo non esiste perché il dispositivo eth0 che è utilizzato dal contenitore appartiene al profilo default:

lxc config device set alp eth0 ipv4.address 10.0.5.5

Errore: il dispositivo non esiste

Possiamo certamente impostare un indirizzo IP statico per eth0 il dispositivo nel profilo, ma sarà unico per tutti i contenitori che utilizzeranno questo profilo. Pertanto, aggiungiamo un dispositivo dedicato per il contenitore:

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

Poi bisogna riavviare il contenitore:

lxc restart alp

Se ora guardiamo la configurazione del contenitore, non è necessario applicare l'opzione --expanded per vedere il dispositivo di rete eth0, poiché lo abbiamo creato a livello di contenitore e ha sovrascritto a cascata lo stesso dispositivo dal profilo default:

lxc config show alp

architettura: x86_64
configurazione:
  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: IN CORSO
devices:
  eth0:
    ipv4.address: 10.0.5.5
    nome: eth0
    nictype: bridged
    parent: lxdbr0
    type: nic
  root:
    path: /
    pool: hddpool
    type: disk
ephemeral: false
profili:
- predefinito
- hddroot
stateful: false
descrizione: ""

Rimozione del contenitore ^

Per rimuovere il contenitore si utilizza il comando lxc delete, ma prima di rimuovere il contenitore, deve essere fermato utilizzando il comando lxc stop:

lxc stop alp

lxc list

+------+---------+-------------------+------+-----------+-----------+
| NOME |  STATO  |       IPV4        | IPV6 |   TIPO    | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| alp  | FERMATO | 10.0.5.10 (eth0)  |      | CONTENITORE | 0         |
+------+---------+-------------------+------+-----------+-----------+

Dopo aver verificato che lo stato del contenitore sia FERMATO, può essere rimosso da Storage Pool:

lxc delete alp

Accesso al contenitore ^

Per eseguire comandi nel contenitore, direttamente, bypassando le connessioni di rete, si usa il comando lxc exec , che esegue comandi nel contenitore senza avviare la shell di sistema. Se hai bisogno di eseguire un comando nella shell, usando modelli di shell, come variabili, redirect di file (pipe), ecc., è necessario avviare esplicitamente la shell e passare il comando come chiave, ad esempio:

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

Nel comando è stato utilizzato un carattere speciale di escape per il carattere speciale $ , affinché la variabile $HOME non venga interpretata sulla macchina host, ma sia interpretata solo all'interno del contenitore.

È anche possibile avviare la modalità interattiva della shell e, dopo aver terminato la sessione, eseguire il hotkey CTRL+D:

lxc exec alp -- /bin/sh

Gestione delle risorse del contenitore ^

In LXD puoi gestire le risorse del contenitore tramite un insieme speciale di configurazioni. L'elenco completo dei parametri di configurazione del contenitore può essere trovato nella documentazione.

Limitazione delle risorse RAM ^

Caratteristica limits.memory limita la quantità di RAM disponibile per il contenitore. Come valore, si indica un numero e uno dei suffissi disponibili.

Impostiamo un limite alla quantità di RAM per il contenitore pari a 256 MB:

lxc config set alp limits.memory 256MB

Esistono anche altri parametri per limitare la memoria:

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

Team lxc config show permette di visualizzare l'intera configurazione del contenitore, inclusa la limitazione delle risorse applicata:

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: ""

Limitazione delle risorse CPU ^

Per limitare le risorse della CPU esistono diversi tipi di limitazioni:

  • limit.cpu — associa il contenitore a uno o più core della CPU
  • limits.cpu.allowance — gestisce sia i limiti dei scheduler CFS, quando si è raggiunto il limite di tempo, sia un meccanismo universale di condivisione delle risorse CPU, quando viene superata una percentuale
  • limits.cpu.priority — priorità del pianificatore, quando più istanze condividono un insieme di processori con la stessa percentuale di CPU assegnata

lxc config set alp limits.cpu.allowance 40%

lxc config show alp

architettura: x86_64
configurazione:
  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: ""

Limitazione dello spazio su disco ^

Oltre a restrizioni come limits.read, limits.write possiamo anche limitare la quantità di spazio su disco utilizzata dal contenitore (funziona solo con ZFS o BTRFS):

lxc config device set alp root size=2GB

Dopo la configurazione, nel parametro devices.root.size possiamo verificare il limite impostato:

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

Per visualizzare le quote di spazio su disco utilizzate, possiamo ottenere le informazioni con il comando lxc info:

lxc info alp
...
Risorse:
  Processi: 5
  Utilizzo disco:
    root: 1.05GB
  Utilizzo CPU:
    Utilizzo CPU (in secondi): 1
  Utilizzo memoria:
    Memoria (attuale): 5.46MB
  Utilizzo rete:
    eth0:
      Byte ricevuti: 802B
      Byte inviati: 1.59kB
      Pacchetti ricevuti: 4
      Pacchetti inviati: 14
    lo:
      Byte ricevuti: 0B
      Byte inviati: 0B
      Pacchetti ricevuti: 0
      Pacchetti inviati: 0

Nonostante abbiamo impostato un limite per il dispositivo radice del container a 2GB, utilità di sistema come df non vedranno questo limite. Per questo faremo un piccolo test per capire come funziona.

Creiamo 2 nuovi container identici nella stessa 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
+------+---------+------------------+------+-----------+-----------+
| NOME |  STATO  |       IPV4       | IPV6 |   TIPO    | SNAPSHOT |
+------+---------+------------------+------+-----------+-----------+
| alp1 | IN FUNZIONE | 10.0.5.46 (eth0) |      | CONTENITORE | 0         |
+------+---------+------------------+------+-----------+-----------+
| alp2 | IN FUNZIONE | 10.0.5.30 (eth0) |      | CONTENITORE | 0         |
+------+---------+------------------+------+-----------+-----------+

In uno dei container creiamo un file di dimensioni 1GB:

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

Assicuriamoci che il file sia stato creato:

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

Se guardiamo nel secondo contenitore, controllando l'esistenza del file nello stesso posto, questo file non sarà presente, come ci si aspetta, poiché i contenitori vengono creati nei loro ambienti separati. Storage Volume in questo stesso Storage Pool:

lxc exec alp2 -- ls -lh
total 0

Ma confrontiamo i valori che restituisce df in entrambi i contenitori:

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% /
...

Dispositivo /dev/loop1 montato come partizione radice è Storage Pool quella che questi contenitori utilizzano, quindi suddividono il suo spazio in due.

Statistiche di utilizzo delle risorse ^

Puoi visualizzare le statistiche sulle risorse consumate dal contenitore con il comando:

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

Lavorare con gli snapshot ^

Con LXD è possibile creare snapshot e ripristinare lo stato di un contenitore da essi.

Per creare uno snapshot, eseguire il seguente comando:

lxc snapshot alp snapshot1

Il comando lxc snapshot non ha una chiave list, quindi, per visualizzare l'elenco degli snapshot, è necessario utilizzare un comando che fornisca informazioni generali sul contenitore:

lxc info alp
...
...
Snapshots:
  snapshot1 (preso il 2020/04/08 18:18 UTC) (senza stato)

È possibile ripristinare il contenitore da uno snapshot con il comando lxc restore specificando il contenitore per il quale si desidera effettuare il ripristino e il nome dello snapshot:

lxc restore alp snapshot1

Il seguente comando serve ad eliminare uno snapshot. Si noti che la sintassi del comando è diversa da tutti gli altri; qui è necessario specificare una barra inclinata dopo il nome del contenitore. Se si omette la barra, il comando di eliminazione dello snapshot viene interpretato come un comando di eliminazione del contenitore!

lxc delete alp/snapshot1

Nell'esempio sopra abbiamo considerato i cosiddetti snapshot senza stato. In LXD esiste anche un altro tipo di snapshot — stateful, in cui viene salvato lo stato attuale di tutti i processi nel contenitore. Gli snapshot stateful presentano una serie di funzionalità interessanti e utili.

Cosa altro? ^

  • Per gli sviluppatori Python è disponibile un modulo PyLXD che fornisce un'API per LXD

AGGIORNAMENTO 10.04.2020 15:00: Aggiunta navigazione

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster