INFORMATIZAR
LAB Profissional TI
Logo

Obter uma visão culturalmente diversificada para o futuro em busca de novos conhecimentos com ideias, objetivos e sonhos.
Impulsionando o desenvolvimento dos sistemas conectados e inteligentes; valorizar independência, objetividade e inovação.


Contêineres LXC no Debian

Virtualização leve e eficiente para ambientes Linux

1. Introdução ao LXC

Linux Containers (LXC) representam uma tecnologia de virtualização leve que permite a execução de múltiplos sistemas Linux isolados (contêineres) em um único host. Diferente das máquinas virtuais tradicionais, que emulam hardware completo e executam um kernel separado para cada VM, os contêineres LXC compartilham o kernel do sistema operacional host. Essa abordagem resulta em menor sobrecarga, inicialização mais rápida e uso mais eficiente dos recursos do sistema.

Documents LXC

O que é LXC?

LXC é uma implementação de virtualização no nível do sistema operacional que utiliza recursos do kernel Linux, como cgroups (grupos de controle) e namespaces. Cgroups permitem o gerenciamento e alocação de recursos (CPU, memória, E/S de disco, rede) para grupos de processos, enquanto namespaces fornecem isolamento para processos, rede, IDs de usuário e montagens de sistema de arquivos. Juntos, esses recursos criam um ambiente isolado que se comporta como um sistema operacional independente, mas sem a necessidade de um kernel separado ou emulação de hardware.

Por que usar LXC?

A utilização de contêineres LXC oferece diversas vantagens:

  • Eficiência de Recursos: Por compartilharem o kernel do host, os contêineres LXC consomem significativamente menos recursos (CPU, RAM, disco) do que as máquinas virtuais. Isso permite executar mais instâncias em um único servidor físico.
  • Inicialização Rápida: A ausência de um kernel separado e a emulação de hardware resultam em tempos de inicialização quase instantâneos para os contêineres, em comparação com os minutos que uma VM pode levar.
  • Isolamento Leve: Embora não ofereçam o mesmo nível de isolamento de segurança que as VMs baseadas em hypervisor, os contêineres LXC proporcionam um isolamento robusto para a maioria dos casos de uso, separando aplicações e serviços em ambientes distintos.
  • Flexibilidade: LXC é altamente flexível e pode ser usado para uma variedade de propósitos, como ambientes de desenvolvimento isolados, hospedagem de aplicações web, testes de software e particionamento de serviços.
  • Compatibilidade: Contêineres LXC são compatíveis com a maioria das ferramentas e fluxos de trabalho Linux existentes, tornando-se essa tecnologia relativamente simples para administradores de sistemas e desenvolvedores.

Este guia detalhará o processo de instalação e configuração de contêineres LXC em um sistema Debian, cobrindo tanto os contêineres privilegiados quanto os não privilegiados, e as configurações de rede essenciais.


2. Pré-requisitos

Antes de iniciar a implantação de contêineres LXC em seu sistema Debian, é fundamental garantir que os seguintes pré-requisitos sejam atendidos. Passos iniciais que asseguram um ambiente estável e funcional na instalação e operação do LXC.

Sistema Operacional Debian

Este guia é focado especificamente na distribuição Debian. Recomenda-se utilizar uma versão estável e atualizada do Debian para garantir a compatibilidade com os pacotes LXC e as funcionalidades do kernel. Embora os princípios gerais possam ser aplicáveis a outras distribuições Linux, as instruções e os nomes dos pacotes podem variar. Certifique-se de que seu sistema Debian esteja atualizado executando os seguintes comandos:

sudo apt update
sudo apt upgrade -y

Acesso Root ou Sudo

Para realizar a instalação e configuração do LXC, você precisará de privilégios de superusuário (root). Isso significa que você deve ter acesso à conta root ou conta de usuário configurada com permissões sudo. Recomendada-se usar sudo sempre que possível para evitar a execução desnecessária de comandos como root direto, o que pode reduzir riscos de segurança.

Verifique se sua conta de usuário tem permissões sudo executando um comando simples, como:

sudo apt update

Se o comando for executado com sucesso, você tem as permissões necessárias. Caso contrário, você precisará configurar o sudo para seu usuário ou alternar para a conta root.

Com esses pré-requisitos estabelecidos, seu sistema estará pronto para a instalação dos pacotes LXC e a criação dos primeiros contêineres.


3. Instalação do LXC

A instalação do LXC no Debian é um processo relativamente simples, que envolve a instalação de alguns pacotes essenciais. Dependendo se você planeja usar contêineres privilegiados ou não privilegiados, os requisitos de pacotes podem variar ligeiramente.

Pacotes Necessários

Os pacotes fundamentais para a operação do LXC incluem:

  • lxc: O pacote principal que contém as ferramentas e bibliotecas para gerenciar contêineres LXC.
  • debootstrap: Uma ferramenta utilizada para criar um sistema Debian básico em um diretório, que será a base do sistema de arquivos do seu contêiner.
  • bridge-utils: Utilitários para configurar pontes de rede, essenciais para a conectividade de rede dos contêineres.

O pacote libvirt-bin é opcional e pode ser instalado se você planeja integrar o LXC com o libvirt, um toolkit de virtualização.

Instalação para Contêineres Privilegiados

Para a maioria dos casos de uso, especialmente para iniciantes, a instalação básica do LXC é suficiente para criar e gerenciar contêineres privilegiados. Contêineres privilegiados são mais fáceis de configurar inicialmente, mas oferecem um nível de isolamento de segurança menor, pois o processo root dentro do contêiner tem privilégios de root no host. Eles são adequados para cargas de trabalho confiáveis.

Para instalar os pacotes necessários, execute o seguinte comando:

sudo apt install lxc debootstrap bridge-utils -y

Se desejar, você pode instalar o libvirt-bin:

sudo apt install libvirt-bin -y

Instalação para Contêineres Não Privilegiados

Contêineres não privilegiados são a opção recomendada para a maioria dos ambientes de produção, pois oferecem um isolamento de segurança significativamente maior. Neles, o usuário root dentro do contêiner não tem privilégios de root no host, mitigando riscos de segurança. A configuração inicial é um pouco mais complexa, exigindo pacotes adicionais e configurações específicas.

Para instalar os pacotes necessários para contêineres não privilegiados, execute:

sudo apt install lxc libvirt0 libpam-cgfs bridge-utils uidmap -y

O pacote uidmap é crucial para o mapeamento de IDs de usuário e grupo, permitindo que usuários não root criem e gerenciem contêineres. O libpam-cgfs é necessário para a integração com cgroups, embora a necessidade possa variar dependendo da configuração do sistema host.

Com a instalação dos pacotes concluída, o próximo passo é configurar o ambiente para contêineres não privilegiados, se essa for a sua escolha, ou prosseguir diretamente para a criação de contêineres privilegiados.


4. Configuração para Contêineres Não Privilegiados
(Opcional, mas recomendado)

A criação de contêineres não privilegiados é altamente recomendada devido aos benefícios de segurança que oferecem. No entanto, eles exigem algumas configurações adicionais no sistema host Debian. Estas etapas garantem que o sistema esteja preparado para lidar com o isolamento de usuários e recursos de rede de forma segura.


Habilitar Namespaces de Usuário Não Privilegiados

Os kernels Debian a partir da versão 5.10+ geralmente vêm com namespaces de usuário não privilegiados habilitados por padrão. Esta funcionalidade é crucial para o funcionamento seguro de contêineres não privilegiados. Para verificar o status, execute o seguinte comando no seu terminal:

sysctl kernel.unprivileged_userns_clone

Se a saída for kernel.unprivileged_userns_clone = 1, significa que a funcionalidade está habilitada. Se a saída for 0, você precisará habilitá-la. Para fazer isso, adicione a linha kernel.unprivileged_userns_clone=1 ao arquivo /etc/sysctl.conf ou crie um novo arquivo como /etc/sysctl.d/unpriv-usernd.conf com este conteúdo. Em seguida, aplique as alterações com sysctl -p:

echo 'kernel.unprivileged_userns_clone=1' | sudo tee -a /etc/sysctl.conf
sudo sysctl -p

Configurar AppArmor

AppArmor é um módulo de segurança do kernel Linux que pode ser usado para restringir as capacidades dos programas. Para contêineres LXC não privilegiados, é importante configurar o perfil do AppArmor para permitir a operação adequada. Você pode definir o perfil no arquivo de configuração global do LXC (.config/lxc/default.conf) ou no arquivo de configuração de cada contêiner individualmente. As opções recomendadas são unconfined (menos restritivo) ou lxc-container-default-cgns (mais seguro).

Para configurar globalmente (afetará novos contêineres), edite ou crie o arquivo ~/.config/lxc/default.conf e adicione uma das seguintes linhas:

lxc.apparmor.profile = lxc-container-default-cgns
# OU
lxc.apparmor.profile = unconfined

É importante notar que pode haver bugs no parser do AppArmor que afetam o perfil lxc-container-default-cgns em algumas versões, potencialmente causando falhas em unidades systemd dentro do contêiner. Nesses casos, o perfil unconfined pode ser uma alternativa temporária, ou você pode consultar a documentação do Debian para soluções alternativas.


Configurar Rede para Usuários Não Root

Para que usuários não root possam criar e gerenciar interfaces de rede virtuais para seus contêineres não privilegiados, é necessário configurar o arquivo /etc/lxc/lxc-usernet. Este arquivo especifica quais usuários podem criar quais tipos de interfaces de rede e em quais pontes.

Adicione uma linha ao arquivo /etc/lxc/lxc-usernet no formato usuário tipo_interface ponte_rede número_máximo_interfaces. Por exemplo, para permitir que o usuário meuusuario crie até 10 interfaces veth na ponte lxcbr0:

echo 'meuusuario veth lxcbr0 10' | sudo tee -a /etc/lxc/lxc-usernet

Substitua meuusuario pelo nome de usuário real que irá gerenciar os contêineres. Esta configuração é essencial para que os contêineres não privilegiados tenham conectividade de rede adequada.

Com essas configurações aplicadas, seu sistema Debian estará totalmente preparado para a criação e operação de contêineres LXC não privilegiados, aproveitando ao máximo os benefícios de segurança e isolamento que eles oferecem.


5. Criação de Contêineres

Após a instalação e configuração inicial do LXC, o próximo passo é criar os contêineres. O LXC oferece a flexibilidade de criar contêineres privilegiados ou não privilegiados, cada um com suas próprias características e casos de uso. A escolha entre eles dependerá dos seus requisitos de segurança e facilidade de gerenciamento.

Contêineres Privilegiados vs. Não Privilegiados

É crucial entender a diferença entre esses dois tipos de contêineres:

  • Contêineres Privilegiados: São mais fáceis de configurar e iniciar, pois o processo root dentro do contêiner tem os mesmos privilégios que o root no sistema host. Isso significa que, se houver uma vulnerabilidade no contêiner, ela pode ser explorada para comprometer o host. Eles são adequados para ambientes onde você confia plenamente nas cargas de trabalho executadas no contêiner.
  • Contêineres Não Privilegiados: Oferecem um nível de segurança muito maior. O root dentro do contêiner é mapeado para um usuário não root no host, limitando significativamente o impacto de uma possível exploração. Embora a configuração inicial seja um pouco mais complexa (conforme detalhado na Seção 4), são a escolha preferencial para a maioria dos cenários, especialmente aqueles que envolvem cargas de trabalho não confiáveis ou ambientes de produção.

Criar um Contêiner Privilegiado

A criação de um contêiner privilegiado é direta e utiliza o comando lxc-create com o template debian. Este processo baixará e instalará um sistema Debian mínimo no diretório rootfs do seu contêiner (/var/lib/lxc/<nome_do_contêiner>/rootfs).


O comando básico para criar um contêiner privilegiado é:

sudo lxc-create -n <nome_do_contêiner> -t debian -- -r <versão_debian>

Onde:

  • -n <nome_do_contêiner>: Define o nome do seu contêiner (ex: meu-servidor-web).
  • -t debian: Especifica o template debian, que automatiza a instalação de um sistema Debian base.
  • -- -r <versão_debian>: Passa o parâmetro de release (versão do Debian) para o script do template. Por exemplo, bookworm para Debian 12, bullseye para Debian 11, etc.

Exemplo: Para criar um contêiner privilegiado chamado meu-contêiner-privilegiado com Debian 12 (Bookworm):

sudo lxc-create -n meu-contêiner-privilegiado -t debian -- -r bookworm

Você também pode especificar o idioma (locale) e o mirror para o debootstrap:

LANG=C SUITE=bookworm MIRROR=http://deb.debian.org/debian sudo lxc-create -n debian12-priv -t debian

Os scripts e templates do LXC são encontrados em /usr/share/lxc/templates/.


Criar um Contêiner Não Privilegiado

A criação de um contêiner não privilegiado também utiliza o comando lxc-create, mas com o template download. Este template baixa uma imagem pré-construída de um servidor público, o que é mais adequado para contêineres não privilegiados.

Importante: Antes de tentar criar um contêiner não privilegiado, certifique-se de ter seguido todas as etapas de configuração detalhadas na Seção 4 (Habilitar Namespaces de Usuário, Configurar AppArmor e Configurar Rede para Usuários Não Root). Essas configurações são pré-requisitos essenciais para o funcionamento correto e seguro de contêineres não privilegiados.

O comando para criar um contêiner não privilegiado é:

lxc-create <nome_do_contêiner> -t download -- -d debian -r <versão_debian> -a amd64

Note que, ao contrário dos contêineres privilegiados, este comando é executado como um usuário comum (não sudo), desde que as configurações de lxc-usernet tenham sido aplicadas corretamente.

Onde:

  • <nome_do_contêiner>: O nome desejado para o seu contêiner.
  • -t download: Especifica o template download.
  • -- -d debian: Define a distribuição como Debian.
  • -r <versão_debian>: Especifica a versão do Debian (ex: bookworm).
  • -a amd64: Define a arquitetura como amd64.

Exemplo: Para criar um contêiner não privilegiado chamado meu-contêiner-nao-privilegiado com Debian 12 (Bookworm):

lxc-create meu-contêiner-nao-privilegiado -t download -- -d debian -r bookworm -a amd64

Após a execução bem-sucedida de um desses comandos, seu contêiner estará criado e pronto para ser iniciado e configurado. O próximo passo é garantir que ele tenha a conectividade de rede adequada.


6. Configuração de Rede

A conectividade de rede é um aspecto fundamental para qualquer contêiner, permitindo que ele se comunique com o host, outros contêineres e a internet. O Debian, por padrão, não configura uma rede para contêineres LXC automaticamente, o que exige uma configuração manual. Existem várias abordagens para configurar a rede, dependendo da complexidade e dos requisitos de isolamento.

Visão Geral das Opções de Rede

As principais formas de configurar a rede para contêineres LXC incluem:

  • lxc-net (Ponte Padrão): Esta é a maneira mais fácil e geralmente recomendada para a maioria dos usuários. O lxc-net configura automaticamente uma ponte de rede (geralmente lxcbr0), um servidor DHCP e NAT para que os contêineres possam obter endereços IP e acessar a internet através do host. É habilitado por padrão para contêineres iniciados como root.
  • Configuração de Bridge Compartilhada pelo Host: Permite que os contêineres se conectem diretamente à rede física do host através de uma ponte, recebendo endereços IP da mesma sub-rede do host. Isso oferece maior transparência na rede, mas pode exigir mais configuração manual.
  • Configuração de Bridge Independente: Cria uma ponte de rede separada para os contêineres, isolando-os da rede principal do host. Isso é útil para cenários onde se deseja um isolamento de rede mais rigoroso ou para criar sub-redes dedicadas aos contêineres.

Configuração de Bridge Padrão com lxc-net

Para a maioria dos casos, utilizar o lxc-net é a solução mais simples. Ele cria uma ponte de rede (lxcbr0) e configura um servidor DHCP e NAT. Para verificar se o lxc-net está configurado e funcionando, você pode inspecionar o arquivo /etc/default/lxc-net.

Se você instalou o LXC, o lxc-net deve estar ativo. Para contêineres privilegiados, ele funcionará automaticamente. Para contêineres não privilegiados, certifique-se de que a configuração em /etc/lxc/lxc-usernet (mencionada na Seção 4) esteja correta para permitir que seu usuário crie interfaces veth na ponte lxcbr0.

Você pode iniciar ou reiniciar o serviço lxc-net se necessário:

sudo systemctl start lxc-net
sudo systemctl enable lxc-net

Configuração de Bridge Compartilhada pelo Host (Manual)

Se você precisa que seus contêineres estejam na mesma sub-rede que o host e sejam acessíveis diretamente da rede externa, você pode configurar uma ponte de rede manual. Este método envolve a criação de uma interface de ponte e a adição da interface de rede física do host a ela.

Exemplo de configuração (requer ajuste para sua rede):

1. Edite o arquivo /etc/network/interfaces (ou /etc/netplan/ se estiver usando Netplan) para configurar a ponte. Substitua eth0 pela sua interface de rede física e ajuste os endereços IP conforme sua rede.

# /etc/network/interfaces

# A interface de rede física não terá mais um IP
auto eth0
iface eth0 inet manual

# Configura a ponte
auto br0
iface br0 inet static
    address 192.168.1.100
    netmask 255.255.255.0
    gateway 192.168.1.1
    bridge_ports eth0
    bridge_fd 0
    bridge_maxwait 0

2. Reinicie o serviço de rede para aplicar as alterações (isso pode causar uma breve interrupção na rede):

sudo systemctl restart networking

3. Configure o contêiner para usar a ponte br0. No arquivo de configuração do contêiner (/var/lib/lxc/<nome_do_contêiner>/config), adicione ou modifique as seguintes linhas:

lxc.net.0.type = veth
lxc.net.0.link = br0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx # Opcional: defina um MAC address

Dentro do contêiner, você precisará configurar a interface de rede para obter um IP via DHCP ou estaticamente, assim como faria em uma máquina virtual normal.


Configuração de Bridge Independente

Para um isolamento de rede mais robusto, você pode criar uma ponte de rede que não esteja diretamente ligada a uma interface física. Esta ponte terá sua própria sub-rede e um servidor DHCP pode ser configurado para atribuir IPs aos contêineres.

1. Crie a ponte virtual:

sudo brctl addbr lxc-private-br
sudo ip link set lxc-private-br up
sudo ip addr add 10.0.0.1/24 dev lxc-private-br

2. Instale e configure um servidor DHCP/NAT (como dnsmasq) para a ponte lxc-private-br.

3. Configure o contêiner para usar lxc-private-br de forma semelhante à configuração de bridge compartilhada, alterando lxc.net.0.link = lxc-private-br.

A escolha da configuração de rede dependerá das suas necessidades específicas. Para a maioria dos usuários, o lxc-net é a opção mais prática e segura para começar.


7. Gerenciamento Básico de Contêineres

Com seus contêineres LXC criados e configurados, é essencial saber como gerenciá-los. Isso inclui iniciar, parar e acessar a linha de comando do contêiner para realizar tarefas administrativas e de configuração. O LXC fornece um conjunto de ferramentas de linha de comando para essas operações básicas.

Iniciar e Parar Contêineres

Para iniciar um contêiner LXC, utilize o comando lxc-start seguido do nome do contêiner. O contêiner será iniciado em segundo plano por padrão.

sudo lxc-start -n <nome_do_contêiner> -d

Onde:

  • -n <nome_do_contêiner>: Especifica o nome do contêiner que você deseja iniciar.
  • -d: (detach) Inicia o contêiner em segundo plano, liberando o terminal.

Exemplo: Para iniciar o contêiner meu-contêiner-privilegiado:

sudo lxc-start -n meu-contêiner-privilegiado -d

Para parar um contêiner em execução, use o comando lxc-stop:

sudo lxc-stop -n <nome_do_contêiner>


Exemplo: Para parar o contêiner meu-contêiner-privilegiado:

sudo lxc-stop -n meu-contêiner-privilegiado

Você pode verificar o status de todos os seus contêineres com o comando lxc-ls -f:

sudo lxc-ls -f

Este comando listará todos os contêineres, seus estados (RUNNING, STOPPED), endereços IP e outras informações relevantes.


Acessar a Linha de Comando do Contêiner

Existem duas maneiras principais de acessar a linha de comando de um contêiner LXC em execução:

Usando lxc-attach

O lxc-attach é a ferramenta mais direta para executar comandos dentro de um contêiner em execução. Ele permite que você execute um comando ou inicie um shell interativo diretamente no namespace do contêiner, sem a necessidade de configuração de rede ou SSH.

Para obter um shell interativo dentro do contêiner:

sudo lxc-attach -n <nome_do_contêiner>

Exemplo: Para acessar o shell do contêiner meu-contêiner-privilegiado:

sudo lxc-attach -n meu-contêiner-privilegiado

Você pode então executar comandos como se estivesse diretamente dentro do contêiner. Para sair do shell do contêiner, digite exit.


Usando SSH

Para um acesso mais flexível e seguro, especialmente para gerenciamento remoto, você pode configurar o SSH dentro do seu contêiner. Isso requer que o serviço SSH esteja instalado e em execução dentro do contêiner, e que o contêiner tenha um endereço IP acessível.

1. Instale o servidor SSH dentro do contêiner:

Primeiro, acesse o contêiner usando lxc-attach:

sudo lxc-attach -n <nome_do_contêiner>

Dentro do contêiner, instale o OpenSSH server:

apt update
apt install openssh-server -y
exit

2. Obtenha o endereço IP do contêiner:

Você pode obter o IP do contêiner usando lxc-ls -f ou lxc-info:

sudo lxc-info -n <nome_do_contêiner> | grep IP

3. Acesse o contêiner via SSH do host:

ssh <usuário_do_contêiner>@<endereço_ip_do_contêiner>

Exemplo: ssh root@10.0.3.123 (se o usuário root estiver habilitado para SSH e o IP for 10.0.3.123). É altamente recomendável criar um usuário não root dentro do contêiner para acesso SSH e desabilitar o login root via SSH por segurança.

O gerenciamento eficaz dos seus contêineres é fundamental para manter suas aplicações e serviços funcionando sem problemas. Com esses comandos básicos, você pode controlar o ciclo de vida dos seus contêineres e interagir com eles conforme necessário.


8. Considerações Finais

A implantação e o gerenciamento de contêineres LXC no Debian oferecem uma solução poderosa e eficiente para virtualização leve. Ao longo deste guia, abordamos desde a instalação básica até a criação de contêineres privilegiados e não privilegiados, bem como as configurações essenciais de rede e gerenciamento. Para garantir o uso eficaz e seguro do LXC, é importante ter em mente algumas considerações adicionais.

Segurança

A segurança é um aspecto crítico ao trabalhar com contêineres. Embora os contêineres não privilegiados ofereçam um nível de isolamento significativamente maior do que os privilegiados, eles não são uma bala de prata. É fundamental seguir as melhores práticas de segurança:

  • Mantenha o Host Atualizado: Garanta que o sistema operacional host esteja sempre atualizado com os patches de segurança mais recentes.
  • Minimize Privilégios: Sempre que possível, utilize contêineres não privilegiados. Dentro dos contêineres, evite executar serviços como root e crie usuários com os privilégios mínimos necessários.
  • AppArmor/SELinux: Utilize e configure corretamente módulos de segurança como AppArmor (que já foi abordado) ou SELinux para restringir ainda mais as ações dos contêineres.
  • Auditoria e Monitoramento: Implemente ferramentas de auditoria e monitoramento para detectar atividades suspeitas tanto no host quanto nos contêineres.
  • Imagens Confiáveis: Ao criar contêineres não privilegiados a partir de imagens pré-construídas, certifique-se de que as fontes são confiáveis.
Recursos Adicionais

O ecossistema LXC é vasto e oferece muitas possibilidades além do que foi coberto neste guia. Para aprofundar seus conhecimentos e explorar funcionalidades avançadas, considere os seguintes recursos:

  • Documentação Oficial do LXC: O site oficial do Linux Containers (linuxcontainers.org) e a wiki do Debian (wiki.debian.org/LXC) são excelentes fontes de informação detalhada e atualizada.
  • LXD: Para um gerenciamento de contêineres mais robusto e com recursos de orquestração, considere explorar o LXD, que é construído sobre o LXC e oferece uma experiência de usuário mais amigável e escalável.
  • Comunidade: Participe de fóruns e comunidades online. A troca de experiências com outros usuários pode ser muito valiosa para resolver problemas e aprender novas técnicas.