
LXD — es un gestor de contenedores de nueva generación, así está declarado . Ofrece una interfaz de usuario similar a las máquinas virtuales, pero utiliza contenedores de Linux en su lugar.
El núcleo de LXD — es un demonio privilegiado (servicio ejecutado con derechos de root) que proporciona una API REST a través de un socket unix local, así como a través de la red, si se establece la configuración adecuada. Los clientes, como la herramienta de línea de comandos proporcionada con LXD, envían solicitudes a través de esta API REST. Esto significa que, independientemente de si estás accediendo al host local o a uno remoto, todo funciona de la misma manera.
En este artículo no profundizaremos en los conceptos de LXD, ni examinaremos todas las capacidades disponibles descritas en la documentación, incluyendo la reciente implementación en las últimas versiones de LXD que soporta máquinas virtuales QEMU junto con contenedores. En su lugar, solo conoceremos las funciones básicas de gestión de contenedores: configuraremos grupos de almacenamiento, red, iniciaremos un contenedor, aplicaremos límites de recursos y también veremos cómo usar instantáneas, para que puedas obtener una visión básica de LXD y utilizar contenedores en Linux.
Para obtener información completa, se debe consultar la fuente oficial:
Navegación
Instalación de LXD
Instalación de LXD en distribuciones de Ubuntu
En la distribución Ubuntu 19.10, el paquete lxd tiene traducción a :
apt search lxd
lxd/eoan 1:0.7 all
Paquete de transición - lxd -> snap (lxd)Esto significa que se instalarán dos paquetes de inmediato, uno del sistema y otro como paquete snap. La instalación de dos paquetes en el sistema puede causar un problema en el que el paquete del sistema puede quedar huérfano si se elimina el paquete snap mediante el gestor de paquetes snap.
Buscar paquete lxd en el repositorio snap se puede hacer con el siguiente comando:
snap find lxd
Nombre Versión Resumen
lxd 3.21 Gestor de contenedores del sistema y API
lxd-demo-server 0+git.6d54658 Sesiones de demostración de software en línea usando LXD
nova ocata Servicio de computación OpenStack (nova)
nova-hypervisor ocata Servicio de computación OpenStack - Hypervisor KVM (nova)
distrobuilder 1.0 Constructor de imágenes para LXC y LXD
fabrica 0.1 Crea snaps simplemente apuntando un formulario web a...
satellite 0.1.2 Plataforma avanzada escalable de inteligencia de código abiertoAl ejecutar el comando list se puede confirmar que el paquete lxd todavía no está instalado:
snap list
Nombre Versión Rev Seguimiento Publicador Notas
core 16-2.43.3 8689 estable canonical✓ coreA pesar de que LXD es un paquete snap, se debe instalar a través del paquete del sistema lxd, el cual creará en el sistema el grupo correspondiente y las utilidades necesarias en /usr/bin etc.
sudo apt update
sudo apt install lxdVerifiquemos que el paquete esté instalado como paquete snap:
snap list
Nombre Versión Rev Seguimiento Publicador Notas
core 16-2.43.3 8689 estable canonical✓ core
lxd 3.21 13474 estable/... canonical✓ -Instalación de LXD en distribuciones de Arch Linux
Para instalar el paquete LXD en el sistema, es necesario ejecutar los siguientes comandos; el primero actualizará la lista de paquetes disponibles en el repositorio y el segundo instalará directamente el paquete:
sudo pacman -Syyu && sudo pacman -S lxdDespués de instalar el paquete, para gestionar LXD como usuario normal, debe ser agregado al grupo del sistema lxd:
sudo usermod -a -G lxd user1Verifiquemos que el usuario user1 haya sido agregado al grupo lxd:
id -Gn user1
user1 adm dialout cdrom floppy sudo audio dip video plugdev netdev lxdSi el grupo lxd no aparece en la lista, entonces es necesario reiniciar la sesión del usuario. Para hacer esto, debe cerrar sesión y volver a ingresar al sistema con el mismo usuario.
Activaremos en systemd la carga del servicio LXD al inicio del sistema:
sudo systemctl enable lxdIniciamos el servicio:
sudo systemctl start lxdVerificamos el estado del servicio:
sudo systemctl status lxdAlmacenamiento LXD (Storage)
Antes de comenzar la inicialización, necesitamos entender cómo está estructurado lógicamente el almacenamiento en LXD.
El almacenamiento (Almacenamiento) de uno o más Grupo de Almacenamiento que utiliza uno de los sistemas de archivos compatibles como ZFS, BTRFS, LVM o directorios normales. Cada Grupo de Almacenamiento se divide en volúmenes (Storage Volume) que contienen imágenes, contenedores o datos para otros fines.
- Imágenes son distribuciones especialmente construidas sin núcleo de Linux y disponibles desde fuentes externas
- Contenedores son distribuciones desplegadas desde imágenes, listas para su uso
- Instantáneas son capturas del estado de los contenedores a las que se puede regresar

Para gestionar el almacenamiento en LXD, se utiliza el comando lxc storage cuya ayuda se puede obtener indicando la clave — lxc storage --help
El siguiente comando muestra en pantalla la lista de todos Grupo de Almacenamiento en el almacenamiento de LXD:
lxc storage list
+---------+-------------+--------+--------------------------------+---------+
| NAME | DESCRIPTION | DRIVER | SOURCE | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| hddpool | | btrfs | /dev/loop1 | 2 |
+---------+-------------+--------+--------------------------------+---------+
| ssdpool | | btrfs | /var/lib/lxd/disks/ssdpool.img | 4 |
+---------+-------------+--------+--------------------------------+---------+Para ver la lista de todos Storage Volume en el elegido Grupo de Almacenamiento se utiliza el comando 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 |
+-----------+----------------------------------+-------------+---------+Además, si al crear se eligió el sistema de archivos BTRFS, se puede obtener la lista de Grupo de Almacenamiento subvolúmenes Storage Volume o en la interpretación de BTRFS mediante las herramientas de este sistema de archivos: sudo btrfs subvolume list -p /var/lib/lxd/storage-pools/hddpoolID 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/alp3Antes de crear y usar contenedores, es necesario realizar la inicialización general de LXD que crea y configura la red, así como el almacenamiento. Esto se puede llevar a cabo manualmente mediante los comandos estándar del cliente que están disponibles en la lista llamando al comandoInicialización de LXD
lxc --help o mediante el asistente de inicialización lxd init respondiendo a algunas preguntas. respondí a varias preguntas.
Selección del sistema de archivos para el grupo de almacenamiento
Durante la inicialización, LXD hace varias preguntas, entre las cuales se definirá el tipo de sistema de archivos para el predeterminado Grupo de Almacenamiento. Por defecto, se selecciona el sistema de archivos BTRFS. No será posible cambiar a otro sistema de archivos después de la creación. Para seleccionar un sistema de archivos, se ofrece :
Características
Directorio
Btrfs
LVM
ZFS
CEPH
Almacenamiento de imágenes optimizado
no
yes
yes
yes
yes
Creación de instancias optimizada
no
yes
yes
yes
yes
Creación de instantáneas optimizada
no
yes
yes
yes
yes
Transferencia de imágenes optimizada
no
yes
no
yes
yes
Transferencia de instancias optimizada
no
yes
no
yes
yes
Copia al escribir
no
yes
yes
yes
yes
Basado en bloques
no
no
yes
no
yes
Clonado instantáneo
no
yes
yes
yes
yes
Controlador de almacenamiento utilizable dentro de un contenedor
yes
yes
no
no
no
Restaurar desde instantáneas anteriores (no la más reciente)
yes
yes
yes
no
yes
Cuotas de almacenamiento
sí(*)
yes
yes
yes
no
Inicialización de la red y del grupo de almacenamiento mediante el asistente
El siguiente comando que revisaremos permite configurar los componentes básicos de LXD respondiendo a preguntas sencillas mediante un asistente de inicialización.
Ejecute el comando lxc init y dé respuestas a las preguntas después de los dos puntos como se muestra en el ejemplo a continuación o modifíquelas según sus condiciones:
lxd init
¿Te gustaría utilizar la agrupación LXD? (sí/no) [predeterminado=no]:
¿Quieres configurar un nuevo grupo de almacenamiento? (sí/no) [predeterminado=sí]:
Nombre del nuevo grupo de almacenamiento [predeterminado=default]: ssdpool
Nombre del backend de almacenamiento a utilizar (lvm, btrfs, dir) [predeterminado=btrfs]:
¿Crear un nuevo grupo BTRFS? (sí/no) [predeterminado=sí]:
¿Te gustaría usar un dispositivo de bloque existente? (sí/no) [predeterminado=no]:
Tamaño en GB del nuevo dispositivo de bucle (mínimo 1GB) [predeterminado=15GB]: 10GB
¿Te gustaría conectarte a un servidor MAAS? (sí/no) [predeterminado=no]:
¿Te gustaría crear un nuevo puente de red local? (sí/no) [predeterminado=sí]:
¿Cómo debería llamarse el nuevo puente? [predeterminado=lxdbr0]:
¿Qué dirección IPv4 debería utilizarse? (notación de subred CIDR, "auto" o "none") [predeterminado=auto]: 10.0.5.1/24
¿Te gustaría que LXD NATeara el tráfico IPv4 en tu puente? [predeterminado=sí]:
¿Qué dirección IPv6 debería utilizarse? (notación de subred CIDR, "auto" o "none") [predeterminado=auto]: none
¿Te gustaría que LXD estuviese disponible a través de la red? (sí/no) [predeterminado=no]:
¿Te gustaría que las imágenes almacenadas en caché caducadas se actualizaran automáticamente? (sí/no) [predeterminado=sí]: no
¿Te gustaría que se imprimiera una preconfiguración YAML para "lxd init"? (sí/no) [predeterminado=no]: Creación de un grupo de almacenamiento adicional
En el paso anterior, hemos creado Grupo de Almacenamiento al que le dimos el nombre ssdpool y cuyo archivo se encuentra en mi sistema en la dirección /var/lib/lxd/disks/ssdpool.img. Esta dirección del sistema de archivos corresponde al disco SSD físico en mi PC.
Las siguientes acciones, para ampliar la comprensión del papel que juega Grupo de Almacenamiento en el almacenamiento, crearemos un segundo Grupo de Almacenamiento que físicamente estará en otro tipo de disco, en un HDD. El problema es que LXD no permite crear Grupo de Almacenamiento fuera de la dirección /var/lib/lxd/disks/ y ni siquiera los enlaces simbólicos funcionarán, . Podemos sortear esta limitación al inicializar/formatear Grupo de Almacenamiento especificando el valor como un dispositivo de bloque en lugar de la ruta a un archivo de bucle, indicándolo en la clave source.
Por lo tanto, antes de crear Grupo de Almacenamiento es necesario definir un archivo de loopback o una partición existente en su sistema de archivos que utilizará. Para ello, crearemos y utilizaremos un archivo que limitaremos a 10 GB:
dd if=/dev/zero of=/mnt/work/lxd/hddpool.img bs=1MB count=10000
10000+0 registros entrantes
10000+0 registros salientes
10000000000 bytes (10 GB, 9,3 GiB) copiados, 38,4414 s, 260 MB/sConectaremos el archivo de loopback a un dispositivo de loopback libre:
sudo losetup --find --show /mnt/work/lxd/hddpool.img
/dev/loop1Gracias a la clave --show la ejecución del comando devuelve en pantalla el nombre del dispositivo al que se ha conectado nuestro archivo de loopback. Si es necesario, podemos mostrar en pantalla la lista de todos los dispositivos ocupados de este tipo, para asegurarnos de que nuestras acciones son correctas:
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 512De la lista se puede observar que en el dispositivo /dev/loop1 se ha conectado un archivo de loopback /mnt/work/lxd/hddpool.img, y en el dispositivo /dev/loop0 se ha conectado un archivo de loopback /var/lib/lxd/disks/ssdpool.img que corresponde al predeterminado Grupo de Almacenamiento.
El siguiente comando crea un nuevo Grupo de Almacenamiento en LXD basado en el archivo de loopback recién preparado. LXD formateará el archivo de loopback /mnt/work/lxd/hddpool.img en el dispositivo /dev/loop1 para el sistema de archivos BTRFS:
lxc storage create hddpool btrfs size=10GB source=/dev/loop1Mostremos la lista de todos Grupo de Almacenamiento en pantalla:
lxc storage list
+---------+-------------+--------+--------------------------------+---------+
| NAME | DESCRIPTION | DRIVER | SOURCE | USED BY |
+---------+-------------+--------+--------------------------------+---------+
| hddpool | | btrfs | /dev/loop1 | 0 |
+---------+-------------+--------+--------------------------------+---------+
| ssdpool | | btrfs | /var/lib/lxd/disks/ssdpool.img | 0 |
+---------+-------------+--------+--------------------------------+---------+Aumento del tamaño del grupo de almacenamiento
Después de crear Grupo de Almacenamiento, si es necesario, se puede ampliar. Para Grupo de Almacenamiento basado en el sistema de archivos BTRFS, ejecute los siguientes comandos:
sudo truncate -s +5G /mnt/work/lxd/hddpool.img
sudo losetup -c /dev/loop1
sudo btrfs filesystem resize max /var/lib/lxd/storage-pools/hddpoolAutoinserción de un archivo de bucle en el slot de dispositivo de bucle
Tenemos un pequeño problema, al reiniciar el sistema host, el archivo /mnt/work/lxd/hddpool.img "se desconectará" del dispositivo /dev/loop1 y el servicio LXD fallará al iniciar ya que no lo verá en este dispositivo. Para resolver este problema, es necesario crear un servicio del sistema que insertará este archivo en el dispositivo /dev/loop1 al iniciar el sistema host.
Crearemos de pruebas unitarias archivo tipo el servicio en /etc/systemd/system/ para el sistema de inicialización 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
EOFActivamos el servicio:
sudo systemctl enable lxd-hddpool
Se creó un enlace simbólico en /etc/systemd/system/local-fs.target.wants/lxd-hddpool.service → /etc/systemd/system/lxd-hddpool.service.Después de reiniciar el sistema host, comprobamos el estado del servicio:
systemctl status lxd-hddpool.service
● lxd-hddpool.service - Losetup LXD Storage Pool (hddpool)
Cargado: cargado (/etc/systemd/system/lxd-hddpool.service; habilitado; ajuste de proveedor: deshabilitado)
Activo: activo (salió) desde el Wed 2020-04-08 03:43:53 MSK; hace 1min 37s
Proceso: 711 ExecStart=/sbin/losetup /dev/loop1 /mnt/work/lxd/hddpool.img (código=salió, estado=0/SÉXITO)
PID principal: 711 (código=salió, estado=0/SÉXITO)
abr 08 03:43:52 manjaro systemd[1]: Iniciando Losetup LXD Storage Pool (hddpool)...
abr 08 03:43:53 manjaro systemd[1]: Finalizado Losetup LXD Storage Pool (hddpool).De la salida podemos asegurarnos de que el estado del servicio es active, a pesar de que la ejecución de nuestro script de un solo comando finalizó, esto nos permitió hacer la opción RemainAfterExit=true.
Seguridad. Privilegios de los contenedores
Dado que todos los procesos del contenedor se ejecutan en aislamiento en el sistema host utilizando su núcleo, para proteger el acceso de los procesos del contenedor al sistema host, LXD ofrece privilegiados procesos, donde:
Contenedores privilegiados son contenedores en los que los procesos con UID y GID corresponden al mismo propietario que en el sistema host. Por ejemplo, un proceso ejecutado en un contenedor con UID igual a 0 tiene los mismos derechos de acceso que un proceso del sistema host con UID igual a 0. En otras palabras, el usuario root en el contenedor tiene todos los derechos no solo dentro del contenedor, sino también en el sistema host si puede salir del espacio de nombres aislado del contenedor.
Contenedores no privilegiados son contenedores en los que los procesos pertenecen al propietario con UID y GID de 0 a 65535, pero para el sistema host el propietario se enmascara mediante el bit SubUID y SubGID añadidos. Por ejemplo, un usuario con UID=0 en el contenedor será visto en el sistema host como
SubUID + UID. Esto protege al sistema host, ya que si algún proceso en el contenedor puede salir de su espacio de nombres aislado, solo puede interactuar con el sistema host como un proceso con UID/GID desconocido y muy alto.
Por defecto, los contenedores recién creados tienen el estado de no privilegiados y por lo tanto debemos definir SubUID y SubGID.
Crearemos dos archivos de configuración en los que establecemos la máscara para SubUID y SubGID respectivamente:
sudo touch /etc{/subuid,/subgid}
sudo usermod --add-subuids 1000000-1065535 root
sudo usermod --add-subgids 1000000-1065535 rootPara aplicar los cambios, el servicio LXD debe ser reiniciado:
sudo systemctl restart lxdCreación de un conmutador virtual de red
Dado que anteriormente inicializamos la red utilizando el asistente de inicialización respondiendo a algunas preguntas. y creamos un dispositivo de red lxdbr0, en esta sección solo nos familiarizaremos con la red en LXD y con cómo crear un conmutador virtual (puente de red, bridge) utilizando el comando del cliente.
El siguiente esquema muestra cómo el conmutador (puente de red, bridge) conecta el host y los contenedores en la red:

Los contenedores pueden interactuar a través de la red con otros contenedores o con el host en el que están alojados. Para ello, es necesario enlazar las tarjetas de red virtuales de los contenedores con el conmutador virtual. Primero crearemos el conmutador, y las interfaces de red del contenedor se enlazarán en capítulos posteriores, después de que se haya creado el propio contenedor.
El siguiente comando crea un conmutador con una subred 10.0.5.0/24 y una dirección IPv4 10.0.5.1/24, y también habilita ipv4.nat para que los contenedores puedan acceder a Internet a través del host utilizando el servicio NAT:
lxc network create lxdbr0 ipv4.address=10.0.5.1/24 ipv4.nat=true ipv6.address=noneVerificamos la lista de dispositivos de red disponibles en LXD:
lxc network list
+--------+----------+---------+-------------+---------+
| NAME | TYPE | MANAGED | DESCRIPTION | USED BY |
+--------+----------+---------+-------------+---------+
| eno1 | physical | NO | | 0 |
+--------+----------+---------+-------------+---------+
| lxdbr0 | bridge | YES | | 0 |
+--------+----------+---------+-------------+---------+Además, se puede verificar la creación del dispositivo de red utilizando la herramienta estándar del sistema operativo Linux — ip link o 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 0Perfil de configuración
Cada contenedor en LXD tiene su propia configuración y puede expandirla mediante configuraciones declaradas globalmente que se denominan perfiles de configuración. La aplicación de perfiles de configuración a un contenedor sigue un modelo en cascada; el siguiente ejemplo lo demuestra:

En este ejemplo, se han creado tres perfiles en el sistema LXD: default, hddpool y hostfs. Los tres perfiles se aplican a un contenedor que tiene una configuración local (zona gris). El perfil default tiene un dispositivo root que tiene el parámetro pool es igual a ssdpool, pero gracias al modelo en cascada de aplicación de configuración, podemos aplicar al contenedor el perfil hddpool que tiene el parámetro pool sobrescribirá este mismo parámetro del perfil default y el contenedor recibirá la configuración del dispositivo root con el parámetro pool igual a hddpool, mientras que el perfil hostfs simplemente añade un nuevo dispositivo al contenedor.
Para ver la lista de perfiles de configuración disponibles, se utiliza el siguiente comando:
lxc profile list
+---------+---------+
| NAME | USED BY |
+---------+---------+
| default | 1 |
+---------+---------+
| hddroot | 0 |
+---------+---------+
| ssdroot | 1 |
+---------+---------+La lista completa de comandos disponibles para trabajar con perfiles se puede obtener agregando la clave --help:
lxc profile --help
Descripción:
Gestionar perfiles
Uso:
lxc profile [comando]
Comandos disponibles:
add Agregar perfiles a instancias
assign Asignar conjuntos de perfiles a instancias
copy Copiar perfiles
create Crear perfiles
delete Eliminar perfiles
device Gestionar dispositivos de instancia
edit Editar configuraciones de perfil como YAML
get Obtener valores para claves de configuración de perfil
list Listar perfiles
remove Eliminar perfiles de instancias
rename Renombrar perfiles
set Establecer claves de configuración de perfil
show Mostrar configuraciones de perfil
unset Desestablecer claves de configuración de perfilEdición del perfil
El perfil de configuración por defecto default no tiene configuración de tarjeta de red para el contenedor y todos los contenedores creados no tienen red. Para ellos, es necesario crear dispositivos de red locales (dedicados) con un comando separado, pero podemos crear en el perfil de configuración un dispositivo de red global que será compartido entre todos los contenedores que usen este perfil. Así, inmediatamente después del comando de creación de un nuevo contenedor, tendrán red con acceso a la red. En este sentido, no hay restricciones; siempre podemos crear más tarde un dispositivo de red local si es necesario.
El siguiente comando añadirá a la configuración del perfil un dispositivo eth0 del tipo nic conectado a la red lxdbr0:
lxc profile device add default eth0 nic network=lxdbr0 name=eth0Es importante señalar que, dado que hemos agregado un dispositivo al perfil de configuración, si hubiéramos especificado una dirección IP estática para el dispositivo, todos los contenedores que apliquen este perfil compartirían la misma dirección IP. Si es necesario crear un contenedor con una dirección IP estática dedicada, entonces se debe crear una configuración de dispositivo de red a nivel del contenedor (configuración local) con la dirección IP, y no a nivel de perfil.
Verificamos el perfil:
lxc profile show default
config: {}
description: Perfil LXD predeterminado
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: \/
pool: ssdpool
type: disk
name: default
used_by: []En este perfil podemos ver que se crearán dos dispositivos (devices) para todos los contenedores recién creados:
eth0— Dispositivo del tiponicconectado a un switch (puente de red)lxdbr0root— Dispositivo del tipodiscoque utiliza un pool de almacenamientossdpool
Creación de nuevos perfiles
Para usar los anteriormente creados Grupo de Almacenamiento contenedores, crearemos un perfil de configuración ssdroot en el que añadiremos un dispositivo del tipo disco con un punto de montaje / (root) usando el ya creado Grupo de Almacenamiento — ssdpool:
lxc profile create ssdroot
lxc profile device add ssdroot root disk path=\/ pool=ssdpoolDe manera similar, creamos un dispositivo del tipo disco, pero en este caso utilizando Grupo de Almacenamiento — hddpool:
lxc profile create hddroot
lxc profile device add hddroot root disk path=\/ pool=hddpoolVerificamos los perfiles de configuración:
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: []Repositorio de imágenes
Los contenedores se crean a partir de imágenes que son distribuciones especialmente construidas sin núcleo de Linux. Por lo tanto, antes de ejecutar un contenedor, debe ser desplegado a partir de esta imagen. La fuente de las imágenes es un repositorio local donde se cargan las imágenes desde repositorios externos.
Repositorios de imágenes remotas
Por defecto, LXD está configurado para recibir imágenes de tres fuentes remotas:
- ubuntu: (para imágenes estables de Ubuntu)
- ubuntu-daily: (para imágenes diarias de Ubuntu)
- images: (para un conjunto de otras distribuciones)
lxc remote list
+-----------------+------------------------------------------+--------+--------+
| NOMBRE | URL | PÚBLICO | ESTÁTICO |
+-----------------+------------------------------------------+--------+--------+
| imágenes | https://images.linuxcontainers.org | SÍ | NO |
+-----------------+------------------------------------------+--------+--------+
| local (predeterminado) | unix:// | NO | SÍ |
+-----------------+------------------------------------------+--------+--------+
| ubuntu | https://cloud-images.ubuntu.com/releases | SÍ | SÍ |
+-----------------+------------------------------------------+--------+--------+
| ubuntu-daily | https://cloud-images.ubuntu.com/daily | SÍ | SÍ |
+-----------------+------------------------------------------+--------+--------+Por ejemplo, el repositorio ubuntu: tiene las siguientes imágenes:
lxc image -c dasut list ubuntu: | head -n 11
+----------------------------------------------+--------------+----------+------------+
| DESCRIPCIÓN | ARQUITECTURA | TAMAÑO | TIPO |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150728) | x86_64 | 153.72MB | CONTENEDOR |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150819) | x86_64 | 152.91MB | CONTENEDOR |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150906) | x86_64 | 154.69MB | CONTENEDOR |
+----------------------------------------------+--------------+----------+------------+
| ubuntu 12.04 LTS amd64 (release) (20150930) | x86_64 | 153.86MB | CONTENEDOR |
+----------------------------------------------+--------------+----------+------------+Para mostrar un número limitado de columnas usamos la opción — el número de paquetes, después de los cuales con los parámetros dasut, y también limitamos la longitud de la lista con el comando head.
Para mostrar la lista de imágenes, está disponible la filtración. El siguiente comando mostrará la lista de todas las arquitecturas disponibles del distribuidor :
lxc image -c ldast list images:alpine/3.11
+------------------------------+--------------------------------------+--------------+
| ALIAS | DESCRIPCIÓN | ARQUITECTURA |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11 (3 más) | Alpine 3.11 amd64 (20200220_13:00) | x86_64 |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/arm64 (1 más) | Alpine 3.11 arm64 (20200220_13:00) | aarch64 |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/armhf (1 más) | Alpine 3.11 armhf (20200220_13:00) | armv7l |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/i386 (1 más) | Alpine 3.11 i386 (20200220_13:01) | i686 |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/ppc64el (1 más) | Alpine 3.11 ppc64el (20200220_13:00) | ppc64le |
+------------------------------+--------------------------------------+--------------+
| alpine/3.11/s390x (1 más) | Alpine 3.11 s390x (20200220_13:00) | s390x |
+------------------------------+--------------------------------------+--------------+Repositorio de imágenes local
Para comenzar a utilizar el contenedor, es necesario añadir una imagen del repositorio global al local. local:En este momento, el repositorio local está vacío, así que la siguiente orden nos confirmará esto: lxc image listSi no se especifica un repositorio en el método, por defecto se utilizará el repositorio local — list lxc image list local:+-------+-------------+--------+-------------+--------------+------+------+ | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE | +-------+-------------+--------+-------------+--------------+------+------+ local:
La gestión de imágenes en el repositorio se realiza mediante los siguientes métodos:lxc image
Comando
Descripción
Gestionar alias de imágenes alias
Copiar imágenes entre servidores
Gestionar alias de imágenes copy
Eliminar imágenes
Gestionar alias de imágenes delete
Editar propiedades de la imagen
Gestionar alias de imágenes edit
exportar
Gestionar alias de imágenes Exportar y descargar imágenes
Importar imágenes en el almacén de imágenes
Gestionar alias de imágenes import
Mostrar información útil sobre las imágenes
Gestionar alias de imágenes info
Listar imágenes
Gestionar alias de imágenes list
Actualizar imágenes
Gestionar alias de imágenes -token.
mostrar
Gestionar alias de imágenes Mostrar propiedades de la imagen
Copiamos la imagen al repositorio local desde el global
lxc image copy images:alpine/3.11/amd64 local: --alias=alpine3¡Imagen copiada con éxito! images::
Mostraremos la lista de todas las imágenes disponibles actualmente en el repositorio locallxc image -c lfdatsu list local:+---------+--------------+------------------------------------+--------------+ | ALIAS | FINGERPRINT | DESCRIPTION | ARCHITECTURE | +---------+--------------+------------------------------------+--------------+ | alpine3 | 73a3093d4a5c | Alpine 3.11 amd64 (20200220_13:00) | x86_64 | +---------+--------------+------------------------------------+--------------+ local::
Además del modo interactivo, LXD también admite un modo no interactivo de configuración, que es cuando la configuración se establece en forma de archivo YAML, un formato especial que permite establecer toda la configuración a la vez, omitiendo la ejecución de múltiples órdenes interactivas que se han tratado anteriormente en este artículo, incluyendo la configuración de red, la creación de perfiles de configuración, etc. Aquí no vamos a tratar este aspecto, puedes informarte sobre esto por ti mismo.Configuración de LXD
El siguiente comando interactivo .
lxc config que vamos a revisar permite configurar las opciones. Por ejemplo, para que las imágenes descargadas en el repositorio local no se actualicen automáticamente desde los repositorios globales, podemos habilitar este comportamiento con el siguiente comando: lxc config set images.auto_update_cached=false
Para crear un contenedor, se utiliza el comandoCreación y gestión de un contenedor
al que se le pasan los valores lxc init repositorio:imagen y luego el identificador deseado para el contenedor. El repositorio puede ser especificado como local. es local: así como cualquier global. Si no se especifica un repositorio, por defecto, se utiliza el repositorio local para buscar la imagen. Si se indica una imagen del repositorio global, primero se descargará la imagen en el repositorio local y luego se utilizará para crear el contenedor.
Ejecutaremos el siguiente comando para crear nuestro primer contenedor:
lxc init alpine3 alp --storage=hddpool --profile=default --profile=hddrootDesglosemos uno por uno las claves del comando que usamos aquí:
alpine3— Se especifica un alias (seudónimo) para la imagen que se ha descargado anteriormente en el repositorio local. Si no se creó un alias para esta imagen, siempre se puede referir a la imagen por su Huella digital que se muestra en la tabla.alp— Se asigna un identificador para el contenedor--storage— Esta clave indica en qué Grupo de Almacenamiento se creará el contenedor--profile— Estas claves aplican en cascada la configuración del contenedor de los perfiles de configuración creados previamente
Iniciamos el contenedor, que comienza a ejecutar el sistema init de la distribución:
lxc start alpTambién se puede usar el comando lxc launch que permite combinar los comandos lxc init y lxc start en una sola operación.
Comprobamos el estado del contenedor:
lxc list -c ns46tb
+------+---------+------------------+------+-----------+--------------+
| NAME | STATE | IPV4 | IPV6 | TYPE | STORAGE POOL |
+------+---------+------------------+------+-----------+--------------+
| alp | RUNNING | 10.0.5.46 (eth0) | | CONTAINER | hddpool |
+------+---------+------------------+------+-----------+--------------+Comprobamos la configuración del contenedor:
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: ""En la sección perfiles podemos asegurarnos de que este contenedor utiliza dos perfiles de configuración — default y hddroot. En la sección dispositivos solo podemos detectar un dispositivo, ya que el dispositivo de red se creó a nivel de perfil defaultPara ver todos los dispositivos utilizados por el contenedor, es necesario agregar la clave --expanded:
lxc config show alp --expanded
arquitectura: 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:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: \/
pool: hddpool
type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""Asignación de una dirección IP estática
Si intentamos establecer la dirección IP para el dispositivo de red eth0 con el comando lxc config device set alp destinada a la configuración del contenedor, obtendremos un error que indicará que el dispositivo no existe porque el dispositivo eth0 que usa el contenedor pertenece al perfil default:
lxc config device set alp eth0 ipv4.address 10.0.5.5
Error: El dispositivo no existePor supuesto, podemos establecer una dirección IP estática para eth0 el dispositivo en el perfil, pero será única para todos los contenedores que utilicen este perfil. Por lo tanto, agreguemos un dispositivo dedicado para el contenedor:
lxc config device add alp eth0 nic name=eth0 nictype=bridged parent=lxdbr0 ipv4.address=10.0.5.5Luego, es necesario reiniciar el contenedor:
lxc restart alpSi ahora miramos la configuración del contenedor, no necesitamos aplicar la opción --expanded para ver el dispositivo de red eth0, ya que lo creamos a nivel de contenedor y ha cubierto en cascada el mismo dispositivo del perfil default:
lxc config show alp
arquitectura: 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: 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: RUNNING
devices:
eth0:
ipv4.address: 10.0.5.5
name: eth0
nictype: bridged
parent: lxdbr0
type: nic
root:
path: \/
pool: hddpool
type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""Eliminación del contenedor
Para eliminar el contenedor, se usa el comando lxc delete, pero antes de eliminar el contenedor, debe ser detenido con el comando lxc stop:
lxc stop alplxc list
+------+---------+-------------------+------+-----------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+---------+-------------------+------+-----------+-----------+
| alp | STOPPED | 10.0.5.10 (eth0) | | CONTAINER | 0 |
+------+---------+-------------------+------+-----------+-----------+Después de asegurarnos de que el estado del contenedor es STOPPED, se puede eliminar de Grupo de Almacenamiento:
lxc delete alpAcceso al contenedor
Para ejecutar comandos en el contenedor directamente, omitiendo las conexiones de red, se usa el comando lxc exec que ejecuta comandos en el contenedor sin iniciar un shell del sistema. Si necesita ejecutar un comando en el shell, utilizando patrones de shell, como variables, redirecciones de archivos (pipe), etc., debe iniciar el shell explícitamente y pasar el comando como argumento, por ejemplo:
lxc exec alp -- \/bin\/sh -c "echo $HOME"En el comando se utilizó un símbolo especial de escape para el símbolo especial $ para que la variable $HOME no se interprete en la máquina host, sino que se interprete solo dentro del contenedor.
También es posible iniciar el modo interactivo del shell, y luego finalizar la sesión usando la tecla de acceso rápido CTRL+D:
lxc exec alp -- \/bin\/shGestión de los recursos del contenedor
En LXD, se puede gestionar los recursos del contenedor mediante un conjunto especial de configuraciones. La lista completa de parámetros de configuración del contenedor se puede encontrar .
Límite de recursos de RAM (memoria)
Parámetro limits.memory limita la cantidad de RAM accesible para el contenedor. Como valor, se indica un número y uno de los .
Introduzcamos un límite de 256 MB de RAM para el contenedor:
lxc config set alp limits.memory 256MBAdemás, existen otros parámetros para limitar la memoria:
limits.memory.enforcelimits.memory.hugepageslimits.memory.swaplimits.memory.swap.priority
Comando lxc config show permite mostrar toda la configuración del contenedor, incluyendo la limitación de recursos aplicada:
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: ""Límite de recursos de CPU
Para limitar los recursos de la CPU, existen varios :
limit.cpu— asigna el contenedor a uno o varios núcleos de CPUlimits.cpu.allowance— gestiona las cuotas del planificador CFS, cuando se ha agotado el límite de tiempo, o un mecanismo universal de uso compartido de recursos de CPU, cuando se ha superado un valor porcentuallimits.cpu.priority— prioridad del planificador, cuando se ha asignado el mismo porcentaje de CPU a varias instancias que comparten un conjunto de procesadores
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: ""Límite de espacio en disco
Además de las limitaciones tales como limits.read, limits.write también podemos limitar la cantidad de espacio en disco usado por el contenedor (solo funciona con ZFS o BTRFS):
lxc config device set alp root size=2GBDespués de la configuración, en el parámetro devices.root.size podemos verificar la limitación establecida:
lxc config show alp
...
devices:
root:
path: \/
pool: hddpool
size: 2GB
type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""Para revisar las cuotas de disco utilizadas, podemos obtenerlo del comando lxc info:
lxc info alp
...
Resources:
Processes: 5
Disk usage:
root: 1.05GB
CPU usage:
CPU usage (in seconds): 1
Memory usage:
Memory (current): 5.46MB
Network usage:
eth0:
Bytes received: 802B
Bytes sent: 1.59kB
Packets received: 4
Packets sent: 14
lo:
Bytes received: 0B
Bytes sent: 0B
Packets received: 0
Packets sent: 0A pesar de que hemos establecido un límite para el dispositivo raíz del contenedor en 2GB, utilidades del sistema como df no verán este límite. Para ello, realizaremos una pequeña prueba y averiguaremos cómo funciona.
Crearemos 2 nuevos contenedores idénticos en el mismo Grupo de Almacenamiento (hddpool):
lxc init alpine3 alp1 --storage=hddpool --profile=default --profile=hddroot
lxc init alpine3 alp2 --storage=hddpool --profile=default --profile=hddrootlxc 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 |
+------+---------+------------------+------+-----------+-----------+En uno de los contenedores, crearemos un archivo de 1GB:
lxc exec alp1 -- dd if=/dev/urandom of=file.img bs=1M count=1000Asegurémonos de que el archivo se haya creado:
lxc exec alp1 -- ls -lh
total 1000M
-rw-r--r-- 1 root root 1000.0M Mar 27 10:16 file.imgSi miramos en el segundo contenedor y comprobamos la existencia del archivo en el mismo lugar, no habrá dicho archivo, lo cual es esperado, ya que los contenedores se crean en sus propios Storage Volume en este mismo Grupo de Almacenamiento:
lxc exec alp2 -- ls -lh
total 0Pero comparemos los valores que reporta df en los dos contenedores:
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 montado como la partición raíz es Grupo de Almacenamiento la cual estos contenedores utilizan, por lo que comparten su volumen entre ellos.
Estadísticas de consumo de recursos
Puede ver las estadísticas de consumo de recursos para el contenedor usando el siguiente 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: 0Trabajo con instantáneas
En LXD, existe la posibilidad de crear instantáneas y restaurar el estado del contenedor desde ellas.
Para crear una instantánea, ejecute el siguiente comando:
lxc snapshot alp snapshot1El comando lxc snapshot no tiene la opción list, por lo que, para ver la lista de instantáneas, debes utilizar un comando que muestre información general sobre el contenedor:
lxc info alp
...
...
Instantáneas:
instantánea1 (tomada el 2020/04/08 18:18 UTC) (sin estado)Se puede restaurar el contenedor a partir de una instantánea con el comando lxc restore especificando el contenedor para el cual se realizará la restauración y el alias de la instantánea:
lxc restore alp instantánea1El siguiente comando se utiliza para eliminar una instantánea. Tenga en cuenta que la sintaxis del comando no se parece a todos los demás; aquí es necesario indicar una barra diagonal después del nombre del contenedor. Si se omite la barra, el comando de eliminación de la instantánea se interpretará como un comando de eliminación del contenedor.
lxc delete alp/instantánea1En el ejemplo anterior, consideramos las llamadas instantáneas sin estado. En LXD hay otro tipo de instantáneas: con estado, en las que se guarda el estado actual de todos los procesos en el contenedor. Las instantáneas con estado están asociadas a una serie de funciones interesantes y útiles.
¿Qué más?
- Para los desarrolladores de Python, está disponible el módulo que proporciona una API para LXD
ACTUALIZACIÓN 10.04.2020 15:00: Agregué navegación
Fuente: habr.com
