Introducción
Un contenedor Linux es un conjunto de procesos independiente del resto del sistema. Para el usuario final, un contenedor Linux funciona como una máquina virtual, pero es mucho más ligero. No tiene la sobrecarga de ejecutar un kernel Linux adicional y los contenedores no requieren compatibilidad con la virtualización de hardware de CPU. Esto significa que puede crear más contenedores que máquinas virtuales en el mismo servidor.
Imagina que tienes un servidor que debe ejecutar varios sitios web para tus clientes. Por un lado, cada sitio web podría ser un bloque de host/servidor virtual de la misma instancia del servidor web Apache o Nginx. Por otro lado, al usar máquinas virtuales, crearías una máquina virtual anidada independiente para cada sitio web. Los contenedores Linux se encuentran entre los hosts virtuales y las máquinas virtuales.
LXD te permite crear y administrar estos contenedores. LXD proporciona un servicio de hipervisor para gestionar todo el ciclo de vida de los contenedores. En este tutorial, configurarás LXD y lo usarás para ejecutar Nginx en un contenedor. Después, dirigirás el tráfico de internet al contenedor para que una página web de ejemplo sea accesible.
Prerrequisitos
Para completar este tutorial, necesitarás lo siguiente:
- Un servidor con Ubuntu 20.04 . Para configurar un servidor, incluyendo un usuario sudo no root y un firewall, puede crear un Droplet de IsnHosting con Ubuntu 20.04 y luego seguir nuestra Guía de configuración inicial del servidor . Anote la dirección IP pública de su servidor. Más adelante la llamaremos
your_server_ip
. - Al menos 5 GB de almacenamiento en bloque. Para configurarlo, puede seguir la Guía rápida de volúmenes de almacenamiento en bloque de IsnHosting. En la configuración del almacenamiento en bloque, seleccione
Manually Format & Mount
[para permitir que LXD lo prepare según sea necesario]. Esto se utilizará para almacenar todos los datos relacionados con los contenedores.
Nota: A partir de Ubuntu 20.04, LXD está disponible oficialmente como paquete snap. Este nuevo formato de paquete ofrece varias ventajas. Un paquete snap se puede instalar en cualquier distribución de Linux compatible con este tipo de paquetes . Se recomienda usar un servidor con al menos 2 GB de RAM al ejecutar el paquete snap de LXD. La siguiente tabla resume las características del paquete snap de LXD:
Característica | paquete instantáneo |
---|---|
versiones LXD disponibles | 2.0, 3.0, 4.0, 4.x |
requisitos de memoria | Moderado, para el servicio SnapD . Servidor recomendado con 2 GB de RAM. |
Consideraciones de actualización | Puede aplazar la actualización de LXD hasta 60 días |
Capacidad de actualizar desde otro formato de paquete | Puede actualizar de deb a snap. |
Sigue el resto de este tutorial para usar LXD desde el paquete snap en Ubuntu 20.04. Si, por el contrario, quieres usar el paquete deb de LXD, consulta nuestro tutorial ” Cómo instalar y usar LXD en Ubuntu 18.04″ .
Paso 1: Preparación del entorno para LXD
Antes de configurar y ejecutar LXD, deberá preparar el entorno de su servidor. Esto implica agregar el usuario sudo al lxd
grupo y configurar el backend de almacenamiento.
Cómo agregar su cuenta no root al lxd
grupo Unix
Al configurar su cuenta no root, agréguela al lxd
grupo con el siguiente comando. El adduser
comando toma como argumentos la cuenta de usuario y el grupo Unix para agregar la cuenta de usuario al grupo Unix existente:
sudo adduser sammy lxd
Ahora aplica la nueva membresía:
su sammy
Introduzca su contraseña y presione ENTER
.
Por último, confirma que tu usuario ahora está agregado al lxd
grupo:
id -nG
Recibirás un resultado como este:
sammy sudo lxd
Ahora está listo para continuar configurando LXD.
Preparación del backend de almacenamiento
Para comenzar, configurará el backend de almacenamiento.
El sistema de almacenamiento recomendado para LXD en Ubuntu es el sistema de archivos ZFS. ZFS también funciona muy bien con el almacenamiento en bloque de IsnHosting . Para habilitar la compatibilidad con ZFS en LXD, primero actualice la lista de paquetes y luego instale el zfsutils-linux
paquete auxiliar:
sudo apt update
sudo apt install -y zfsutils-linux
Estamos casi listos para ejecutar el script de inicialización de LXD.
Antes de hacerlo, debe identificar y tomar nota del nombre del dispositivo para su almacenamiento en bloque.
Para ello, utilice ls
para comprobar el /dev/disk/by-id/
directorio:
ls -l /dev/disk/by-id/
En este ejemplo específico, la ruta completa del nombre del dispositivo es /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-0
:
Outputtotal 0
lrwxrwxrwx 1 root root 9 Sep 16 20:30 scsi-0DO_Volume_volume-fra1-0 -> ../../sda
Anote la ruta completa del archivo de su dispositivo de almacenamiento. La usará en el siguiente paso al configurar LXD.
Paso 2: Inicialización y configuración de LXD
LXD está disponible como paquete snap en Ubuntu 20.04. Viene preinstalado, pero debes configurarlo.
Primero, verifique que el paquete snap de LXD esté instalado. El comando snap list
muestra los paquetes snap instalados:
snap list
Ubuntu 20.04 preinstala LXD 4.0.3 y está siguiendo el 4.0/stable
canal. LXD 4.0 tiene soporte durante cinco años (hasta 2025). Solo recibirá actualizaciones de seguridad:
Output of the "snap list" command — Listing the installed snap packagesName Version Rev Tracking Publisher Notes
core18 20200724 1885 latest/stable canonical✓ base
lxd 4.0.3 16922 4.0/stable/… canonical✓ -
snapd 2.45.3.1 8790 latest/stable canonical✓ snapd
Para obtener más información sobre el paquete snap instalado en LXD, ejecute snap info lxd
. Podrá ver las versiones disponibles, incluyendo la fecha de la última actualización.
Ahora configurarás LXD.
Configuración de opciones de almacenamiento para LXD
Inicie el proceso de inicialización de LXD utilizando el sudo lxd init
comando:
sudo lxd init
Primero, el programa le preguntará si desea habilitar la agrupación en clústeres de LXD. Para este tutorial, presione ENTER
para aceptar el valor predeterminado no
o escriba no
y luego presione ENTER
. La agrupación en clústeres de LXD es un tema avanzado que permite alta disponibilidad para su configuración de LXD y requiere al menos tres servidores LXD ejecutándose en un clúster:
OutputWould you like to use LXD clustering? (yes/no) [default=no]: no
Las siguientes seis indicaciones abordan el pool de almacenamiento. Proporcione las siguientes respuestas:
- Presione
ENTER
para configurar un nuevo grupo de almacenamiento. - Presione
ENTER
para aceptar el nombre del grupo de almacenamiento predeterminado. - Presione
ENTER
para aceptar elzfs
backend de almacenamiento predeterminado. - Presione
ENTER
para crear un nuevo grupo ZFS. - Escriba
yes
para utilizar un dispositivo de bloque existente. - Por último, escriba la ruta completa al nombre del dispositivo de almacenamiento en bloque (esto es lo que registró anteriormente. Debería ser algo como: ).
/dev/disk/by-id/device_name
Sus respuestas se verán así:
OutputDo you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: default
Name of the storage backend to use (btrfs, dir, lvm, zfs) [default=zfs]: zfs
Create a new ZFS pool? (yes/no) [default=yes]: yes
Would you like to use an existing block device? (yes/no) [default=no]: yes
Path to the existing block device: /dev/disk/by-id/scsi-0DO_Volume_volume-fra1-01
Ya has configurado el backend de almacenamiento para LXD. Siguiendo con init
el script de LXD, configurarás algunas opciones de red.
Configuración de opciones de red para LXD
LXD ahora pregunta si desea conectarse a un servidor MAAS (Metal As A Server). MAAS es un software que hace que un servidor físico parezca una máquina virtual y se gestione como tal.
Estamos ejecutando LXD en modo independiente, por lo tanto, acepte el valor predeterminado y responda no
:
OutputWould you like to connect to a MAAS server? (yes/no) [default=no]: no
Se le pedirá que configure un puente de red para los contenedores LXD. Esto habilita las siguientes funciones:
- Cada contenedor obtiene automáticamente una dirección IP privada.
- Cada contenedor puede comunicarse con los demás a través de la red privada.
- Cada contenedor puede iniciar conexiones a Internet.
- De forma predeterminada, cada contenedor permanece inaccesible desde internet; no es posible iniciar una conexión desde internet y acceder a un contenedor a menos que se habilite explícitamente. Aprenderá a permitir el acceso a un contenedor específico en el siguiente paso.
Cuando se le solicite crear un nuevo puente de red local, elija yes
:
OutputWould you like to create a new local network bridge? (yes/no) [default=yes]: yes
Luego acepta el nombre predeterminado lxdbr0
:
OutputWhat should the new bridge be called? [default=lxdbr0]: lxdbr0
Acepte la selección automatizada del rango de direcciones IP privadas para el puente:
OutputWhat IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
Finalmente, LXD plantea las siguientes preguntas diversas:
Cuando se le pregunte si desea administrar LXD a través de la red, presione ENTER
o responda no
:
OutputWould you like LXD to be available over the network? (yes/no) [default=no]: no
Cuando se le pregunte si desea actualizar automáticamente las imágenes de contenedores obsoletos, presione ENTER
o responda yes
:
OutputWould you like stale cached images to be updated automatically? (yes/no) [default=yes] yes
Cuando se le pregunte si desea ver y conservar la configuración YAML que acaba de crear, responda yes
si así lo desea. De lo contrario, presione ENTER
o responda no
:
OutputWould you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: no
Se ejecutará un script en segundo plano. Es normal que no se reciba ninguna salida.
Ya has configurado tus opciones de red y almacenamiento para LXD. A continuación, crearás tu primer contenedor LXD.
Paso 2: Creación y configuración de un contenedor LXD
Ahora que ha configurado LXD correctamente, está listo para crear y administrar su primer contenedor. En LXD, los contenedores se administran mediante el comando lxc
seguido de una acción, como list
, launch
, y .start
stop
delete
Utilice lxc list
para ver los contenedores instalados disponibles:
lxc list
Dado que esta es la primera vez que el lxc
comando se comunica con el hipervisor LXD, muestra información sobre cómo iniciar un contenedor. Finalmente, el comando muestra una lista vacía de contenedores. Esto es normal, ya que aún no hemos creado ninguno.
Output of the "lxd list" commandTo start your first container, try: lxc launch ubuntu:18.04
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
Ahora cree un contenedor que ejecute Nginx. Para ello, primero use el lxc launch
comando para crear e iniciar un contenedor de Ubuntu 18.04 llamado webserver
.
Crea el webserver
contenedor. ” 18.04
in” ubuntu:18.04
es un acceso directo para Ubuntu 18.04. ubuntu:
Es el identificador del repositorio preconfigurado de imágenes LXD. También puedes usar ubuntu:bionic
:
lxc launch ubuntu:20.04 webserver
Nota : Puede encontrar la lista completa de imágenes de Ubuntu disponibles ejecutando [<sub> lxc image list ubuntu:
y</sub> otras distribuciones de Linux ejecutando [<sub>y</sub>] lxc image list images:
. Tanto [<sub> ubuntu:
y</sub> images:
son repositorios de imágenes de contenedor. Para cada imagen de contenedor, puede obtener más información con el comando [<sub>y</sub>] lxc image info ubuntu:20.04
.
Como es la primera vez que crea un contenedor, este comando descarga la imagen del contenedor de internet y la almacena en caché. Verá este resultado una vez que el nuevo contenedor termine de descargarse:
OutputCreating webserver
Starting webserver
Con el webserver
contenedor iniciado, use el lxc list
comando para mostrar información sobre él. Hemos añadido ` --columns ns4
para` para mostrar solo las columnas de name
`,` state
y IPv4
`dirección`. El comando predeterminado lxc list
muestra tres columnas más: la dirección IPv6, si el contenedor es persistente o efímero, y si hay instantáneas disponibles para cada contenedor.
lxc list --columns ns4
La salida muestra una tabla con el nombre de cada contenedor, su estado actual, su dirección IP y su tipo:
Output+-----------+---------+------------------------------------+
| NAME | STATE | IPV4 |
+-----------+---------+------------------------------------+
| webserver | RUNNING | your_webserver_container_ip (eth0) |
+-----------+---------+------------------------------------+
El servidor DHCP de LXD proporciona esta dirección IP y, en la mayoría de los casos, se mantendrá igual incluso al reiniciar el servidor. Sin embargo, en los siguientes pasos, creará iptables
reglas para reenviar conexiones desde internet al contenedor. Por lo tanto, debe indicarle al servidor DHCP de LXD que siempre asigne la misma dirección IP al contenedor.
El siguiente conjunto de comandos configurará el contenedor para obtener una asignación de IP estática. Primero, anulará la configuración de red del eth0
dispositivo heredada del perfil LXD predeterminado. Esto le permite establecer una dirección IP estática, lo que garantiza la correcta comunicación del tráfico web hacia y desde el contenedor.
Específicamente, lxc config device
es un comando que config
configura un dispositivo device
. La primera línea contiene la subacción override
para anular el dispositivo eth0
del contenedor webserver
. La segunda línea contiene la subacción para configurar el ipv4.address
campo del eth0
dispositivo del webserver
contenedor con la dirección IP proporcionada inicialmente por el servidor DHCP.
Ejecute el primer config
comando:
lxc config device override webserver eth0
Recibirás un resultado como este:
OutputDevice eth0 overridden for webserver
Ahora configure la IP estática:
lxc config device set webserver eth0 ipv4.address your_webserver_container_ip
Si el comando es exitoso, no recibirá ninguna salida.
Reiniciar el contenedor:
lxc restart webserver
Ahora verifique el estado del contenedor:
lxc list
Deberías ver que el contenedor es RUNNING
y la IPV4
dirección es tu dirección estática.
Está listo para instalar y configurar Nginx dentro del contenedor.
Paso 3: Configuración de Nginx dentro de un contenedor LXD
En este paso te conectarás al webserver
contenedor y configurarás el servidor web.
Conéctese al contenedor con lxc shell
el comando, que toma el nombre del contenedor e inicia un shell dentro del contenedor:
lxc shell webserver
Una vez dentro del contenedor, el indicador de shell se verá así:
[environment second]
Este shell, incluso si es un shell raíz, está limitado al contenedor. Todo lo que se ejecuta en él permanece en el contenedor y no puede escapar al servidor host.
Nota: Al introducir un shell en un contenedor, es posible que vea una advertencia como mesg: ttyname failed: No such device
. Este mensaje se genera cuando el shell del contenedor intenta ejecutar el comando mesg
desde el archivo de configuración /root/.profile
. Puede ignorarlo sin problema. Para evitarlo, puede eliminar el comando mesg n || true
de /root/.profile
.
Una vez dentro de su contenedor, actualice la lista de paquetes e instale Nginx:
apt update
apt install nginx
Con Nginx instalado, ahora editará la página web predeterminada de Nginx. En concreto, añadirá dos líneas de texto para que quede claro que este sitio está alojado en el webserver
contenedor.
Usando nano
su editor preferido, abra el archivo /var/www/html/index.nginx-debian.html
:
nano /var/www/html/index.nginx-debian.html
Añade las dos frases resaltadas al archivo:
/var/www/html/index.nginx-debian.html<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx on LXD container webserver!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...
Editó el archivo en dos partes y agregó específicamente el texto on LXD container webserver
. Guarde el archivo y salga del editor de texto.
Ahora cierre la sesión del contenedor:
logout
Una vez que aparezca el mensaje predeterminado del servidor, use [nombre del servidor] curl
para comprobar que el servidor web del contenedor funciona correctamente. Para ello, necesitará la dirección IP del contenedor web, que obtuvo con el lxc list
comando anterior.
Utilice curl
para probar su servidor web:
curl http://your_webserver_container_ip
Recibirá la página de bienvenida HTML predeterminada de Nginx. Tenga en cuenta que incluye sus modificaciones:
Output<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx on LXD container webserver!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
...
El servidor web funciona, pero solo se puede acceder a él desde el host usando la IP privada. En el siguiente paso, enrutará las solicitudes externas a este contenedor para que todo el mundo pueda acceder a su sitio web a través de internet.
Paso 4: Reenvío de conexiones entrantes al contenedor Nginx mediante LXD
Ahora que ha configurado Nginx, es hora de conectar el contenedor del servidor web a internet. Para comenzar, debe configurar el servidor para que reenvíe 80
al webserver
contenedor cualquier conexión que reciba en el puerto. Para ello, creará una iptables
regla para reenviar las conexiones de red. Puede obtener más información sobre IPTables en nuestros tutoriales ” Cómo funciona el firewall de IPtables” y “Fundamentos de IPtables: Reglas y comandos comunes del firewall” .
Este iptables
comando requiere dos direcciones IP: la dirección IP pública del servidor ( your_server_ip
) y la dirección IP privada del webserver
contenedor ( your_webserver_container_ip
), que puede obtener mediante el lxc list
comando .
Ejecute este comando para crear una nueva regla de IPtables:
PORT=80 PUBLIC_IP=your_server_ip CONTAINER_IP=your_container_ip IFACE=eth0 sudo -E bash -c 'iptables -t nat -I PREROUTING -i $IFACE -p TCP -d $PUBLIC_IP --dport $PORT -j DNAT --to-destination $CONTAINER_IP:$PORT -m comment --comment "forward to the Nginx container"'
Estudiemos ese comando:
-t nat
especifica que estamos usando lanat
tabla para la traducción de direcciones.-I PREROUTING
especifica que estamos agregando la regla a la cadena PREROUTING.-i $IFACE
especifica la interfazeth0
, que es la interfaz de red pública predeterminada en el host para Droplets.-p TCP
dice que estamos usando el protocolo TCP.-d $PUBLIC_IP
Especifica la dirección IP de destino para la regla.--dport $PORT
: especifica el puerto de destino (por ejemplo80
).-j DNAT
dice que queremos realizar un salto a Destino NAT (DNAT).--to-destination $CONTAINER_IP:$PORT
dice que queremos que la solicitud vaya a la dirección IP del contenedor específico y al puerto de destino.
Nota: Puede reutilizar este comando para configurar reglas de reenvío. Restablezca las variables , y PORT
al PUBLIC_IP
principio de la línea. Simplemente cambie los valores resaltados.CONTAINER_IP
IFACE
Ahora enumera tus reglas de IPTables:
sudo iptables -t nat -L PREROUTING
Verás un resultado como este:
[secondary_label Output]
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT tcp -- anywhere your_server_ip tcp dpt:http /* forward to this container */ to:your_container_ip:80
...
Ahora prueba que el servidor web sea accesible desde Internet.
Utilice el curl
comando desde su máquina local para probar las conexiones:
curl --verbose 'http://your_server_ip'
Verás los encabezados seguidos del contenido de la página web que creaste en el contenedor:
Output* Trying your_server_ip...
* Connected to your_server_ip (your_server_ip) port 80 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Server: nginx/1.10.0 (Ubuntu)
...
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx on LXD container webserver!</title>
<style>
body {
...
Esto confirma que las solicitudes van al contenedor.
Por último, guardará la regla de firewall para que se vuelva a aplicar después de reiniciar.
Para ello, primero instale el iptables-persistent
paquete:
sudo apt install iptables-persistent
Al instalar el paquete, la aplicación le solicitará que guarde las reglas de firewall actuales. Acepte y guarde todas las reglas.
Al reiniciar el equipo, se cargará la regla del firewall. Además, el servicio Nginx del contenedor LXD se reiniciará automáticamente.
Has configurado LXD correctamente. En el paso final, aprenderás a detener y destruir el servicio.
Paso 5: Detención y retirada de contenedores mediante LXD
Puedes decidir que quieres desactivar el contenedor y eliminarlo. En este paso, lo detendrás y lo eliminarás.
Primero, detenga el contenedor:
lxc stop webserver
Utilice el lxc list
comando para verificar el estado:
lxc list
Verás que el estado del contenedor dice STOPPED
:
Output+-----------+---------+------+------+------------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+-----------+---------+------+------+------------+-----------+
| webserver | STOPPED | | | PERSISTENT | 0 |
+-----------+---------+------+------+------------+-----------+
Para retirar el contenedor, utilice lxc delete
:
lxc delete webserver
Al ejecutarlo lxc list
nuevamente se muestra que no hay ningún contenedor ejecutándose:
lxc list
El comando generará el siguiente resultado:
+------+-------+------+------+------+-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+------+-------+------+------+------+-----------+
Utilice el lxc help
comando para ver opciones adicionales.
Para eliminar la regla de firewall que enruta el tráfico al contenedor, primero ubique la regla en la lista de reglas con este comando, que asocia un número de línea con cada regla:
sudo iptables -t nat -L PREROUTING --line-numbers
Verás tu regla, precedida por un número de línea, de la siguiente manera:
OutputChain PREROUTING (policy ACCEPT)
num target prot opt source destination
1 DNAT tcp -- anywhere your_server_ip tcp dpt:http /* forward to the Nginx container */ to:your_container_ip
Utilice ese número de línea para eliminar la regla:
sudo iptables -t nat -D PREROUTING 1
Enumere nuevamente las reglas para garantizar la eliminación:
sudo iptables -t nat -L PREROUTING --line-numbers
Se elimina la regla:
OutputChain PREROUTING (policy ACCEPT)
num target prot opt source destination
Ahora guarde los cambios para que la regla no vuelva a aparecer cuando reinicie su servidor:
sudo netfilter-persistent save
Ahora puedes crear otro contenedor con tu propia configuración y agregar una nueva regla de firewall para reenviarle tráfico.
Conclusión
En este tutorial, instalaste y configuraste LXD. Luego, creaste un sitio web con Nginx, ejecutándose dentro de un contenedor LXD, y lo publicaste mediante IPtables.
Desde aquí, puedes configurar más sitios web, cada uno confinado en su propio contenedor, y usar un proxy inverso para dirigir el tráfico al contenedor correspondiente. El tutorial ” Cómo alojar varios sitios web con Nginx y HAProxy usando LXD en Ubuntu 16.04″ te guía en esta configuración.
Consulte la documentación de referencia de LXD para obtener más información sobre cómo utilizar LXD.
Para practicar con LXD, puedes probar LXD en línea y seguir el tutorial basado en la web.
Para obtener asistencia al usuario sobre LXD, visita el foro de discusión de LXD .