Màquinas virtuales lxc sobre Debian para principiantes

Creación de contenedores LXC (máquinas virtuales) con base Debian

Un contenedor LXC es una tecnología de virtualización a nivel de sistema operativo para Linux.

Las máquinas virtuales son útiles en los servidores, pues una máquina base se pueden tener diferentes máquinas virtuales o sistemas aislados con funciones diferentes en cada una.

La tecnología de contenedores  se monta sobre una máquina de base Debian, en la cual se instalan uno o más contenedores o máquinas virtuales, en nuestro caso siempre en Debian. Antiguamente se utilizaba Openvz, pero está opción está abandonada y resulta anticuada.

A partir de la Distribución 8 se dejó de utilizar Openvz y se paso a utilizar el propio Kernel Debian que ya permite el uso de contenedores independientes, no se trata de máquinas totalmente independientes sino que tienen propiedades comunes con el sistema que hace la virtualización más sencilla, siendo una opción claramente más moderna.

El presente articulo pretende ser únicamente una introducción sencilla para principiantes.

Podéis ver las siguientes webs o las que vosotros creáis mejores.






Para poder manipular con agilidad el sistema, facilitar su estudio y comprobación, y consultar a internet en todo momento, utilizaremos una máquina base con entorno gráfico siendo nuestro preferido el entorno Mate.
Podéis ver el artículo Adaptar Debian de este blog.

Las máquinas virtuales o contenedores escogidas siempre son Linux y, más concretamente, siempre utilizamos Debian aunque puede utilizar-se cualquier otra distribución, como es lógico no se pueden instalar contenedores Windows porque no utilizan el mismo sistema operativo, y recordar que hemos dicho que se utiliza Kernel de Linux como máquina base.

Utilizan las siguientes características más importantes del núcleo:

- Espacio de nombres del kernel (ipc, mount, network, pid, user).
- Chroots.
- CGroups.

Actualmente se dispone de los siguientes elementos:

- Librería liblxc.
- Diferentes lenguajes disponibles (Haskell, Go, Lua, Pyton 3, Ruby).
- Conjunto de herramientas pera interactuar con las máquinas contenedores.
- Plantillas con diferentes distribuciones, pero, tal como hemos comentado, nosotros  siempre utilizamos contenedores iguales y con Debian para facilitar el conjunto del mantenimiento.

Instalación de la base lxc:

# apt install lxc
# apt install bridge-utils libvirt-bin debootstrap

Poner en funcionamiento el sistema cgroup

# nano /etc/fstab

cgroup /sys/fs/cgroup cgroup defaults 0 0

montar cgroup

# mount /sys/fs/cgroup

Veamos como queda todo:

# lxc-checkconfig

Ahora crearemos un contenedor virtual, utilizando el nombre de máquina que se quiera

#  lxc-create -n nomb_maquina -t debian -- -r bullseye

También podéis crear el contenedor por copia de seguridad con la orden resync.

El comando será un poco más complicado:

# lxc-create -n nombre_maquina  -t debian -B lvm --vgname lxc --lvname lv_debian --fssize 1G --fstype xfs

Una vez acabado se debe entrar en el contenedor como root y poner contraseña, esta operación es imprescindible. Recordar que después se puede cambiar.


Ahora haremos dos pruebas de configuración de red en los contenedores la 1a será con DHCP que no es costumbre en servidores pero funciona, y la 2a será con una IP fija que es la opción habitual.

1.- Prueba de configuración de red física de los contenedores con DHCP en el servidor de base.

Máquina base

# nano /etc/network/interfaces

allow-hotplug eth0
iface eth0 inet static
        address 192.168.0.42
        netmask 255.255.255.0
        network 192.168.0.0
        gateway 192.168.0.1
        dns-nameserver x.x.x.x  # valor DNS
auto br0
iface br0 inet dhcp
        bridge_ports eth0
        bridge_fd 0
        bridge_maxwait 0

Fichero de configuración LXC

nano /var/lib/lxc/nom_maquina/config
# Agregamos:

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 12:ae:9a:12:ac:32
lxc.start.auto = 0
lxc.loglevel = 0
lxc.network.ipv4 = 192.168.0.100/24
lxc.network.ipv4.gateway = 192.168.0.1

2.- Configuración del contenedor con IP fija

Fichero de configuración de la máquina base

# nano /etc/network/interfaces
allow-hotplug eth0
iface eth0 inet static
        address 192.168.0.42
        netmask 255.255.255.0
        network 192.168.0.0
        gateway 192.168.0.1

auto br0
iface br0 inet dhcp
        bridge_ports eth0
        bridge_fd 0
        bridge_maxwait 0

Fichero de configuración LXC

# nano /var/lib/lxc/nom_maquina/config

lxc.network.type = veth
lxc.network.flags = up
lxc.network.link = br0
lxc.network.hwaddr = 12:ae:9a:12:ac:32
lxc.start.auto = 0
lxc.loglevel = 0
lxc.network.ipv4 = 192.168.0.45            # IP interna o externa del contenedor
lxc.network.ipv4.gateway = 192.168.0.1  #gateway vuestra externa


En todos los casos de configuración anteriores debe hacerse:

Vamos al fichero sysctl.con y se comenta (#)

# nano /etc/sysctl.conf

# net.ipv4.ip_forward=1

No se habla ni se utilizan IP externas, en los dos ejemplos se ha utilizado una Vlan de prueba, aunque esto no afecta para nada la explicación de configuración.

Una operación muy importante que no puede dejarse de tener en cuenta es la utilización de un cortafuegos. Nuestra intención es hacer un artículo para principiantes utilizando shorewall, que es la opción más común y más segura. Y como no es inmediata preferimos hacer uno  específico con este tema.


Configuremos el contenedor con los programas básicos

Ahora vamos a configurar las lenguas del contenedor con el programa locales.

# apt install nano
# apt install locales
# dpkg-reconfigure locales
# locale-gen

Para una distribución Debian strecth el contenedor que utilizaremos el siguiente repositorio.

# nano /etc/apt/sources.list

deb http://security.debian.org/ bullseye/updates main contrib non-free
# apt update

Después proponemos los siguientes programas:

# apt --no-install-recommends install -y adduser apt-utils iproute netbase sudo iputils-ping iptables rsyslog
# apt install --no-install-recommends openssh-blacklist openssh-blacklist-extra openssh-server
# apt install net-tools ifupdown sockstat
# apt install wget less lsof screen apt-utils nano telnet inetutils-ping psmisc aptitude


Ordenes lxc más sencillas

 Para iniciar el contenedor

# lxc-start -n contenedor1 -d

Conectar el contenedor anteriormente iniciado

# lxc-console -n contenedor1

Para salir presionar CTRL+a y al soltar q.

Para listar los  contenodores

# lxc-ls -f 

Para arrancar el contenedor

# lxc-startx -n nomb_maquina

Parar el contenedor

# lxc-stop -n nomb_maquina

Apagar el contenidor

# lxc-halt -n nomb_maquina

Eliminar el contenedor

# lxc-destroy -n nomb_maquina

Conocer la información del contenedor y la configuración

# lxc-info -n nomb_maquina
# lxc-checkconfig 

Clonar contenedor

# lxc-clone -o contenedor1 -n contenedor2

Si se desea que el contenedor se inicie al poner en funcionamiento el ordenador, hacer lo siguiente:

# nano /var/lib/lxc/contenidor1/config y agregamos:    

       lxc.start.auto = 1

Ejecutar comandos desde fuera del contenedor sin entrar en el:

# lxc-attach -n contenedor1 -- ip addr

Todas las ordenes posibles serian las siguientes, que podéis continuar investigando.

lxc-attach                  lxc-test-clonetest
lxc-autostart               lxc-test-concurrent
lxc-cgroup                  lxc-test-console
lxc-checkconfig             lxc-test-containertests
lxc-clone                   lxc-test-createtest
lxc-config                  lxc-test-destroytest
lxc-console                 lxc-test-device-add-remove
lxc-create                  lxc-test-get_item
lxc-destroy                 lxc-test-getkeys
lxc-device                  lxc-test-list
lxc-execute                 lxc-test-locktests
lxc-freeze                  lxc-test-lxcpath
lxc-info                    lxc-test-may-control
lxc-ls                      lxc-test-reboot
lxc-monitor                 lxc-test-saveconfig
lxc-snapshot                lxc-test-shutdowntest
lxc-start                   lxc-test-snapshot
lxc-start-ephemeral         lxc-test-startone
lxc-stop                    lxc-test-symlink
lxc-test-apparmor           lxc-unfreeze
lxc-test-attach             lxc-unshare
lxc-test-autostart          lxc-usernsexec
lxc-test-cgpath             lxc-wait

Veamos como ejemplo, para listar los contenedores:

# lxc-ls -f  

NAME                 STATE           IPV4    IPV6  AUTOSTART
------------------------------------------------------------------------------
nombre_maquina  RUNNING  192.168.0.45  -     YES  

Acceso SSH

Para tener acceso directo desde otra máquina nuestro contenedor deberemos utlizar un túnel ssh de la forma siguiente.
Ir a:

nano /etc/ssh/sshd_config

Cambiar la opción poniéndola a yes:

PermitRootLogin yes

# service ssh restart

Así ja podréis acceder desde otra máquina a vuestro contenedor. Recordar que por defecto se utiliza el puerto 22, si queréis lo podéis cambiar una opción frecuente es utilizar el puerto 2022.

Esto lo podéis hacer en el fichero del contenedor:

nano /etc/ssh/ssh_config

Para acceder al contenedor des de otra máquina utilizar la orden siguiente:

# ssh root@192.168.0.xxx -p 2022

Para cambiar el pasword de root  del contenedor desde la máquina base, utilizar la siguiente orden:

# rm -r /var/lib/lxc/nomb_maquina/ rootfs passwd