Escenario 2B. LXC: perfís, redes e control de recursos
Sumario
Introdución
Montaremos a infraestrutura da figura con contedores e ó longo do proceso aprenderemos a:
- Crear e asignar perfís (profiles) ós contedores para aplicar configuracións 'hardware' específicas ós nosos contedores.
- Coñecer o funcionamento da interface incusbr0 creada na inicialización.
- Crear e configurar redes para situar os contedores nelas. Coñeceremos outros modos de rede e como facer accesibles os servizos correndo nos contedores dende fóra do anfitrión.
- Establecer límites de cpu, RAM e disco ós contedores para controlar o uso dos recursos do equipo anfitrión.
Esquema de rede do escenario 2B:
Preparación da máquina Incus:
Para abordar este escenario usaremos a máquina Incus ó remate do Escenario 2A - Contedores LXC. No meu caso tiña uns contedores Ubuntu xa creados, pero non hai problema con que sexa diferente xa que crearemos todo o que precisamos para implantar esta infraestrutura.
Perfíl por defecto
Os profiles ou perfís permiten de xeito 'centralizado' definir a configuración e os dispositivos dun contedor para así poder aplicalo a todos os contedores que o precisen. Por exemplo, podemos crear un perfil onde está imposto un uso máximo de 256 MB de memoria e 1 cpu. Este perfil podemos aplicalo a todos aqueles contedores ós que queiramos aplicar esta restricción. Do mesmo xeito, podemos ter un perfil onde indicamos que haberá dúas interfaces de rede (p.e. unha con conexión á rede local e outra conectada a unha rede interna/ privada) e aplicalo a todos aqueles contedores que o precisen. Podemos crear varios perfís e aplicarllos a un contedor; deste xeito, cando se cree a configuración final do contedor os perfís aplicaranse na orde na que foron indicados (sobreescribindo a configuración anterior no caso de haber coincidencias).
Podemos ver os perfís dispoñibles executando o comando incus profile list e tamén modificar o comando incus list para ver directamente que perfís están a usar os contedores (executar incus list -h para ver todas as posibilidades):
~$ incus profile list +---------+-----------------------+---------+ | NAME | DESCRIPCIÓN | USED BY | +---------+-----------------------+---------+ | default | Default Incus profile | 0 | +---------+-----------------------+---------+
Para ver as características do perfil e os contedores que o utilizan executamos o comando lxc profile show <nome_perfil>:
~$ incus profile show default
config: {}
description: Default Incus profile
devices:
eth0:
name: eth0
network: incusbr0
type: nic
root:
path: /
pool: default
type: disk
name: default
used_by: []
project: default
Ó instalar incus créase un perfil chamado default que correspóndese cun contedor cun disco duro e unha interface de rede conectada ó dispositivo incusbr0.
Ó longo deste escenario traballaremos cos perfís, creando, editando as súas características, asignando, etc.; pero de momento, se queremos ver todas as operacións posibles sobe os perfís podemos executar:
~$ incus profile
Usage:
incus profile [flags]
incus profile [command]
Available Commands:
add Add profiles to instances
assign Assign sets of profiles to instances
copy Copy profiles
create Create profiles
delete Delete profiles
device Manage devices
edit Edit profile configurations as YAML
get Get values for profile configuration keys
list List profiles
remove Remove profiles from instances
rename Rename profiles
set Set profile configuration keys
show Show profile configurations
unset Unset profile configuration keys
Global Flags:
--debug Show all debug messages
--force-local Force using the local unix socket
-h, --help Print help
--project Override the source project
-q, --quiet Don't show progress information
--sub-commands Use with help or --help to view sub-commands
-v, --verbose Show all information messages
--version Print version number
Use "incus profile [command] --help" for more information about a command.
Interfaz incusbr0
Ó traballar con contedores LXC/Incus podemos crear configuracións de rede semellantes ás que ofrecen solucións de virtualización como Virtualbox. A xestión das redes pode facerse a través da configuración de rede do sistema operativo ou ben directamente a través de Incus. Ó longo do curso ensinarei a facelo das dúas formas, para que escollades a que mellor se adapta á vosa forma de traballar co alumnado.
No momento de facer o incus init creamos unha nova interface de rede incusbr0 que proporciona funcionalidades semellantes ás que ofrece o modo rede NAT en Virtualbox xa que:
Os contedores reciben por dhcp unha configuración válida para unha rede privada 10.103.214.0/24 (esta é a rede creada no meu equipo e seguramente sexa diferente no voso). Os contedores conectados a ela poden comunicarse entre si. É dicir, funciona como se fose un conmutador/switch para eles. Os contedores conectados a ela poden saír ó exterior. É dicir, funciona como se fose un router-nat, traducindo os enderezos IP privados pola IP real do equipo anfitrión. Automáticamente creáronse regras de filtrado e NAT no equipo anfitrión durante a inicialización de incus. O equipo anfitrión pode comunicarse cos contedores a través dos enderezos da rede interna (no meu exemplo, a rede 10.103.214.0/24) e viceversa. No meu caso o equipo anfitrión recibiu a IP 10.103.214.1 e a través desta IP pode falar directamente cos contedores conectados á rede incusbr0 10.103.214.1/24. Dende fóra do equipo anfitrión non se poden iniciar comunicacións directas hacia os servizos correndo nos contedores; polo tanto, habería que crear regras de filtrado e NAT para permitilo ou crear a través de incus un dispositivo tipo proxy asociado ó contedor. No meu equipo de probas hai dous contedores usando o perfil por defecto que emprega incusbr0 como tarxeta de rede:
asir@incus:~$ incus list -c n,4,s,P,S,l +-----------+----------------------+---------+----------+-----------+----------------------+ | NAME | IPV4 | STATE | PROFILES | SNAPSHOTS | LAST USED AT | +-----------+----------------------+---------+----------+-----------+----------------------+ | platega00 | 10.103.214.4 (eth0) | RUNNING | default | 0 | 2026/01/17 13:08 CET | +-----------+----------------------+---------+----------+-----------+----------------------+ | platega01 | 10.103.214.70 (eth0) | RUNNING | default | 0 | 2026/01/17 13:08 CET | +-----------+----------------------+---------+----------+-----------+----------------------+ asir@incus:~$ incus profile show default config: {} description: Default Incus profile devices:
eth0: name: eth0 network: incusbr0 type: nic root: path: / pool: default type: disk
name: default used_by: - /1.0/instances/platega00 - /1.0/instances/platega01 project: default asir@incus:~$ ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> 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 noprefixroute
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:ea:0d:42 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.40/24 brd 192.168.1.255 scope global dynamic noprefixroute enp0s3
valid_lft 29661sec preferred_lft 29661sec
inet6 fe80::e492:220c:7e0f:c8b8/64 scope link noprefixroute
valid_lft forever preferred_lft forever
3: incusbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
link/ether 10:66:6a:73:84:27 brd ff:ff:ff:ff:ff:ff
inet 10.103.214.1/24 brd 10.103.214.255 scope global incusbr0
valid_lft forever preferred_lft forever
inet6 fd42:5fbb:5bb1:46a5::1/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::1266:6aff:fe73:8427/64 scope link
valid_lft forever preferred_lft forever
... Gráficamente a rede incusbr0 podería entenderse como:
Interfaz lxdbr0
Fig. Rede en Incus - interfaz incusbr0
Acceso a un servizo correndo nun contedor mediante netfilter/iptables
Os servizos correndo nun contedor son directamente accesibles dende o equipo anfitrión grazas ó dispositivo incusbr0; sen embargo, se desexamos facer accesible algún servizo dos contedores dende o exterior hai que facer DNAT. Por exemplo, os contenedores ó crealos xa veñen co servidor openssh-server instalado e para permitir o acceso por ssh ó contenedor platega00 que ten a IP 10.122.236.9 a través da IP do 'equipo real' polo porto tcp/22000:
~$ sudo iptables -t nat -A PREROUTING -p tcp -i enp0s3 --dport 22000 -j DNAT --to 10.103.214.4:22
Accedendo dende un equipo externo á IP do equipo anfitrión porto 22000/tcp poderíamos abrir unha sesión ssh en platega00 (previamente habería que poñer un contrasinal ó usuario ubuntu e habilitar o acceso por ssh mediante contrasinal como se indicou no apartado 2.4 do tema):
$ ssh ubuntu@192.168.1.150 -p 22000 The authenticity of host '[192.168.1.150]:22000 ([192.168.1.150]:22000)' can't be established. ... Welcome to Ubuntu 22.04.5 LTS (GNU/Linux 6.14.0-37-generic x86_64) ...
Acceso a un servizo correndo nun contedor mediante un dispositivo proxy
Pódese asociar a un contedor un dispositivo de tipo proxy que faga o traballo das regras NAT vistas no punto anterior. A modo de exemplo, faremos que un servidor web correndo en platega00 sexa accesible dende calquera ordenador a través da IP do equipo real:
En platega00 instalamos o servidor Apache:
~$ incus exec platega00 bash ~# apt update ~# apt install apache2 net-tools ~# netstat -putan Active Internet connections (servers and established) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN 190/systemd-resolve tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 235/sshd tcp6 0 0 :::80 :::* LISTEN 1742/apache2 ...
No equipo real creamos un dispositivo de tipo proxy que mapeamos ó porto 80 do contedor:
~$ incus config device add platega00 apache proxy listen=tcp:0.0.0.0:80 connect=tcp:127.0.0.1:80
Device apache added to platega00
asir@incus:~$ incus config show platega00
architecture: x86_64
config:
image.architecture: amd64
image.description: Ubuntu jammy amd64 (20260116_07:42)
image.os: Ubuntu
image.release: jammy
image.serial: "20260116_07:42"
image.type: squashfs
image.variant: default
volatile.base_image: fc7f50dfa54d2b78a38ecf381aae912cbac338be01ff08c3c1c61cc74c502aad
volatile.cloud-init.instance-id: 240792e5-4b41-4f9d-8dcc-9f5de51fba06
volatile.eth0.host_name: veth7dfe3eb5
volatile.eth0.hwaddr: 10:66:6a:a2:d9:0b
volatile.idmap.base: "0"
volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":1000000,"Nsid":0,"Maprange":1000000000},{"Isuid":false,"Isgid":true,"Hostid":1000000,"Nsid":0,"Maprange":1000000000}]'
volatile.last_state.idmap: '[]'
volatile.last_state.power: RUNNING
volatile.uuid: 5254a789-4f45-4411-873c-f8b0a524b1db
volatile.uuid.generation: 5254a789-4f45-4411-873c-f8b0a524b1db
devices:
apache:
connect: tcp:127.0.0.1:80
listen: tcp:0.0.0.0:80
type: proxy
ephemeral: false
profiles:
- default
stateful: false
description: ""
Atacando a IP do equipo real porto tcp/80 poderemos acceder ó servidor Apache correndo no contedor:
Accedendo ó servidor Apache a través do dispositivo proxy
Fig. Accedendo ó servidor apache grazas o dispositivo proxy
A rede incusbr0 e o seu modo de funcionamento; aínda que é práctico, noutras ocasións non é o que precisamos. Non hai problema xa que LXC/Incus soportan diversos modos de funcionamento de rede, semellantes o modo ponte e rede interna de Virtualbox .