Ubuntu LXD

O LXD cria "mini-servidores" Ubuntu dentro do seu Ubuntu: cada um tem usuários, apt, systemd e IP próprios, como uma máquina virtual, mas sobe em segundos e gasta pouca memória. É o lugar perfeito para testar uma instalação ou estudar administração sem medo de estragar o sistema.

Você vai aprender
  • A diferença entre container de sistema (LXD) e container de aplicação (Docker).
  • Instalar e configurar o LXD, entendendo cada resposta do lxd init.
  • Criar, entrar, listar, parar e apagar instâncias.
  • Tirar um snapshot antes de algo arriscado e voltar no tempo.
  • Limitar CPU e memória e copiar arquivos para dentro.

Exemplos na máquina fictícia notebook. IPs, versões e tempos variam: as saídas são ilustrativas.


Conceito: container de sistema

O Docker roda um programa por container. O LXD roda um sistema operacional inteiro, com o systemd como primeiro processo, igual a um servidor de verdade. Os dois usam o mesmo kernel do Ubuntu.

LXDDockerVM (KVM)
O que roda dentroUm sistema completoUm programaUm sistema completo, com kernel próprio
Dá para apt install e systemctl?Sim, como num servidorNão é o uso normalSim
Vida útilLonga (dias, meses)DescartávelLonga
Sobe em~2 segundos< 1 segundo~20 segundos
Melhor paraLaboratório, servidores levesEmpacotar e entregar appsOutro kernel ou Windows

O LXD também cria máquinas virtuais (--vm), com os mesmos comandos. Os nomes: LXD é o serviço; lxc é o comando que você digita. Existe também o Incus, um projeto derivado do LXD mantido pela comunidade, com comandos quase iguais.


Instalar e configurar

$ sudo snap install lxd
lxd (5.21/stable) 5.21.3-c5ae129 from Canonical✓ installed      « versão ilustrativa
$ sudo usermod -aG lxd $USER
$ newgrp lxd

Como no Docker, o grupo lxd dá controle total do LXD, o que equivale a poder de root. No Ubuntu Server, o LXD pode já estar disponível: o primeiro lxc oferece instalá-lo.

lxd init: as perguntas, uma a uma

Rode uma vez, antes de criar qualquer instância. Para um notebook de estudos, aceitar quase tudo com Enter funciona:

$ lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:                « vários servidores juntos: não
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]:
Name of the storage backend to use (btrfs, ceph, dir, lvm, powerflex, zfs) [default=zfs]: « zfs permite snapshots rápidos
Create a new ZFS pool? (yes/no) [default=yes]:
Would you like to use an existing empty block device (e.g. a disk or partition)? (yes/no) [default=no]:
Size in GiB of the new loop device (1GiB minimum) [default=30GiB]: 20GiB   « um arquivo de 20 GB fará o papel de disco
Would you like to connect to a MAAS server? (yes/no) [default=no]:
Would you like to create a new local network bridge? (yes/no) [default=yes]:  « rede interna para as instâncias
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]:
Would you like the LXD server to be available over the network? (yes/no) [default=no]:  « só local: mais seguro
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]:
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:

Com pressa? lxd init --minimal aceita todos os padrões sem perguntar (usa o armazenamento dir, mais simples e sem snapshots instantâneos).


Criar a primeira instância: lxc launch

lxc
O comando cliente do LXD.
launch
Baixa a imagem (se preciso), cria e inicia a instância.
ubuntu:26.04
remoto:imagem. O remoto ubuntu: tem as imagens oficiais.
lab
O nome da instância.
$ lxc launch ubuntu:26.04 lab
Creating lab
Starting lab
$ lxc list
+------+---------+----------------------+------------------------------------------------+-----------+-----------+
| NAME |  STATE  |         IPV4         |                      IPV6                      |   TYPE    | SNAPSHOTS |
+------+---------+----------------------+------------------------------------------------+-----------+-----------+
| lab  | RUNNING | 10.48.112.37 (eth0)  | fd42:9c3e:51a0:7d1b:216:3eff:fe2c:91aa (eth0)  | CONTAINER | 0         |
+------+---------+----------------------+------------------------------------------------+-----------+-----------+

A instância ganhou o IP 10.48.112.37 na rede interna lxdbr0. Do seu Ubuntu você alcança esse IP direto: ping 10.48.112.37 funciona.

Entrar: lxc exec e lxc shell

lxc exec lab
Roda um comando dentro da instância lab.
--
Daqui para frente, tudo é do comando de dentro (não são opções do lxc).
bash
O comando: um shell, como root da instância.
$ lxc exec lab -- bash
#> cat /etc/os-release | head -1
PRETTY_NAME="Ubuntu 26.04.1 LTS"
#> apt update -q && apt install -y -q nginx > /dev/null
#> systemctl is-active nginx
active                                « systemd funciona: é um sistema completo
#> exit
$ curl -s 10.48.112.37 | grep -o "<title>.*</title>"
<title>Welcome to nginx!</title>     « o nginx da instância respondeu

Atalho: lxc shell lab faz o mesmo que lxc exec lab -- su -l, abrindo uma sessão de login do root.

Rodar um comando sem entrar

$ lxc exec lab -- df -h /
Sist. Arq.                   Tam. Usado Disp. Uso% Montado em
default/containers/lab        18G  1,2G   17G   7% /
$ lxc exec lab -- su - ubuntu -c "whoami"
ubuntu

Snapshots: voltar no tempo

Antes de algo arriscado (atualizar a versão, mexer no firewall), tire um snapshot, uma foto do estado atual. Se der errado, volte a ele em segundos.

$ lxc snapshot lab antes-teste
$ lxc exec lab -- rm -rf /etc/nginx                 « estragando de propósito
$ lxc exec lab -- systemctl restart nginx
Job for nginx.service failed because the control process exited with error code.
$ lxc restore lab antes-teste
$ lxc exec lab -- systemctl is-active nginx
active                                              « tudo de volta
$ lxc info lab | sed -n '/Snapshots:/,$p'
Snapshots:
+-------------+----------------------+------------+----------+
|    NAME     |       TAKEN AT       | EXPIRES AT | STATEFUL |
+-------------+----------------------+------------+----------+
| antes-teste | 2026/10/15 10:42 -03 |            | NO       |
+-------------+----------------------+------------+----------+
Laboratório perfeito

Os projetos Quebre e Conserte ficam muito mais tranquilos numa instância LXD com snapshot: estrague, aprenda e restaure.


Gerenciar instâncias

$ lxc stop lab
$ lxc start lab
$ lxc config set lab limits.cpu 2
$ lxc config set lab limits.memory 1GiB
$ lxc file push ~/site/index.html lab/var/www/html/index.html
$ lxc file pull lab/etc/hostname .
$ lxc copy lab lab2                               « clona a instância
$ lxc delete lab2 --force

Máquina virtual com os mesmos comandos

$ lxc launch ubuntu:26.04 vm1 --vm
$ lxc list -c ns4t
+------+---------+-----------------------+-----------------+
| NAME |  STATE  |         IPV4          |      TYPE       |
+------+---------+-----------------------+-----------------+
| lab  | RUNNING | 10.48.112.37 (eth0)   | CONTAINER       |
| vm1  | RUNNING | 10.48.112.140 (enp5s0)| VIRTUAL-MACHINE |
+------+---------+-----------------------+-----------------+

Formas de ter um "servidor de teste"

FormaComandoMelhor quando…
LXD containerlxc launch ubuntu:26.04 labLeve e rápido; vários ao mesmo tempo.
LXD VMlxc launch ubuntu:26.04 vm1 --vmPrecisa de kernel próprio (módulos, Docker dentro).
Multipassmultipass launch 26.04Uma VM Ubuntu com zero configuração (veja KVM).
Dockerdocker run -it ubuntu:26.04Testar um comando rápido e jogar fora.
virt-managerinterface gráficaInstalar outro sistema a partir de uma ISO.

Quando não funciona

"Error: The LXD daemon doesn't appear to be started"

O que aconteceu: o serviço do snap não está rodando. Como resolver: sudo snap start lxd; veja o motivo em sudo snap logs lxd.

Permissão negada ao usar o lxc

O que aconteceu: seu usuário ainda não está no grupo lxd nesta sessão. Como confirmar: groups. Como resolver: sudo usermod -aG lxd $USER e abra uma sessão nova (ou newgrp lxd).

A instância não tem IPv4 (coluna vazia)

O que aconteceu: quase sempre é o firewall do Ubuntu bloqueando o DHCP da ponte lxdbr0, ou o Docker instalado na mesma máquina, que muda regras de rede.

Como resolver (ufw):

$ sudo ufw allow in on lxdbr0
$ sudo ufw route allow in on lxdbr0
$ sudo ufw route allow out on lxdbr0
$ lxc restart lab
"Error: Instance is running"

Você tentou apagar uma instância ligada. Pare antes (lxc stop lab) ou use lxc delete lab --force.


Referência

ComandoO que faz
lxd initConfiguração inicial (uma vez)
lxc launch IMAGEM NOME [--vm]Cria e inicia
lxc listLista instâncias
lxc exec NOME -- CMDRoda comando dentro
lxc shell NOMEAbre sessão de root
lxc start / stop / restart NOMELiga, desliga, reinicia
lxc delete NOME [--force]Apaga
lxc snapshot NOME SNAPTira snapshot
lxc restore NOME SNAPVolta ao snapshot
lxc info NOMEDetalhes, uso de recursos e snapshots
lxc config set NOME limits.memory 1GiBLimita recursos
lxc file push/pullCopia arquivos para dentro/fora
lxc image list ubuntu:Imagens disponíveis no remoto

Exercícios

1. Criar

Complete para criar uma instância chamada teste com Ubuntu 26.04:

lxc ubuntu:26.04 teste

2. Rodar um comando dentro

lxc exec teste apt update

3. Snapshot

Complete para voltar a instância teste ao snapshot limpo:

lxc teste limpo

4. Qual a principal diferença entre um container LXD e um container Docker?


Resumo

  • LXD = mini-servidores completos que sobem em segundos; lxc é o comando.
  • snap install lxd, grupo lxd e lxd init uma vez.
  • lxc launch ubuntu:26.04 nome cria; lxc exec nome -- bash entra; lxc list mostra.
  • Snapshot antes de qualquer teste arriscado; lxc restore volta no tempo.
  • --vm cria máquina virtual com os mesmos comandos.