Recursos básicos do LXD - sistemas de contêineres Linux
LXD é o gerenciador de contêineres do sistema da próxima geração, é o que diz fonte. Ele oferece uma interface de usuário semelhante às máquinas virtuais, mas em vez disso usa contêineres Linux.
Núcleo LXD é um daemon privilegiado (um serviço executado com direitos de root) que fornece uma API REST através de um soquete unix local, bem como através da rede se a configuração apropriada estiver instalada. Os clientes, como a ferramenta de linha de comando fornecida com o LXD, fazem solicitações por meio desta API REST. Isso significa que, quer você esteja acessando um host local ou remoto, tudo funciona da mesma forma.
Neste artigo não nos deteremos detalhadamente nos conceitos do LXD, não consideraremos todos os recursos disponíveis descritos na documentação, incluindo a recente implementação nas versões mais recentes do LXD de suporte para máquinas virtuais QEMU em paralelo com contêineres. Em vez disso, aprenderemos apenas o básico do gerenciamento de contêineres – configurar pools de armazenamento, rede, executar um contêiner, aplicar limites de recursos e como usar instantâneos para que você possa obter uma compreensão básica do LXD e usar contêineres no Linux.
Para informações completas, consulte a fonte oficial:
Isso significa que dois pacotes serão instalados ao mesmo tempo, um como pacote de sistema e outro como pacote snap. A instalação de dois pacotes em um sistema pode criar alguns problemas em que o pacote do sistema pode ficar órfão se o pacote snap for removido pelo gerenciador de pacotes snap.
Encontrar pacote lxd no repositório snap você pode usar o seguinte comando:
snap find lxd
Name Version Summary
lxd 3.21 System container manager and API
lxd-demo-server 0+git.6d54658 Online software demo sessions using LXD
nova ocata OpenStack Compute Service (nova)
nova-hypervisor ocata OpenStack Compute Service - KVM Hypervisor (nova)
distrobuilder 1.0 Image builder for LXC and LXD
fabrica 0.1 Build snaps by simply pointing a web form to...
satellite 0.1.2 Advanced scalable Open source intelligence platform
Executando o comando list você pode ter certeza de que o pacote lxd ainda não instalado:
snap list
Name Version Rev Tracking Publisher Notes
core 16-2.43.3 8689 stable canonical✓ core
Apesar do LXD ser um pacote instantâneo, ele deve ser instalado através do pacote do sistema lxd, que criará o grupo correspondente no sistema, os utilitários necessários em /usr/bin и т.д.
sudo apt update
sudo apt install lxd
Vamos ter certeza de que o pacote está instalado como um pacote snap:
snap list
Name Version Rev Tracking Publisher Notes
core 16-2.43.3 8689 stable canonical✓ core
lxd 3.21 13474 stable/… canonical✓ -
Para instalar o pacote LXD no sistema, é necessário executar os seguintes comandos, o primeiro irá atualizar a lista de pacotes do sistema disponíveis no repositório, o segundo irá instalar diretamente o pacote:
sudo pacman -Syyu && sudo pacman -S lxd
Depois de instalar o pacote, para gerenciar o LXD por um usuário regular, ele deve ser adicionado ao grupo de sistemas lxd:
sudo usermod -a -G lxd user1
Vamos garantir que o usuário user1 adicionado ao grupo lxd:
id -Gn user1
user1 adm dialout cdrom floppy sudo audio dip video plugdev netdev lxd
Se o grupo lxd não estiver visível na lista, será necessário ativar a sessão do usuário novamente. Para fazer isso, você precisa sair e fazer login com o mesmo usuário.
Ativar em systemd carregando o serviço LXD na inicialização do sistema:
Antes de iniciar a inicialização, precisamos entender como o armazenamento no LXD é organizado logicamente.
Armazenar (Armazenamento) consiste em de um ou mais Pool de armazenamento que usa um dos sistemas de arquivos suportados, como ZFS, BTRFS, LVM ou diretórios regulares. Todo Pool de armazenamento é dividido em volumes (Volume de Armazenamento) que contenham imagens, contêineres ou dados para outros fins.
Imagens - estas são distribuições especialmente montadas sem o kernel Linux e disponíveis em fontes externas
Containers - são distribuições implantadas a partir de imagens, prontas para uso
Instantâneos - estes são instantâneos do estado dos contêineres aos quais você pode retornar
Para gerenciar o armazenamento no LXD, use o comando lxc storage um certificado que pode ser obtido especificando a chave - lxc storage --help
O comando a seguir exibe uma lista de todos Pool de armazenamento no armazenamento 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 uma lista de todos Volume de Armazenamento no selecionado Pool de armazenamento atende a equipe 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 |
+-----------+----------------------------------+-------------+---------+
Além disso, se por Pool de armazenamento Ao criar, o sistema de arquivos BTRFS foi selecionado e, em seguida, obtenha uma lista Volume de Armazenamento ou subvolumes na interpretação do BTRFS, você pode usar o kit de ferramentas deste sistema de arquivos:
sudo btrfs subvolume list -p /var/lib/lxd/storage-pools/hddpool
ID 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/alp3
Antes de criar e usar contêineres, você deve realizar uma inicialização geral do LXD que cria e configura a rede e o armazenamento. Isso pode ser feito manualmente usando comandos de cliente padrão que estão disponíveis na lista chamando o comando lxc --help ou usando o assistente de inicialização lxd init respondendo algumas perguntas.
Selecionando um sistema de arquivos para pool de armazenamento ^
Durante a inicialização, o LXD faz várias perguntas, incluindo a determinação do tipo de sistema de arquivos padrão Pool de armazenamento. Por padrão, o sistema de arquivos BTRFS é selecionado para ele. Será impossível mudar para outro FS após a criação. Para selecionar um FS sugere-se tabela de comparação de recursos:
Característica
Diretório
Btrfs
LVM
ZFS
CEPH
Armazenamento de imagens otimizado
não
sim
sim
sim
sim
Criação de instância otimizada
não
sim
sim
sim
sim
Criação otimizada de snapshots
não
sim
sim
sim
sim
Transferência de imagem otimizada
não
sim
não
sim
sim
Transferência de instância otimizada
não
sim
não
sim
sim
Cópia na gravação
não
sim
sim
sim
sim
Baseado em bloco
não
não
sim
não
sim
Clonagem instantânea
não
sim
sim
sim
sim
Driver de armazenamento utilizável dentro de um contêiner
sim
sim
não
não
não
Restaurar de snapshots mais antigos (não os mais recentes)
sim
sim
sim
não
sim
Cotas de armazenamento
sim(*)
sim
sim
sim
não
Inicializando a rede e o pool de armazenamento usando o assistente ^
O próximo comando que veremos sugere a configuração dos principais componentes do LXD respondendo a perguntas simples usando o assistente de inicialização.
Comando de execução lxc init e insira as respostas às perguntas após os dois pontos conforme mostrado no exemplo abaixo ou altere-as de acordo com suas condições:
lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
Do you want to configure a new storage pool? (yes/no) [default=yes]:
Name of the new storage pool [default=default]: ssdpool
Name of the storage backend to use (lvm, btrfs, dir) [default=btrfs]:
Create a new BTRFS pool? (yes/no) [default=yes]:
Would you like to use an existing block device? (yes/no) [default=no]:
Size in GB of the new loop device (1GB minimum) [default=15GB]: 10GB
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]:
What should the new bridge be called? [default=lxdbr0]:
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 10.0.5.1/24
Would you like LXD to NAT IPv4 traffic on your bridge? [default=yes]:
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none
Would you like LXD to be available over the network? (yes/no) [default=no]:
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] no
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]:
Na etapa anterior criamos Pool de armazenamento que recebeu o nome ssdpool e cujo arquivo está localizado no meu sistema em /var/lib/lxd/disks/ssdpool.img. Este endereço do sistema de arquivos corresponde à unidade SSD física do meu PC.
As ações a seguir, para ampliar a compreensão do papel desempenhado pela Pool de armazenamento no repositório, criaremos um segundo Pool de armazenamento que estará fisicamente localizado em um tipo diferente de disco, HDD. O problema é que o LXD não permite criar Pool de armazenamento fora de endereço /var/lib/lxd/disks/ e mesmo links simbólicos não funcionarão, veja a resposta do desenvolvedor. Podemos contornar esta limitação durante a inicialização/formatação Pool de armazenamento especificando o valor como um dispositivo de bloco em vez do caminho para o arquivo de loopback, especificando isso na chave source.
Então, antes de criar Pool de armazenamento você precisa definir um arquivo de loopback ou uma partição existente em seu sistema de arquivos que ele usará. Para fazer isso, criaremos e usaremos um arquivo cujo tamanho limitaremos a 10 GB:
dd if=/dev/zero of=/mnt/work/lxd/hddpool.img bs=1MB count=10000
10000+0 records in
10000+0 records out
10000000000 bytes (10 GB, 9,3 GiB) copied, 38,4414 s, 260 MB/s
Vamos conectar o arquivo de loopback a um dispositivo de loopback gratuito:
Graças à chave --show a execução do comando retorna à tela o nome do dispositivo ao qual nosso arquivo de loopback está conectado. Se necessário, podemos exibir uma lista de todos os dispositivos ocupados deste tipo para ter certeza de que nossas ações estão corretas:
Na lista você pode descobrir que o dispositivo possui /dev/loop1 arquivo de loopback incluído /mnt/work/lxd/hddpool.img, e no dispositivo /dev/loop0 arquivo de loopback incluído /var/lib/lxd/disks/ssdpool.img que corresponde ao padrão Pool de armazenamento.
O comando a seguir cria um novo Pool de armazenamento no LXD com base no arquivo de loopback que acabamos de preparar. LXD irá formatar o arquivo de loopback /mnt/work/lxd/hddpool.img no dispositivo /dev/loop1 para o sistema de arquivos BTRFS:
Após a criação Pool de armazenamento, se necessário, pode ser expandido. Para Pool de armazenamento com base no sistema de arquivos BTRFS, execute os seguintes comandos:
Inserção automática de um arquivo de loopback em um slot de dispositivo de loopback ^
Temos um pequeno problema: ao reiniciar o sistema host, o arquivo /mnt/work/lxd/hddpool.img vai "voar" para fora do dispositivo /dev/loop1 e o serviço LXD irá travar ao carregar porque não o verá neste dispositivo. Para resolver este problema você precisa criar um serviço de sistema que irá inserir este arquivo no dispositivo /dev/loop1 quando o sistema host é inicializado.
vamos criar unidade tipo de arquivo serviço в /etc/systemd/system/ para o sistema de inicialização 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
EOF
Ative o serviço:
sudo systemctl enable lxd-hddpool
Created symlink /etc/systemd/system/local-fs.target.wants/lxd-hddpool.service → /etc/systemd/system/lxd-hddpool.service.
Após reiniciar o sistema host, verificamos o status do serviço:
systemctl status lxd-hddpool.service
● lxd-hddpool.service - Losetup LXD Storage Pool (hddpool)
Loaded: loaded (/etc/systemd/system/lxd-hddpool.service; enabled; vendor preset: disabled)
Active: active (exited) since Wed 2020-04-08 03:43:53 MSK; 1min 37s ago
Process: 711 ExecStart=/sbin/losetup /dev/loop1 /mnt/work/lxd/hddpool.img (code=exited, status=0/SUCCESS)
Main PID: 711 (code=exited, status=0/SUCCESS)
апр 08 03:43:52 manjaro systemd[1]: Starting Losetup LXD Storage Pool (hddpool)...
апр 08 03:43:53 manjaro systemd[1]: Finished Losetup LXD Storage Pool (hddpool).
A partir da saída podemos verificar que o estado do serviço é ativo, apesar de a execução do nosso script a partir de um comando ter sido concluída, a opção nos permitiu fazer isso RemainAfterExit=true.
Como todos os processos de contêiner são executados isoladamente no sistema host usando seu kernel, para proteger ainda mais o acesso dos processos de contêiner ao sistema host, o LXD oferece privilégios de processo, onde:
Contêineres Privilegiados - são contêineres nos quais os processos com UID e GID correspondem ao mesmo proprietário do sistema host. Por exemplo, um processo em execução em um contêiner com UID 0 tem todos os mesmos direitos de acesso que um processo no sistema host com UID 0. Em outras palavras, o usuário root no contêiner tem todos os direitos, não apenas em no contêiner, mas também no sistema host, se ele puder sair do namespace isolado do contêiner.
Contêineres sem privilégios - são contêineres nos quais os processos pertencem ao proprietário do UID e GID com um número de 0 a 65535, mas para o sistema host o proprietário é mascarado usando os bits SubUID e SubGID adicionados, respectivamente. Por exemplo, um usuário com UID=0 em um contêiner será visto no sistema host como SubUID + UID. Isso protege o sistema host porque se qualquer processo no contêiner for capaz de escapar de seu namespace isolado, ele só poderá se comunicar com o sistema host como um processo com um UID/GID desconhecido e muito alto.
Por padrão, os contêineres recém-criados têm um status sem privilégios e, portanto, devemos definir um SubUID e um SubGID.
Vamos criar dois arquivos de configuração nos quais definiremos a máscara para SubUID e SubGID, respectivamente:
Como inicializamos a rede anteriormente usando o assistente de inicialização lxd init e criou um dispositivo de rede lxdbr0, nesta seção iremos simplesmente nos familiarizar com redes no LXD e como criar um switch virtual (ponte) usando o comando do cliente.
O diagrama a seguir demonstra como um switch (ponte) conecta o host e os contêineres em uma rede:
Os contêineres podem se comunicar através de uma rede com outros contêineres ou com o host no qual esses contêineres são servidos. Para fazer isso, você precisa vincular as placas de rede virtuais dos contêineres a um switch virtual. Criaremos um switch primeiro, e as interfaces de rede do contêiner serão vinculadas nos capítulos subsequentes, após a criação do próprio contêiner.
O comando a seguir cria um switch com uma sub-rede 10.0.5.0/24 e endereço IPv4 10.0.5.1/24, e também inclui ipv4.nat para que os contêineres possam acessar a Internet através do host usando o serviço NAT:
Cada contêiner no LXD tem sua própria configuração e pode estendê-la com configurações declaradas globalmente chamadas perfis de configuração. A aplicação de perfis de configuração a um contêiner possui um modelo em cascata, o exemplo a seguir demonstra isso:
Neste exemplo, três perfis foram criados no sistema LXD: default, hddpool и hostfs. Todos os três perfis são aplicados a um contêiner que possui configuração local (área cinza). Perfil default tem um dispositivo root que tem um parâmetro pool é igual a ssdpool, mas graças ao modelo de aplicação de configuração em cascata, podemos aplicar um perfil ao contêiner hddpool que tem um parâmetro pool substituirá o mesmo parâmetro do perfil default e o contêiner receberá a configuração do dispositivo root com parâmetro pool igual hddpoole o perfil hostfs simplesmente adiciona um novo dispositivo ao contêiner.
Para ver a lista de perfis de configuração disponíveis, use o seguinte comando:
lxc profile list
+---------+---------+
| NAME | USED BY |
+---------+---------+
| default | 1 |
+---------+---------+
| hddroot | 0 |
+---------+---------+
| ssdroot | 1 |
+---------+---------+
Uma lista completa de comandos disponíveis para trabalhar com um perfil pode ser obtida adicionando a chave --help:
lxc profile --help
Description:
Manage profiles
Usage:
lxc 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 instance 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
Perfil de configuração padrão default não possui configuração de placa de rede para o container e todos os containers recém-criados não possuem rede, para eles é necessário criar dispositivos de rede locais (dedicados) com um comando separado, mas podemos criar um dispositivo de rede global na configuração perfil que será compartilhado entre todos os contêineres que usam esse perfil. Desta forma, imediatamente após o comando de criação de um novo container, eles terão uma rede com acesso à rede. Ao mesmo tempo, não há restrições; podemos sempre criar um dispositivo de rede local posteriormente, se necessário.
O comando a seguir adicionará o dispositivo ao perfil de configuração eth0 digite nic conectado à rede lxdbr0:
lxc profile device add default eth0 nic network=lxdbr0 name=eth0
É importante observar que, como adicionamos o dispositivo ao perfil de configuração, se especificarmos um endereço IP estático no dispositivo, todos os contêineres que usarão esse perfil compartilharão o mesmo endereço IP. Se houver necessidade de criar um contêiner com um endereço IP estático alocado para o contêiner, você deverá criar uma configuração de dispositivo de rede no nível do contêiner (configuração local) com o parâmetro de endereço IP, e não no nível do perfil.
Vamos verificar o perfil:
lxc profile show default
config: {}
description: Default LXD profile
devices:
eth0:
name: eth0
network: lxdbr0
type: nic
root:
path: /
pool: ssdpool
type: disk
name: default
used_by: []
Neste perfil podemos ver que para todos os containers recém-criados serão criados dois dispositivos:
eth0 - Tipo de dispositivo nic conectado a um switch (ponte de rede) lxdbr0
root - Tipo de dispositivo disk que usa um pool de armazenamento ssdpool
Para usar criado anteriormente Pool de armazenamento contêineres, crie um perfil de configuração ssdroot no qual adicionaremos um dispositivo como disk com ponto de montagem / (root) usando o criado anteriormente Pool de armazenamento - ssdpool:
Os contêineres são criados a partir de imagens que são distribuições especialmente montadas que não possuem um kernel Linux. Portanto, antes de executar o contêiner, ele deverá ser implantado a partir desta imagem. A fonte das imagens é um repositório local no qual as imagens são baixadas de repositórios externos.
Para exibir um número limitado de colunas usamos a opção -c com parâmetros dasute também limitou o comprimento da lista com o comando head.
A filtragem está disponível para exibir uma lista de imagens. O comando a seguir listará todas as arquiteturas de distribuição disponíveis Alpine Linux:
Para começar a usar o contêiner, você precisa adicionar uma imagem do repositório global ao local local:. Agora que o repositório local está vazio, o comando irá garantir isso lxc image list. Se o método list não especifique um repositório, então o repositório local será usado por padrão - local:
lxc image list local:
+-------+-------------+--------+-------------+--------------+------+------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCHITECTURE | TYPE | SIZE |
+-------+-------------+--------+-------------+--------------+------+------+
As imagens no repositório são gerenciadas usando os seguintes métodos:
Equipe
descrição
imagem lxc aliás
Gerenciar aliases de imagens
imagem lxc cópia
Copie imagens entre servidores
imagem lxc excluir
Apagar imagens
imagem lxc editar
Editar propriedades da imagem
imagem lxc exportar
Exportar e baixar imagens
imagem lxc importar
Importe imagens para o armazenamento de imagens
imagem lxc info
Mostrar informações úteis sobre imagens
imagem lxc Lista
Listar imagens
imagem lxc refrescar
Atualizar imagens
imagem lxc mostrar
Mostrar propriedades da imagem
Copie a imagem para o repositório local do global images::
Além do modo interativo, o LXD também suporta um modo de instalação de configuração não interativo, ou seja, quando a configuração é especificada na forma de um arquivo YAML, um formato especial que permite instalar toda a configuração de uma vez, ignorando a execução de muitos comandos interativos que foram discutidos acima neste artigo, incluindo configuração de rede, criação de perfis de configuração, etc. Não cobriremos esta área aqui, você pode conferir por conta própria. na documentação.
Próximo comando interativo lxc config que veremos permite que você defina a configuração. Por exemplo, para garantir que as imagens baixadas para o repositório local não sejam atualizadas automaticamente a partir dos repositórios globais, podemos ativar esse comportamento com o seguinte comando:
Para criar um contêiner use o comando lxc init para o qual os valores são passados репозиторий:образ e, em seguida, o ID desejado para o contêiner. O repositório pode ser especificado como local local: assim como qualquer global. Se o repositório não for especificado, por padrão o repositório local será usado para procurar a imagem. Se a imagem for especificada no repositório global, a imagem será primeiro baixada no repositório local e depois usada para criar o contêiner.
Vamos executar o seguinte comando para criar nosso primeiro contêiner:
lxc init alpine3 alp --storage=hddpool --profile=default --profile=hddroot
Vejamos as teclas de comando que usamos aqui em ordem:
alpine3 — Um alias (alias) é especificado para a imagem que foi carregada anteriormente no repositório local. Se o alias não foi criado para esta imagem, você sempre poderá referir-se à imagem pelo seu Impressão digital que é exibido na tabela.
alp — Define o identificador do contêiner
--storage — Esta chave indica em que Pool de armazenamento um contêiner será criado
--profile — Essas chaves aplicam em cascata a configuração de perfis de configuração criados anteriormente ao contêiner
Lançamos o contêiner, que começa a lançar o sistema init da distribuição:
lxc start alp
Você também pode usar o comando lxc launch que permite combinar equipes lxc init и lxc start em uma operação.
Verificando o estado do contêiner:
lxc list -c ns46tb
+------+---------+------------------+------+-----------+--------------+
| NAME | STATE | IPV4 | IPV6 | TYPE | STORAGE POOL |
+------+---------+------------------+------+-----------+--------------+
| alp | RUNNING | 10.0.5.46 (eth0) | | CONTAINER | hddpool |
+------+---------+------------------+------+-----------+--------------+
Na seção profiles podemos ter certeza de que este contêiner usa dois perfis de configuração - default и hddroot. Na seção devices só podemos detectar um dispositivo porque o dispositivo de rede foi criado no nível do perfil default. Para ver todos os dispositivos usados pelo contêiner você precisa adicionar uma chave --expanded:
Se tentarmos definir um endereço IP para um dispositivo de rede eth0 a equipe lxc config device set alp destinado à configuração do contêiner, receberemos um erro informando que o dispositivo não existe porque o dispositivo eth0 que é usado pelo contêiner pertence ao perfil default:
lxc config device set alp eth0 ipv4.address 10.0.5.5
Error: The device doesn't exist
É claro que podemos definir um endereço IP estático para eth0 dispositivos no perfil, mas será o mesmo para todos os contêineres que usarão esse perfil. Portanto, vamos adicionar um dispositivo dedicado ao container:
lxc config device add alp eth0 nic name=eth0 nictype=bridged parent=lxdbr0 ipv4.address=10.0.5.5
Então você precisa reiniciar o contêiner:
lxc restart alp
Se observarmos a configuração do contêiner agora, não precisamos usar a opção --expanded para ver o dispositivo de rede eth0, já que o criamos no nível do contêiner e ele foi colocado em cascata no mesmo dispositivo a partir do perfil default:
Para executar comandos diretamente em um contêiner, ignorando as conexões de rede, use o comando lxc exec que executa comandos no contêiner sem iniciar o shell do sistema. Se você precisar executar um comando em um shell usando padrões de shell, como variáveis, redirecionamentos de arquivos (pipe), etc., será necessário iniciar explicitamente o shell e passar o comando como uma chave, por exemplo:
lxc exec alp -- /bin/sh -c "echo $HOME"
O comando usou um caractere de escape especial para caractere especial $ para que a variável $HOME não foi interpretado na máquina host, mas foi interpretado apenas dentro do contêiner.
Também é possível iniciar o modo shell interativo e encerrar a sessão executando a tecla de atalho CTRL+D:
No LXD, você pode gerenciar recursos de contêiner usando um conjunto especial de configurações. Uma lista completa de parâmetros de configuração do contêiner pode ser encontrada na documentação.
limit.cpu - vincula um contêiner a um ou mais núcleos de CPU
limits.cpu.allowance - gerencia as cotas do agendador CFS quando o limite de tempo tiver passado ou o mecanismo universal de compartilhamento de recursos da CPU quando a porcentagem tiver passado
limits.cpu.priority - prioridade do escalonador quando múltiplas instâncias que compartilham um conjunto de processadores recebem a mesma porcentagem de processadores
Além de restrições como limits.read, limits.write também podemos limitar a quantidade de espaço em disco consumido pelo contêiner (funciona apenas com ZFS ou BTRFS):
lxc config device set alp root size=2GB
Após a instalação, no parâmetro devices.root.size Podemos verificar o limite definido:
lxc config show alp
...
devices:
root:
path: /
pool: hddpool
size: 2GB
type: disk
ephemeral: false
profiles:
- default
- hddroot
stateful: false
description: ""
Para visualizar as cotas de disco usadas, podemos obter no 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: 0
Apesar de termos definido um limite para o dispositivo raiz do contêiner em 2 GB, utilitários de sistema como df não verá esta restrição. Para isso, faremos um pequeno teste e descobriremos como funciona.
Vamos criar 2 novos containers idênticos no mesmo Pool de armazenamento (pool de disco rígido):
lxc exec alp1 -- ls -lh
total 1000M
-rw-r--r-- 1 root root 1000.0M Mar 27 10:16 file.img
Se olharmos no segundo container, verificarmos a existência de um arquivo no mesmo local, então esse arquivo não estará lá, o que é esperado, pois os containers são criados por conta própria Volume de Armazenamento no mesmo Pool de armazenamento:
lxc exec alp2 -- ls -lh
total 0
Mas vamos comparar os valores que ele produz df em um e outro contêiner:
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% /
...
O dispositivo /dev/loop1 montado como a partição raiz é Pool de armazenamento que estes contentores utilizam, pelo que partilham o seu volume entre dois.
O LXD tem a capacidade de criar instantâneos e restaurar o estado do contêiner a partir deles.
Para criar um instantâneo, execute o seguinte comando:
lxc snapshot alp snapshot1
O time lxc snapshot nenhuma chave disponível list, portanto, para visualizar a lista de snapshots você precisa usar o comando que exibe informações gerais sobre o container:
lxc info alp
...
...
Snapshots:
snapshot1 (taken at 2020/04/08 18:18 UTC) (stateless)
Você pode restaurar um contêiner a partir de um instantâneo usando o comando lxc restore especificando o contêiner para o qual a restauração será executada e o alias do snapshot:
lxc restore alp snapshot1
O comando a seguir é usado para excluir um instantâneo. Observe que a sintaxe do comando não é semelhante a todas as outras; aqui você precisa especificar uma barra após o nome do contêiner. Se a barra for omitida, o comando para excluir um instantâneo será interpretado como um comando para excluir um contêiner!
lxc delete alp/snapshot1
No exemplo acima, vimos os chamados snapshots sem estado. O LXD possui outro tipo de snapshots - stateful, que salva o estado atual de todos os processos no contêiner. Há vários recursos interessantes e úteis associados aos snapshots com estado.